Well-Formed
An XML snake game
- Score
- 0
- Best
- 0
An XML arcade game
The snake is the document. Eat start tags to open elements, then close them in order, innermost first. One wrong end tag and it isn't XML any more.
- Best
- —
- Today
- not played
- Formats written
- 0 of 36
Open tags to grow. Close them innermost first. Leave the board, bite yourself or eat the wrong end tag and the document breaks.
How to play
The rules are XML's, taken literally
The snake is the document you are writing. Its tail is the root element, every segment after it is an element you opened, in document order, and the lit ones are the elements still open — the stack a parser keeps while it reads.
1Open tags to grow
Eat a start tag and that element opens inside the one you are in. Every element you write adds a segment, and the deeper it is, the more it scores.
2Close the innermost
Every open element's end tag is somewhere on the board, but only one is safe: the innermost's. It pulses, in the colour of its segment.
3Anything else breaks it
Any other end tag is a mismatch. So is running off the board with elements still open, or into your own document.
4Finish the document
Write the level's quota of elements, close everything inside, and the root's end tag finishes the file. The next level is a different format, and faster.
Arrow keys or WASD steer, Space pauses and M mutes. On a phone, swipe on the board or use the pad beneath it.
Why one tag ends it
XML does not guess
HTML parsers repair broken markup and carry on. XML parsers are not allowed to: the specification calls a well-formedness violation a fatal error, and a conforming parser has to stop at the first one. So does this game.
When a run ends, the message on the screen is not written for the game. It is what libxml2 — the parser under PHP, lxml, Nokogiri and this site's validator — says about the document you had written, broken exactly where you broke it, and the test suite parses those documents to hold every message to the parser's wording. The document itself is one click from the XML validator, which will say the same.
- Opening and ending tag mismatch — eating the wrong end tag
- Premature end of data in tag — leaving the board with elements open
<rss version="2.0">
<channel>
<item>
<title>First post</title>
</channel>libxml2 reports Opening and ending tag mismatch: item line 3 and channel (line 5). The mistake is the </item> missing before line 5, and the message leads with line 3 because that is where the unclosed element began.
Scoring
Dive deep, then unwind in one go
Depth multiplies everything, and end tags eaten back to back chain into a combo. Five elements deep and closed in a single run is worth several times the same five closed one at a time — and a snake five elements longer, with four traps on the board.
- Start tag
- 10 × depth40 at depth 4
- End tag
- 25 × depth × combo300 at depth 4, third in a row
- Finished document
- 50 × elements + 250 × level1,350 for 12 elements on level 3
A finished run can go on the global leaderboard: today's daily challenge, where everyone was dealt the same board, or all time. It goes under a name the game deals you, such as <brisk-element-42/>, and it is not taken on trust. The server replays every move from the seed it dealt, and only the score the replay reaches goes on the board.
The documents
36 formats to write, from sitemaps to bank transfers
Each level is a real format from the format reference, and the tags it deals are read off that format's example document: which elements nest in which, which repeat, the namespace declarations on the root and a sample of the text. What you write reads like the format. It is guaranteed to be well-formed — not to be valid against the format's schema, which is a stricter question the game does not ask.
None written yet. The daily challenge deals a different lineup every day, so the far end of this list is reachable without surviving to level 36.
- 1XML sitemap<urlset>
- 2RSS 2.0<rss>
- 3Atom 1.0<feed>
- 4KML<kml>
- 5OPML<opml>
- 6GPX<gpx>
- 7JUnit XML<testsuites>
- 8Android manifest<manifest>
- 9DocBook 5<book>
- 10XLIFF<xliff>
- 11SOAP envelope<soap:Envelope>
- 12Log4j 2 config<Configuration>
- 13MusicXML 4.0<score-partwise>
- 14XML Schema (XSD)<xs:schema>
- 15JATS article<article>
- 16OOXML document<w:document>
- 17TEI document<TEI>
- 18HL7 CDA<ClinicalDocument>
- 19XMP metadata<x:xmpmeta>
- 20ISO 20022 pain.001<Document>
- 21Sitemap index<sitemapindex>
- 22Property list<plist>
- 23Checkstyle report<checkstyle>
- 24MathML<math>
- 25RDF/XML<rdf:RDF>
- 26Android strings<resources>
- 27MSBuild project<Project>
- 28OpenStreetMap XML<osm>
- 29SAML 2.0<samlp:Response>
- 30XSLT stylesheet<xsl:stylesheet>
- 31WSDL<definitions>
- 32UBL Invoice<Invoice>
- 33EPUB package<package>
- 34TTML captions<tt>
- 35XSL-FO<fo:root>
- 36JaCoCo report<report>
Get started
Real documents break the same way.
The validator runs the same libxml2 your documents meet in production. A workspace keeps checking the feeds, sitemaps and payloads you cannot afford to have break.