• # XML in Games

General and Gameplay Programming

The foundation of the World Wide Web, HTML, is known as a 'mark-up' language (HTML is short for "HyperText Mark-up Language", a child of SGML). This means that you 'mark up' pieces of data to allow them to be recognized in particular ways. You might mark up the text "Welcome" as a heading, or the URL "bob.gif" as an image.

The good, clever folks down at the W3C have drafted another language (also derived from SGML, HTML's big daddy). This language is known as XML, and is a very good thing. Firstly, it's another mark-up language ("eXtensible Mark-up Language", to be precise). But it doesn't have any defined 'tags' or keywords whatsoever!

How is that useful? you ask. What can we do with a language that has no words in it?! Well, the reason it's known as an 'extensible' mark-up language is that you can 'extend' it - that is, make it up. You create the words, and everything adheres to the language 'grammar.' XML is meta-data: data about data. The full language specification is at http://www.w3.org/TR/REC-xml, and while it's heavy reading, describes every aspect of the language from start to finish.

If your program dumps a whole load of data to a file, then what happens when you want to use that data in another program? You have to drag up format specifications, the code that created the file in the first place, and so on. The reason is that once your data's in the file, that's all it is: data. A stream of numbers with no real meaning to anyone or anything. You've effectively encrypted it - anyone who doesn't have the format specification will have no idea how to read the data. Sure, they could try and figure it out - but that's as slow and difficult as standard code-breaking.

Surely, in the days of object-orientation and massively-multiplayer online games, there must be a better way? I think XML can fill part of the gap.

[size="5"]XML 101

A single 'item' in XML is called an "element". An element consists, at a bare minimum, of a tagname (in HTML, things like P, H1, or TABLE are tagnames), which is in an opening tag and a closing tag. If my tagname is "gibbon", I could write it like this:

In fact, because there are several cases where there's nothing between the two tags, you're allowed to shorten it to this:

You have to have the forward-slash at the end there, so that the XML parser knows not to look for a closing tag.

At it's fullest, an element can have three things: Attributes, Children, and Data.

An Attribute is a "name=value" pair (e.g. 'family="mammal"'). All the attributes go in the opening tag, after the tagname:

Children are other elements, which are 'contained' within the first element. What that really means depends on how you interpret it; it could be that the child is 'inside' the parent (if the parent is, perhaps, a box of some sort), or it could be that the child is literaly a child of the parent, like so:

 
The babyGibbon, as a seperate element, is in it's simplest form - no attributes or children. However, because the gibbon now has a child, you can't write in the condensed form; you have to have seperate opening and closing tags, as shown.

Finally, an element can have 'data.' Data is anything that you put between the opening and closing tag, and which isn't an element. At it's simplest, you can just have plain text in there - there's also something called CDATA, which you use when your text might contain [lessthan] and > symbols (thus confusing the parser).

There's one last rule about XML. All your XML has to be 'well-formed.' To do that, you just have to make sure that every opening tag has a matching close-tag (or is in the condensed form), and that you close things in the same order you open them. So, you can't do this:

 
Instead, you need to do this:

 
Keeping things well-formed will help you out a lot. It's much, much easier for the parser to treat the XML code as a tree or stack; and if your code isn't well-formed, it won't be able to. In the first example, after the 3rd line ([lessthan]thing/>) my stack of elements looks like ":box:bag". After the next line, it becomes ":bag". That doesn't work, because there is no 'bag' element at the top level. HTML let you get away with this; XML is not so forgiving.

Conveniently, Internet Explorer (up till IE6, at least), when presented with an XML file, will check it and display it as a tree (and tell you if you messed it up), so you can check your XML syntax and layout by opening it in IE. There are plenty of other syntax-checking utilities out there, of course - including, I'm sure, something to write the XML for you, while you just build up a tree of your elements.

[size="3"]An Example

Here's a little chunk of XML:

 
And viola, the contents of my fridge.

According to the code above, my fridge contains some mild cheddar cheese, a can of cola, and a Tupperware box containing a half-eaten sandwich. Could you get that just by reading it? I'll guess you did - well-written XML is very easy to understand like that. If I were to eat more of the sandwich, and put, I dunno, a piece of broccoli into the box, I could just change the code to:

 
then you get the idea.

You may be wondering about that first line - [lessthan]?xml version="1.0"?>. It's given in the spec as a requirement for 'proper' XML data - really, it just gives the version of the language used to make the file (as the language will, nay, has, changed - they're already up to 1.1, but the parsers are still catching up). It's not totally necessary, if your file sizes are constricted or something, but it's a good thing to use.

[size="5"]XML in games

In my opinion, XML could be a valuable technology in games. It may not seem so, but I'll give a couple of applied examples.

 It's a box. It's empty. It's a box. I think there's something in it. I click 'Pick up' and then click on the ball, that I can see in the box. The game looks up the 'onPickup' attribute, and because it starts with 'do:' it executes the command shown on my cunning adventure-game VM. The value of the 'onLook' attribute of theBox gets set to "string:look_empty", and the game "get"s the ball - something which I predefined as a command. If I then look again at the box, the string "look_empty" is looked up, so I get "It's a box. It's empty." Bear in mind that all the script engine work is done by my game engine; XML doesn't do that for you, it just allows you to store the relevant information in a simple way. It's easily represented with a few classes (and I mean, two or three), and can be serialised efficiently (for saving/loading games - the entire world can be saved just by recursively writing out each element with all children). It's also excellent for testing or creating; you can edit the world state in Notepad and test the effects, rather than having to play with a hex editor or compile with custom-built tools. [size="3"]Saved/Loaded games Talking of saving/loading games, there's an entire application right there. So, we've got a hairy_monster, a volume of water (which is full, as opposed to drained), containing a shark. The only disadvantage of using XML as a format for saved games is that it might be a little too easy to read... you might not want people editing their saved games. However, in that case, all you need to do is encrypt/decrypt the file before/after you use it. [size="3"]Asset management And so on and so on. The above code describes a simple layout of a few files on disk and in a .PAK file (or whatever you want to use, maybe ZIP files, maybe your own equivalent). It'd be brilliant for virtual file systems; perhaps as a packing list (to ensure that the whole package is present, or by adding checksums to each item to check that it hasn't been tampered with), or information about files to load at start-up. In my game code, I could call 'LoadModel("shotgun")' and it'd be able to look up the "model" "shotgun" (located at "shotgun/shotgun.mdl" inside folder "weapons" inside folder "game/media/models", making a grand total of "game/media/models/weapons/shotgun/shotgun.mdl"). If you happen to move all your assets around, you don't really want to be changing all your code. Not to mention the fact that this method gives you the capability to change things on the fly - you could change the "loc" of the "models" folder to "games/models" if you discover that you've been configured to use the old models, for example. It also lets you look at the files you've got without accessing the hard disk; if I want to spawn a random gib, I can just pick a random child from "gibs" and load it, without having to check through the directory itself. [size="5"]Conclusion I hope I've set your mind off a little bit. These are only a few examples; but quite frankly, it appears to me that XML can be applied to, well, anything. You can describe structures or interfaces in it; dword name="dwWidth"> [Ed Note: no idea what is missing here] could be useful sometime. You can use items to reference other items (as I demonstrated with the adventure game example). Heck, you can do anything. Next time, I'll look at how we actually use XML in code - I'll show you how to use a particular XML parser, expat (http://expat.sf.net/), to read the XML data in and get it into a tree structure, and then I'll show you how to write it back out again. I wonder why I write all my articles at 2:30am... and then revise them at 3:00am... Richard Fine (a.k.a. Superpig) [email="rfine@lycos.com"]rfine@lycos.com[/email], or catch me in the forums or on #gamedev. Happy coding. 0   Report Article Sign in to follow this   Followers 0 Go to articles General and Gameplay Programming User Feedback 2 Comments 0 Reviews Mikepicker 194 Posted June 29, 2013 Really interesting article. What do you think about creating an rpg Skill Tree using XML? Do you think is a good idea? Thanks! Share this comment Link to comment Share on other sites LordMark 103 Posted July 2, 2013 Lol, I think you meant "and that you close things in the reverse order you open them" Closing in the same order would be like the first block that you cannot do. Share this comment Link to comment Share on other sites Create an account or sign in to comment You need to be a member in order to leave a comment Create an account Sign up for a new account in our community. It's easy! Register a new account Sign in Already have an account? Sign in here. Sign In Now Advertisement Advertisement Latest Featured Articles 7 The Total Beginner's Guide to Game AI By Kylotan Monday at 01:32 AM 0 Ray Tracing - Part 1 By Bacterius August 8 4 Effect: Black Hole Background By Vilem Otte July 12 0 Project Management By lawnjelly July 7 0 Unreal Engine 4: Realistic, high-quality windows By khawk June 29 Featured Blogs Individual Landing Capsules By Jooki in Imagine Earth - Planetary Colonization    0 Toolin' Around, By Halves By Ben Walker in Postmortems    0 Gargoyle Art Head Piece By Rutin in Rutin's Dev Blog    0 Daily Update #7 - Ａｎｏｔｈｅｒ　ｐｌａｎｅ　ｏｆ　ｂｅｉｎｇ By jb-dev in Projects Of Some Degree Of Interest    0 Imperfect Environment Maps By Hodgman in 22 Racing Series    0 Popular Now 16 Worst time of your life as an indie By Timothy SharpStarted Thursday at 07:30 PM 12 3D Data in light map when using Patch Tracing By ChenMoStarted Thursday at 06:34 AM 20 How to solve this trig function? By JoeJStarted Tuesday at 07:10 PM 12 Help in Naming my Games. By sprotzStarted Tuesday at 12:26 AM 19 How to avoid bugs By Timothy SharpStarted Monday at 05:48 PM Advertisement GameDev.net GameDev.net Articles GameDev.net Event Coverage GameDev.net Forums GameDev.net Blogs GameDev.net Gallery GameDev.net News GameDev.net Projects GDNet Chat All Activity Search In Everywhere This Category This Article More options... Find results that contain... All of my search term words Any of my search term words Find results in... Content titles and body Content titles only Home Articles Programming General and Gameplay Programming XML in Games Resources Articles & Tutorials Blogs Calendar Forums Gallery Community Activity Guidelines GameDev Market GameDev Jobs Leaderboard About About Us Terms of Service Privacy Policy Contact Us Social Copyright © 1999-2018 GameDev.net, LLC We've detected an ad blocker! We've detected an ad blocker. Please whitelist GameDev.net for access to our game development community. Don't like ads? Consider our GDNet+ Memberships for a no-ad experience. Yes, I'll Whitelist (adsbygoogle=window.adsbygoogle||[]).push({google_ad_client:"ca-pub-3167291168602081",enable_page_level_ads:true}); Copyright (c) 1999-2018 GameDev.net, LLC Powered by Invision Community × Existing user? Sign In Sign Up Browse Back Articles & Tutorials Back All Categories Audio Business Game Design Industry Programming Visual Arts Columns Back GameDev Unboxed Event Coverage Back All Events Game Developers Conference Power Up Digital Games Conference GameDev.Market Links News Podcasts Back All Podcasts Game Dev Loadout Archive Community Back Beginners Back Beginners Group Beginners Forum Beginners Resources Blogs Calendar Chat Forums Back All Forums Audio Business Game Design Programming Visual Arts Community GameDev Challenges Affiliates Topical Workshops Gallery Groups Back For Beginners GameDev Challenges All Groups Projects Back All Projects Games Game Assets Game Mods Developer Tools Store Forums Back All Forums For Beginners Audio Back Music and Sound FX Games Career Development Business Back Games Career Development Production and Management Games Business and Law Game Design Back Game Design and Theory Writing for Games Programming Back Artificial Intelligence Engines and Middleware General and Gameplay Programming Graphics and GPU Programming Math and Physics Networking and Multiplayer Visual Arts Back 2D and 3D Art Critique and Feedback Community Back GameDev Challenges GDNet Lounge GDNet Comments, Suggestions, and Ideas Coding Horrors Your Announcements Hobby Project Classifieds Indie Showcase Affiliates Back NeHe Productions AngelCode Topical Workshops Careers Back Contractors Hobby Projects Game Jobs Back Browse on GameDev.Jobs Post a Job Members Back Chat GDNet+ Membership Guidelines Leaderboard Online Users Awards Search Back All Activity My Activity Streams Back Latest Topics Featured Blogs Search var ipsDebug=false;var CKEDITOR_BASEPATH='//www.gamedev.net/applications/core/interface/ckeditor/ckeditor/';var ipsSettings={cookie_path:"/",cookie_prefix:"ips4_",cookie_ssl:true,upload_imgURL:"",message_imgURL:"",notification_imgURL:"",baseURL:"//www.gamedev.net/",jsURL:"//www.gamedev.net/applications/core/interface/js/js.php",csrfKey:"a220a77ae4746d0f3b9eedc54b5a9d10",antiCache:"14de000c45",disableNotificationSounds:false,useCompiledFiles:true,links_external:true,memberID:0,analyticsProvider:"ga",viewProfiles:true,mapProvider:'google',mapApiKey:"AIzaSyAeT7tk3vnWWmbgVISkLpbhkQvekG19rHM",}; ips.setSetting('date_format',jQuery.parseJSON('"mm\/dd\/yy"'));ips.setSetting('date_first_day',jQuery.parseJSON('0'));ips.setSetting('remote_image_proxy',jQuery.parseJSON('1'));ips.setSetting('ipb_url_filter_option',jQuery.parseJSON('"none"'));ips.setSetting('url_filter_any_action',jQuery.parseJSON('"allow"'));ips.setSetting('bypass_profanity',jQuery.parseJSON('0'));ips.setSetting('emoji_style',jQuery.parseJSON('"native"'));ips.setSetting('emoji_shortcodes',jQuery.parseJSON('"1"'));ips.setSetting('emoji_ascii',jQuery.parseJSON('"1"'));ips.setSetting('emoji_cache',jQuery.parseJSON('"1"'));ips.setSetting('quickSearchDefault',jQuery.parseJSON('"all"'));ips.setSetting('quickSearchMinimum',jQuery.parseJSON('3'));ips.setSetting('quickSearchShowAdv',jQuery.parseJSON('true'));ips.setSetting('quickSearchIn',jQuery.parseJSON('"title"')); { "@context": "http://schema.org", "@type": "Article", "url": "https://www.gamedev.net/articles/programming/general-and-gameplay-programming/xml-in-games-r1928/", "discussionUrl": "https://www.gamedev.net/articles/programming/general-and-gameplay-programming/xml-in-games-r1928/", "mainEntityOfPage": "https://www.gamedev.net/articles/programming/general-and-gameplay-programming/xml-in-games-r1928/", "name": "XML in Games", "headline": "XML in Games", "text": "The foundation of the World Wide Web, HTML, is known as a \u0027mark-up\u0027 language (HTML is short for \"HyperText Mark-up Language\", a child of SGML). This means that you \u0027mark up\u0027 pieces of data to allow them to be recognized in particular ways. You might mark up the text \"Welcome\" as a heading, or the URL \"bob.gif\" as an image. \nThe good, clever folks down at the W3C have drafted another language (also derived from SGML, HTML\u0027s big daddy). This language is known as XML, and is a very good thing. Firstly, it\u0027s another mark-up language (\"eXtensible Mark-up Language\", to be precise). But it doesn\u0027t have any defined \u0027tags\u0027 or keywords whatsoever! \nHow is that useful? you ask. What can we do with a language that has no words in it?! Well, the reason it\u0027s known as an \u0027extensible\u0027 mark-up language is that you can \u0027extend\u0027 it - that is, make it up. You create the words, and everything adheres to the language \u0027grammar.\u0027 XML is meta-data: data about data. The full language specification is at http://www.w3.org/TR/REC-xml, and while it\u0027s heavy reading, describes every aspect of the language from start to finish. \nOK, so what\u0027s so great about this, then? \nIf your program dumps a whole load of data to a file, then what happens when you want to use that data in another program? You have to drag up format specifications, the code that created the file in the first place, and so on. The reason is that once your data\u0027s in the file, that\u0027s all it is: data. A stream of numbers with no real meaning to anyone or anything. You\u0027ve effectively encrypted it - anyone who doesn\u0027t have the format specification will have no idea how to read the data. Sure, they could try and figure it out - but that\u0027s as slow and difficult as standard code-breaking. \nSurely, in the days of object-orientation and massively-multiplayer online games, there must be a better way? I think XML can fill part of the gap. \n[size=\"5\"]XML 101\nA single \u0027item\u0027 in XML is called an \"element\". An element consists, at a bare minimum, of a tagname (in HTML, things like P, H1, or TABLE are tagnames), which is in an opening tag and a closing tag. If my tagname is \"gibbon\", I could write it like this: \n In fact, because there are several cases where there\u0027s nothing between the two tags, you\u0027re allowed to shorten it to this: You have to have the forward-slash at the end there, so that the XML parser knows not to look for a closing tag. \nAt it\u0027s fullest, an element can have three things: Attributes, Children, and Data. \nAn Attribute is a \"name=value\" pair (e.g. \u0027family=\"mammal\"\u0027). All the attributes go in the opening tag, after the tagname: Children are other elements, which are \u0027contained\u0027 within the first element. What that really means depends on how you interpret it; it could be that the child is \u0027inside\u0027 the parent (if the parent is, perhaps, a box of some sort), or it could be that the child is literaly a child of the parent, like so: The babyGibbon, as a seperate element, is in it\u0027s simplest form - no attributes or children. However, because the gibbon now has a child, you can\u0027t write in the condensed form; you have to have seperate opening and closing tags, as shown. \nFinally, an element can have \u0027data.\u0027 Data is anything that you put between the opening and closing tag, and which isn\u0027t an element. At it\u0027s simplest, you can just have plain text in there - there\u0027s also something called CDATA, which you use when your text might contain [lessthan] and \u0026gt; symbols (thus confusing the parser). \nThere\u0027s one last rule about XML. All your XML has to be \u0027well-formed.\u0027 To do that, you just have to make sure that every opening tag has a matching close-tag (or is in the condensed form), and that you close things in the same order you open them. So, you can\u0027t do this: Instead, you need to do this: Keeping things well-formed will help you out a lot. It\u0027s much, much easier for the parser to treat the XML code as a tree or stack; and if your code isn\u0027t well-formed, it won\u0027t be able to. In the first example, after the 3rd line ([lessthan]thing/\u0026gt;) my stack of elements looks like \":box:bag\". After the next line, it becomes \":bag\". That doesn\u0027t work, because there is no \u0027bag\u0027 element at the top level. HTML let you get away with this; XML is not so forgiving. \nConveniently, Internet Explorer (up till IE6, at least), when presented with an XML file, will check it and display it as a tree (and tell you if you messed it up), so you can check your XML syntax and layout by opening it in IE. There are plenty of other syntax-checking utilities out there, of course - including, I\u0027m sure, something to write the XML for you, while you just build up a tree of your elements. \n[size=\"3\"]An Example\nHere\u0027s a little chunk of XML: And viola, the contents of my fridge. \nAccording to the code above, my fridge contains some mild cheddar cheese, a can of cola, and a Tupperware box containing a half-eaten sandwich. Could you get that just by reading it? I\u0027ll guess you did - well-written XML is very easy to understand like that. If I were to eat more of the sandwich, and put, I dunno, a piece of broccoli into the box, I could just change the code to: then you get the idea. \nYou may be wondering about that first line - [lessthan]?xml version=\"1.0\"?\u0026gt;. It\u0027s given in the spec as a requirement for \u0027proper\u0027 XML data - really, it just gives the version of the language used to make the file (as the language will, nay, has, changed - they\u0027re already up to 1.1, but the parsers are still catching up). It\u0027s not totally necessary, if your file sizes are constricted or something, but it\u0027s a good thing to use. \n[size=\"5\"]XML in games\nIn my opinion, XML could be a valuable technology in games. It may not seem so, but I\u0027ll give a couple of applied examples. \n[size=\"3\"]Adventure games\nIt\u0027s not too hard to describe adventure game worlds in XML. For example: It\u0027s a box. It\u0027s empty.It\u0027s a box. I think there\u0027s something in it.\n\nI click \u0027Pick up\u0027 and then click on the ball, that I can see in the box. The game looks up the \u0027onPickup\u0027 attribute, and because it starts with \u0027do:\u0027 it executes the command shown on my cunning adventure-game VM. The value of the \u0027onLook\u0027 attribute of theBox gets set to \"string:look_empty\", and the game \"get\"s the ball - something which I predefined as a command. \nIf I then look again at the box, the string \"look_empty\" is looked up, so I get \"It\u0027s a box. It\u0027s empty.\" \nBear in mind that all the script engine work is done by my game engine; XML doesn\u0027t do that for you, it just allows you to store the relevant information in a simple way. It\u0027s easily represented with a few classes (and I mean, two or three), and can be serialised efficiently (for saving/loading games - the entire world can be saved just by recursively writing out each element with all children). It\u0027s also excellent for testing or creating; you can edit the world state in Notepad and test the effects, rather than having to play with a hex editor or compile with custom-built tools. \n[size=\"3\"]Saved/Loaded games\nTalking of saving/loading games, there\u0027s an entire application right there. So, we\u0027ve got a hairy_monster, a volume of water (which is full, as opposed to drained), containing a shark. \nThe only disadvantage of using XML as a format for saved games is that it might be a little too easy to read... you might not want people editing their saved games. However, in that case, all you need to do is encrypt/decrypt the file before/after you use it. \n[size=\"3\"]Asset management And so on and so on. The above code describes a simple layout of a few files on disk and in a .PAK file (or whatever you want to use, maybe ZIP files, maybe your own equivalent). It\u0027d be brilliant for virtual file systems; perhaps as a packing list (to ensure that the whole package is present, or by adding checksums to each item to check that it hasn\u0027t been tampered with), or information about files to load at start-up. In my game code, I could call \u0027LoadModel(\"shotgun\")\u0027 and it\u0027d be able to look up the \"model\" \"shotgun\" (located at \"shotgun/shotgun.mdl\" inside folder \"weapons\" inside folder \"game/media/models\", making a grand total of \"game/media/models/weapons/shotgun/shotgun.mdl\"). If you happen to move all your assets around, you don\u0027t really want to be changing all your code. Not to mention the fact that this method gives you the capability to change things on the fly - you could change the \"loc\" of the \"models\" folder to \"games/models\" if you discover that you\u0027ve been configured to use the old models, for example. It also lets you look at the files you\u0027ve got without accessing the hard disk; if I want to spawn a random gib, I can just pick a random child from \"gibs\" and load it, without having to check through the directory itself. \n[size=\"5\"]Conclusion\nI hope I\u0027ve set your mind off a little bit. These are only a few examples; but quite frankly, it appears to me that XML can be applied to, well, anything. You can describe structures or interfaces in it; dword name=\"dwWidth\"\u0026gt; [Ed Note: no idea what is missing here] could be useful sometime. You can use items to reference other items (as I demonstrated with the adventure game example). Heck, you can do anything. \nNext time, I\u0027ll look at how we actually use XML in code - I\u0027ll show you how to use a particular XML parser, expat (http://expat.sf.net/), to read the XML data in and get it into a tree structure, and then I\u0027ll show you how to write it back out again. \nI wonder why I write all my articles at 2:30am... and then revise them at 3:00am... \nRichard Fine (a.k.a. Superpig) [email=\"rfine@lycos.com\"]rfine@lycos.com[/email], or catch me in the forums or on #gamedev. Happy coding. \n", "articleBody": "The foundation of the World Wide Web, HTML, is known as a \u0027mark-up\u0027 language (HTML is short for \"HyperText Mark-up Language\", a child of SGML). This means that you \u0027mark up\u0027 pieces of data to allow them to be recognized in particular ways. You might mark up the text \"Welcome\" as a heading, or the URL \"bob.gif\" as an image. \nThe good, clever folks down at the W3C have drafted another language (also derived from SGML, HTML\u0027s big daddy). This language is known as XML, and is a very good thing. Firstly, it\u0027s another mark-up language (\"eXtensible Mark-up Language\", to be precise). But it doesn\u0027t have any defined \u0027tags\u0027 or keywords whatsoever! \nHow is that useful? you ask. What can we do with a language that has no words in it?! Well, the reason it\u0027s known as an \u0027extensible\u0027 mark-up language is that you can \u0027extend\u0027 it - that is, make it up. You create the words, and everything adheres to the language \u0027grammar.\u0027 XML is meta-data: data about data. The full language specification is at http://www.w3.org/TR/REC-xml, and while it\u0027s heavy reading, describes every aspect of the language from start to finish. \nOK, so what\u0027s so great about this, then? \nIf your program dumps a whole load of data to a file, then what happens when you want to use that data in another program? You have to drag up format specifications, the code that created the file in the first place, and so on. The reason is that once your data\u0027s in the file, that\u0027s all it is: data. A stream of numbers with no real meaning to anyone or anything. You\u0027ve effectively encrypted it - anyone who doesn\u0027t have the format specification will have no idea how to read the data. Sure, they could try and figure it out - but that\u0027s as slow and difficult as standard code-breaking. \nSurely, in the days of object-orientation and massively-multiplayer online games, there must be a better way? I think XML can fill part of the gap. \n[size=\"5\"]XML 101\nA single \u0027item\u0027 in XML is called an \"element\". An element consists, at a bare minimum, of a tagname (in HTML, things like P, H1, or TABLE are tagnames), which is in an opening tag and a closing tag. If my tagname is \"gibbon\", I could write it like this: \n In fact, because there are several cases where there\u0027s nothing between the two tags, you\u0027re allowed to shorten it to this: You have to have the forward-slash at the end there, so that the XML parser knows not to look for a closing tag. \nAt it\u0027s fullest, an element can have three things: Attributes, Children, and Data. \nAn Attribute is a \"name=value\" pair (e.g. \u0027family=\"mammal\"\u0027). All the attributes go in the opening tag, after the tagname: Children are other elements, which are \u0027contained\u0027 within the first element. What that really means depends on how you interpret it; it could be that the child is \u0027inside\u0027 the parent (if the parent is, perhaps, a box of some sort), or it could be that the child is literaly a child of the parent, like so: The babyGibbon, as a seperate element, is in it\u0027s simplest form - no attributes or children. However, because the gibbon now has a child, you can\u0027t write in the condensed form; you have to have seperate opening and closing tags, as shown. \nFinally, an element can have \u0027data.\u0027 Data is anything that you put between the opening and closing tag, and which isn\u0027t an element. At it\u0027s simplest, you can just have plain text in there - there\u0027s also something called CDATA, which you use when your text might contain [lessthan] and \u0026gt; symbols (thus confusing the parser). \nThere\u0027s one last rule about XML. All your XML has to be \u0027well-formed.\u0027 To do that, you just have to make sure that every opening tag has a matching close-tag (or is in the condensed form), and that you close things in the same order you open them. So, you can\u0027t do this: Instead, you need to do this: Keeping things well-formed will help you out a lot. It\u0027s much, much easier for the parser to treat the XML code as a tree or stack; and if your code isn\u0027t well-formed, it won\u0027t be able to. In the first example, after the 3rd line ([lessthan]thing/\u0026gt;) my stack of elements looks like \":box:bag\". After the next line, it becomes \":bag\". That doesn\u0027t work, because there is no \u0027bag\u0027 element at the top level. HTML let you get away with this; XML is not so forgiving. \nConveniently, Internet Explorer (up till IE6, at least), when presented with an XML file, will check it and display it as a tree (and tell you if you messed it up), so you can check your XML syntax and layout by opening it in IE. There are plenty of other syntax-checking utilities out there, of course - including, I\u0027m sure, something to write the XML for you, while you just build up a tree of your elements. \n[size=\"3\"]An Example\nHere\u0027s a little chunk of XML: And viola, the contents of my fridge. \nAccording to the code above, my fridge contains some mild cheddar cheese, a can of cola, and a Tupperware box containing a half-eaten sandwich. Could you get that just by reading it? I\u0027ll guess you did - well-written XML is very easy to understand like that. If I were to eat more of the sandwich, and put, I dunno, a piece of broccoli into the box, I could just change the code to: then you get the idea. \nYou may be wondering about that first line - [lessthan]?xml version=\"1.0\"?\u0026gt;. It\u0027s given in the spec as a requirement for \u0027proper\u0027 XML data - really, it just gives the version of the language used to make the file (as the language will, nay, has, changed - they\u0027re already up to 1.1, but the parsers are still catching up). It\u0027s not totally necessary, if your file sizes are constricted or something, but it\u0027s a good thing to use. \n[size=\"5\"]XML in games\nIn my opinion, XML could be a valuable technology in games. It may not seem so, but I\u0027ll give a couple of applied examples. \n[size=\"3\"]Adventure games\nIt\u0027s not too hard to describe adventure game worlds in XML. For example: It\u0027s a box. It\u0027s empty.It\u0027s a box. I think there\u0027s something in it.\n\nI click \u0027Pick up\u0027 and then click on the ball, that I can see in the box. The game looks up the \u0027onPickup\u0027 attribute, and because it starts with \u0027do:\u0027 it executes the command shown on my cunning adventure-game VM. The value of the \u0027onLook\u0027 attribute of theBox gets set to \"string:look_empty\", and the game \"get\"s the ball - something which I predefined as a command. \nIf I then look again at the box, the string \"look_empty\" is looked up, so I get \"It\u0027s a box. It\u0027s empty.\" \nBear in mind that all the script engine work is done by my game engine; XML doesn\u0027t do that for you, it just allows you to store the relevant information in a simple way. It\u0027s easily represented with a few classes (and I mean, two or three), and can be serialised efficiently (for saving/loading games - the entire world can be saved just by recursively writing out each element with all children). It\u0027s also excellent for testing or creating; you can edit the world state in Notepad and test the effects, rather than having to play with a hex editor or compile with custom-built tools. \n[size=\"3\"]Saved/Loaded games\nTalking of saving/loading games, there\u0027s an entire application right there. So, we\u0027ve got a hairy_monster, a volume of water (which is full, as opposed to drained), containing a shark. \nThe only disadvantage of using XML as a format for saved games is that it might be a little too easy to read... you might not want people editing their saved games. However, in that case, all you need to do is encrypt/decrypt the file before/after you use it. \n[size=\"3\"]Asset management And so on and so on. The above code describes a simple layout of a few files on disk and in a .PAK file (or whatever you want to use, maybe ZIP files, maybe your own equivalent). It\u0027d be brilliant for virtual file systems; perhaps as a packing list (to ensure that the whole package is present, or by adding checksums to each item to check that it hasn\u0027t been tampered with), or information about files to load at start-up. In my game code, I could call \u0027LoadModel(\"shotgun\")\u0027 and it\u0027d be able to look up the \"model\" \"shotgun\" (located at \"shotgun/shotgun.mdl\" inside folder \"weapons\" inside folder \"game/media/models\", making a grand total of \"game/media/models/weapons/shotgun/shotgun.mdl\"). If you happen to move all your assets around, you don\u0027t really want to be changing all your code. Not to mention the fact that this method gives you the capability to change things on the fly - you could change the \"loc\" of the \"models\" folder to \"games/models\" if you discover that you\u0027ve been configured to use the old models, for example. It also lets you look at the files you\u0027ve got without accessing the hard disk; if I want to spawn a random gib, I can just pick a random child from \"gibs\" and load it, without having to check through the directory itself. \n[size=\"5\"]Conclusion\nI hope I\u0027ve set your mind off a little bit. These are only a few examples; but quite frankly, it appears to me that XML can be applied to, well, anything. You can describe structures or interfaces in it; dword name=\"dwWidth\"\u0026gt; [Ed Note: no idea what is missing here] could be useful sometime. You can use items to reference other items (as I demonstrated with the adventure game example). Heck, you can do anything. \nNext time, I\u0027ll look at how we actually use XML in code - I\u0027ll show you how to use a particular XML parser, expat (http://expat.sf.net/), to read the XML data in and get it into a tree structure, and then I\u0027ll show you how to write it back out again. \nI wonder why I write all my articles at 2:30am... and then revise them at 3:00am... \nRichard Fine (a.k.a. Superpig) [email=\"rfine@lycos.com\"]rfine@lycos.com[/email], or catch me in the forums or on #gamedev. Happy coding. \n", "dateCreated": "2003-04-20T20:26:24+0000", "datePublished": "2003-04-20T20:26:00+0000", "dateModified": "2003-04-20T20:26:00+0000", "pageStart": 1, "pageEnd": 1, "author": { "@type": "Person", "name": "Myopic Rhino", "image": "https://secure.gravatar.com/avatar/16f4f23aa8088c2c27c829623874b42e?d=https://www.gamedev.net/uploads/monthly_2017_08/M.png.3d2e4bcade48bd80a1d6554f9c036e99.png", "url": "https://www.gamedev.net/profile/6-dave-astle/" }, "publisher": { "@type": "Organization", "name": "Myopic Rhino", "image": "https://secure.gravatar.com/avatar/16f4f23aa8088c2c27c829623874b42e?d=https://www.gamedev.net/uploads/monthly_2017_08/M.png.3d2e4bcade48bd80a1d6554f9c036e99.png", "logo": { "@type": "ImageObject", "url": "https://secure.gravatar.com/avatar/16f4f23aa8088c2c27c829623874b42e?d=https://www.gamedev.net/uploads/monthly_2017_08/M.png.3d2e4bcade48bd80a1d6554f9c036e99.png" }, "url": "https://www.gamedev.net/profile/6-dave-astle/" }, "interactionStatistic": [ { "@type": "InteractionCounter", "interactionType": "http://schema.org/ViewAction", "userInteractionCount": 23455 }, { "@type": "InteractionCounter", "interactionType": "http://schema.org/FollowAction", "userInteractionCount": 6 }, { "@type": "InteractionCounter", "interactionType": "http://schema.org/ReviewAction", "userInteractionCount": 0 }, { "@type": "InteractionCounter", "interactionType": "http://schema.org/CommentAction", "userInteractionCount": 2 } ], "image": { "@type": "ImageObject", "url": "https://secure.gravatar.com/avatar/16f4f23aa8088c2c27c829623874b42e?d=https://www.gamedev.net/uploads/monthly_2017_08/M.png.3d2e4bcade48bd80a1d6554f9c036e99.png", "width": "500", "height": "500" }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": 5, "ratingCount": 2, "reviewCount": 0, "bestRating": "5" }, "commentCount": 2 } { "@context": "http://www.schema.org", "@type": "WebSite", "name": "GameDev.net", "url": "https://www.gamedev.net/", "potentialAction": { "type": "SearchAction", "query-input": "required name=query", "target": "https://www.gamedev.net/search/?q={query}" }, "inLanguage": [ { "@type": "Language", "name": "English (USA)", "alternateName": "en-US" } ] } { "@context": "http://www.schema.org", "@type": "Organization", "name": "GameDev.net", "url": "https://www.gamedev.net/", "logo": "https://www.gamedev.net/uploads/themes/monthly_2017_04/gamedev-logo-2017-368x76.png.e986e41d566ff6c90485a5304985ed5f.png", "address": { "@type": "PostalAddress", "streetAddress": "", "addressLocality": null, "addressRegion": null, "postalCode": null, "addressCountry": null } } { "@context": "http://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "item": { "@id": "https://www.gamedev.net/articles/", "name": "Articles" } }, { "@type": "ListItem", "position": 2, "item": { "@id": "https://www.gamedev.net/articles/programming/", "name": "Programming" } }, { "@type": "ListItem", "position": 3, "item": { "@id": "https://www.gamedev.net/articles/programming/general-and-gameplay-programming/", "name": "General and Gameplay Programming" } } ] } { "@context": "http://schema.org", "@type": "ContactPage", "url": "https://www.gamedev.net/contact/" } Important Information By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.   I accept We are the game development community. Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up! Sign me up!