in reply to Re^2: CRPGs, Perl, Gtk2, and my vision
in thread CRPGs, Perl, Gtk2, and my vision

My biggest stumbling block when it comes to XML is determining what should be an attribute of an element (like the "class" type in the spell element) and what should be the data of an element (like the name of the spell in the name element).

My rules of thumb are as follows. Note: I am sooo not an XML purist. In fact, most XML'ers are probably going to puke when they read my ideas. You have been warned.

  1. Every primary node is a thing. In this case, you have a spell.
  2. If you can, you should use attributes. Not for any storage issue, but becaues it makes more sense.
  3. Most attributes can be redefined as containing nodes that propagate their attributes to their children. For example, I would have a node called <spelltype> that has an attribute called "value". So, you could have something like:
    <spelltype value="mage"> <spell name="sleep"> .... </spell> <spell name="fireball"> .... </spell> </spelltype> <spell name="lightning bolt" spelltype="mage"> .... </spell>

    I use this in Excel::Template for formatting and other attributes that might work across a group of similar nodes.

  4. If an attribute is a thing, it belongs as a child node. For example, <effect>.
  5. If an attribute is complex, it belongs as a child node. For example, <sounds>.
  6. If an attribute can be repeated, it belongs as a child node. For example, <effect>.

So, I would rewrite your spell as follows:

<spell spelltype="mage" name="sleep" level="1" friendlyfire="0" combatonly="1" cumulative="1" castbyparty="1" canscribe="1" autoscribe="0" candispel="1" throw_vs="spell" > <message to="can_see_target">%t is put to sleep</message> <message to="target">You have fallen asleep</message> <sounds> <cast>DEFAULT</cast> <hit>enchanted.midi</cast> </sounds> <school>enchantment</school> <images> <cast>DEFAULT</cast> <hit>DEFAULT</hit> </images> <target type="square"> <count dice="" sides="" bonus="" perlevel=""/> <range dice="" sides="" bonus="" perlevel=""/> </target> <duration units=""> <length dice="" sides="" bonus="" perlevel=""/> </duration> <casttime></casttime> <throwresult></throwresult> <component type="somatic" /> <component type="verbal" /> <component type="material" consumed="1"> <item name="sand" amount="1" units="pinch" /> </component> <abilities> <ability>sleep</ability> </abilities> <effect> <attr>ASLEEP</attr> <amount>1</amount> <units>absolute</units> <targeting>target</targeting> <cumul>1</cumul> <worksif> <true>$TARGET->hit_dice() < 5</true> <false>$TARGET->is_undead()</false> </worksif> </effect> </spell>

The problem is that you're going to start developing a mini-language. For example, some spells allow for more than one material component. And, some spells allow for an either-or with material components. You're starting to discover this in your <:worksif> node. The components is just another example of htis.

It's almost better to embed a database that to use flatfiles. That way, you can link directly to the record for sand instead of having to look it up in some large file. This will reduce the amount of RAM needed, probably by a factor of 10.

And, you're not really going to be using the fact that XML is human-readable. You're still going to have a data-entry interface to manage these. Might as well use an RDBMS instead.

Being right, does not endow the right to be rude; politeness costs nothing.
Being unknowing, is not the same as being stupid.
Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.