Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I want to create an XML format in which I will define data objects for a game I am currently working on.

The base idea is that I will have Elements which can be combined in other Elements, Items or Spells.

A primal element is an element which is directly available. If an element is not primal then in order to create it, it must be combined from other elements so it will have a recipe definition (list of components required to combine in order to create the specific entity).

Items and Spells also need to have a recipe.

As of now I created the sample XML:

<TechTree>

    <ElementDefinitions>
        <Element name="Fire" primal="true"/>
        <Element name="Earth" primal="true"/>
        <Element name="Nature" primal="true"/>
        <Element name="Mana" primal="true"/>

        <Element name="Lava">
            <Component>Fire</Component>
            <Component>Fire</Component>
            <Component>Earth</Component>
        </Element>

        <Element name="Grass">
            <Component>Nature</Component>
            <Component>Mana</Component>
            <Component>Earth</Component>        
        </Element>

    </ElementDefinitions>

    <ItemDefinitions>
        <Item name="ManaPotion">
            <Component>Mana</Component>
            <Component>Grass</Component>
            <Component>Nature</Component>
        </Item>
    </ItemDefinitions>

    <SpellDefinitions>
        <Spell name="FireSpell">
            <Component>Fire</Component>
            <Component>Fire</Component>
            <Component>Mana</Component>
        </Spell>

        <Spell name="HealingSpell">
            <Component>Nature</Component>
            <Component>Nature</Component>
            <Component>Mana</Component>
        </Spell>

        <Spell name="MoltenArmor" selection="ordered">
            <Component>Lava</Component>
            <Component>Nature</Component>
            <Component>Mana</Component>
        </Spell>

        <Spell name="RestoreMana">
            <Component>Mana</Component>
            <Component>Mana</Component>
            <Component>Mana</Component>
        </Spell>

    </SpellDefinitions>

</TechTree>

As of now there aren't too many attributes, but in the future the entities will have all kind of attributes (damage, effect, usable conditions etc) so I need to have a format that would allow me to extend, for instance, all items but not spells or elements.

I will enforce with an XML schema that components used in the recipe must be already defined. So writing Air as a component without firstly defining it will yield an error.

Although as of now all recipes have 3 elements in the future I might decide to create some with a different number.

I would greatly appreciate feedback or tips on how can I improve the format.

share|improve this question
    
It would be really interesting to see the code for your actual game another time. How you format your XML will likely depend a lot on that code. –  Simon André Forsberg Jul 24 at 11:22
1  
You might want to look into Entity-Component-System for your game. –  Simon André Forsberg Jul 24 at 11:24
    
@SimonAndréForsberg I am using a pattern similar with ECS favoring composition for my game entities and using the prototype design pattern for creation so I wont have strong coupling between the architecture and the entities. –  Memleak Jul 24 at 12:02
    
Have you considered a format other than XML? XML is great when you want to validate your schema formally. Not so much when you want to read it easily...JSON is great and almost identically powerful. This is very strongly an opinion, and I'm sure other people disagree, but boy is it nice to not have to deal with all those angles, closing tags, and especially XML tooling... –  Christopher Pfohl Jul 24 at 16:38

2 Answers 2

up vote 10 down vote accepted

XML based configuration structures often tend to change during the development-cycle of the product. It is good to plan ahead, but you should also expect to run in to something that needs a format change.

First though, the structure you have for your XML appears clean, and good. The presentation you have is good and neat. That makes it nice to review.

There are some suggestions I have that will help you though.

  1. Use Attributes. Atributes are a convenient storage system, and don't have the same white-space uncertainties as element content. I would convert all your current text-based values to attributes (and I would also incorporate the quantity as suggested by Pimgd):

    <Spell name="RestoreMana">
        <Component item="Mana" quantity="10" />
    </Spell>
    
  2. Use references that are unique and not related to the name. I would consider using the attribute name 'id' because that has some advantages:

    <ElementDefinitions>
        <Element id="elem-fire" name="Fire" primal="true"/>
        <Element id="elem-earth" name="Earth" primal="true"/>
        <Element id="elem-nature" name="Nature" primal="true"/>
        <Element id="elem-mana" name="Mana" primal="true"/>
    
        <Element id="elem-lava" name="Lava">
            <Component ref="elem-fire" quantity="2" />
            <Component ref="elem-earth" />
        </Element>
    
        <Element id="elem-grass" name="Grass">
            <Component ref="elem-nature" />
            ......
        </Element>
    
    </ElementDefinitions>
    
    ....
    
        <Item id="item-manapotion" name="ManaPotion">
            <Component ref="elem-Mana" />
            .....
        </Item>
    

The advantages of these changes is that each element has a unique ID that will help resolve looking for things in potentially multiple places. Additionally, having a reference that is independent of the display name allows you to change properties of the data in a single place, without having to redo many places in your code. For example, you could possibly have multi-language support directly in the XML with something like:

    <ElementDefinitions>
        <Element id="elem-fire" name="Fire" name_fr="Feu" name_de="Feuer" primal="true"/>
        ...
share|improve this answer
    
@TRiG - thanks and fixed. –  rolfl Jul 24 at 19:42
    
I'd say the contrary, one the biggest mistakes people do when designing XML is putting all data in attributes. Don't use attributes to store your data. Attributes are not extensible and during development you don't know what will change. Use attributes only for metadata and store your data in text elements. –  Lie Ryan Jul 25 at 0:39

I'd wrap the <Component>s in a <Components> tag. Maybe you want to add more attributes to spells later. In fact, I'd probably make <ItemComponents> and <SpellComponents>.

I'm also thinking you might be better off here and there by using some sort of "quantity". Lets say a spell had 10 components (for some arbitrary game design reason)...

    <Spell name="RestoreMana">
        <Component>Mana</Component>
        <Component>Mana</Component>
        <Component>Mana</Component>
        <Component>Mana</Component>
        <Component>Mana</Component>
        <Component>Mana</Component>
        <Component>Mana</Component>
        <Component>Mana</Component>
        <Component>Mana</Component>
        <Component>Mana</Component>
    </Spell>

or

    <Spell name="RestoreMana">
        <Component quantity="10">Mana</Component>
    </Spell>

I like the second one more, it's smaller. Plus, I don't wanna be the one who has to check if the balancing is done right by counting whether this spell has 10 components via a process which includes manually counting lines.

From this point, however, you can go pretty much everywhere. Future proofing your schema is hard without fully knowing what data it will have to support, so I'd focus on getting the domain model right and then looking at the xml schema again.

share|improve this answer
6  
"Future proofing your schema is hard without fully knowing what data it will have to support". Yes! Totally. –  Simon André Forsberg Jul 24 at 11:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.