<--Version 4 ^--xmld20--^ Intermediate stage-->

xmld20 - an XML Schema for d20 gaming systems - version 5

That's right, version 5. Version 4 never really got off the ground -- we saw a little scripting with XML, but nothing more than half of the aboleth got generated before I started rethinking that approach.

I've always wanted this system to be modular, and while I did design the XML data to be very pluggable, the rest of the system never really went that way. Additionally, I had never touched on the specifics of the interface, having to this point only had command-line tools that generated HTML results. This is fine for one-time generation of character sheets or statblocks, but we will, of course, want something interactive. Additionally, downloading datasets from other sources is nice, but in today's online world, being able to access them on remote servers seems to make sense, too.

The user interface has been something in the back of my mind for a while now, something to consider while driving, where I can't do any hands-on coding. I had briefly considered a standalone application, but with the desire not to single out any operating system, the idea of a web-based app, or Java, was prevalent. But then, there's Google.

I've been interesting in the Google Gadgets for a while now, being similar to the widgets on Mac OS X and the gadgets of Windows Vista. I did write a quick Google Gadget a few months ago that displayed an xmld20 character sheet, which went well, and that got me thinking of using the Google homepage as the application environment itself. Using various Gadgets, you could have your character sheet up while playing, but character creation could be augmented by having Gadgets with class descriptions, Gadgets with races, with spells, with equipment... the DM, too, could have all the information needed right there on the Google desktop, with monsters and NPCs in their own Gadgets, tables for XP and treasure, spells, random name generator, various tables...

But the Gadgets are better used for lookup and reference than interaction. Yes, a Gadget could be made to implement the full user interface for xmld20, for creation of races and classes, for character creation, spell creation, data input, etc., but the Gadget would have to be so big as to take up the whole Google Desktop, and in that case, it might as well not be a Gadget, which is intended to work with other things around it.

This brings me to the Google Web Toolkit, that I learned about yesterday. This toolkit takes Java code and compiles it into AJAX code. This means that the application can use the whole browser window, natively, and not worry about the Java Virtual Machine being there, or of the right version, and should work in all supported browsers. It also means that the large programming task of the interface can be done in a language with which I'm familiar, and moved over to the browser without me having to delve into the delicate world of DHTML.

These technologies, along with Google Gears, and a PHP backend, really had me reconsider the overall design of the xmld20 system, which is why I've gone to version five.


Here is the idea for the new system. There will be a backend server, written in PHP, which takes XML datafiles (characters, classes, races, spells, etc.) and XML rulesets, and returns XML results. That is, it would take an XML file with my character creation choices, file(s) with the pertinent race and class(es), files with appropriate spells, feats, equipment and whatnot, and output a pre-calculated XML character. This is different than before; the various output-generating XSLT, such as for the new- and old-statblocks, did the calculations as well as the output, so a lot of code got repeated. Instead, the scripting (yes, we haven't given that up!) will all be applied to the character and accompanying datafiles, to generate a final result, not unlike the character we were using way back in version 2 of xmld20, or the format that the d20xml group had. I was against this format before, because it contained so much stuff that should be calculated, but in our case it will have been. That format is nice, however, for something that takes the final character and outputs it, into character sheets, statblocks, monster entries, etc. It can also be used for in-game calculations and combat scenarios.

This final character sheet will be retrievable from the command-line, for testing purposes, as well as through a webserver. The request for results would include pointers to the datafiles, the kind of result requested, etc., which might be part of the URL or provided in an XML file with references to all of the other datafiles. The server, too, could have default files (the base SRD for instance), so only extra data would have to be provided to the system. But recall that this final character sheet would be in XML, which is not terribly useful to the end user.

This is where the Gadgets and the JavAJAX comes in. They would retrieve the XML result and change it into HTML or whatever format they need to produce, well, whatever they're designed to. This design modularizes the system a little more, and allows for remote computing and storage.


So what does this mean? Where do I start? With the move to PHP, we've made the code that processes the data a little easier to write by using a "real" language, and we've also simplified the scripting process, if we use PHP, or at least a small subset of it, as our scripting language.

So how will this work? A nice module in PHP is the SimpleXML module, which loads an XML document into a hierarchy of objects, which then lets you access all the nested data using PHP object syntax. It also supports XPath queries into the object hierarchy, as if the data was still in XML. This can be handier than object traversal when looking for elements of a certain type. For instance, when we're trying to find all of the code that pertains to the calculation of hitpoints, we want to find any Code blocks in the XML data that say so. Using traversal of the object hierarchy, we'd have to step through each object, find all Code objects, then have conditional code to check if they pertain to hitpoints; with XPath, we can make one request for any and all Code segments that matter, and then iterate through the results.

Looking up values from the character sheet -- that is, values that were decided at creation or level up time, is easy enough to support in the PHP script, since we can access it directly with the SimpleXML with something like

	$basestrength=$charsheet->Ability->Strength;
But most of the logic for calculating values needs to have access to bonuses from feats, items and such, as well as other calculations. This can be structured in the form a function call, since we can write that actual function in PHP, and have it exist for the calling. For instance, we could have
	$strbonus=Bonus(Calc("Strength"));
This is more realistic than the previous one, since you're unlikely to ever want to access the original strength roll (since it doesn't represent possible gains every four levels, magic items, class boosts, etc.) The Calc() function will know how to go off and do the calculation that the former version in XSLT did (the <Calc/> element), and the Bonus() function would be one in a handful of available functions for doing other standard calculations. Or, perhaps there should just be a StrengthBonus Calc() call? This was done as a <Modifier/> element in version 4.

I've been re-thinking the system that was used to "build up" the character and the code before. We used to have something like this:

≪Characters>
  ≪Character>
  ≪Bio>
        ≪Name>aboleth≪/Name>
        ≪Race>aboleth≪/Race>
  ≪/Bio>
    ≪Levels>
        ≪Level number="0">
                ≪Set type="Ability" name="strength">10≪/Set>
                ≪Set type="Ability" name="dexterity">10≪/Set>
                ≪Set type="Ability" name="constitution">10≪/Set>
                ≪Set type="Ability" name="intelligence">11≪/Set>
                ≪Set type="Ability" name="wisdom">11≪/Set>
                ≪Set type="Ability" name="charisma">11≪/Set>
...

Which then became:
<Characters>
  <Character>
    <Name>aboleth</Name>
    <Race>aboleth</Race>
    <Levels>
        <Level number="0">
                <Code calc="Ability">
                        <If this.name="strength">
                                <Add type="Base">10</Add>
                        </If>
                        <If this.name="dexterity">
                                <Add type="Base">10</Add>
                        </If>
                        <If this.name="constitution">
                                <Add type="Base">10</Add>
                        </If>
                        <If this.name="intelligence">
                                <Add type="Base">11</Add>
                        </If>
                        <If this.name="wisdom">
                                <Add type="Base">11</Add>
                        </If>
                        <If this.name="charisma">
                                <Add type="Base">11</Add>
                        </If>
                </Code>
...

I think the <Set/>, <Add/>, etc. idea may no longer be necessary. When moving the venerable aboleth over to the new system, I'll see how it fares with something like
<Characters>
  <Character>
    <Name>aboleth</Name>
    <Race>aboleth</Race>

    <Base calc="strength">10</Base>
    <Base calc="dexterity">10</Base>
    <Base calc="constitution">10</Base>
    <Base calc="intelligence">11</Base>
    <Base calc="wisdom">11</Base>
    <Base calc="charisma">11</Base>
...
Where elements like Base, Bonus and Text would be default types. By using calc as the name of the calculation, we have "type" available to use for the type of bonus, which makes more sense, as this is the terminology of the game. I don't like the above, though, for reasons mentioned in previous incarnations, so I think I'll go with
<Characters>
  <Character>
    <Name>aboleth</Name>
    <Race>aboleth</Race>

    <Base calc="Ability" subcalc="strength">10</Base>
    <Base calc="Ability" subcalc="dexterity">10</Base>
    <Base calc="Ability" subcalc="constitution">10</Base>
    <Base calc="Ability" subcalc="intelligence">11</Base>
    <Base calc="Ability" subcalc="wisdom">11</Base>
    <Base calc="Ability" subcalc="charisma">11</Base>
...
It might be a bit wordy, but it allows us to have Ability as a standard concept without forcing the names of those abilities, which lets us support systems that don't use the standard six.

Upon first consideration, I think I might prefer this:

<Characters>
  <Character>
    <Name>aboleth</Name>
    <Race>aboleth</Race>

    Base("Ability","strength",10);
    Base("Ability","dexterity",10);
    Base("Ability","constitution",10);
    Base("Ability","intelligence",11);
    Base("Ability","wisdom",11);
    Base("Ability","charisma",11);
...
It's tempting to support something like
    Ability["strength"]=10;
But it isn't clear how bonuses to the ability might be handled. Even with
    Ability["strength","enhancement"]=4;
But this doesn't support the idea of multiple sources of bonuses, and the ability to choose from the best (this would overwrite something better) or the ability to support stacking of like-named bonuses (such as dodge).

To get a clearer picture of what we need at the front end, let's take a look at what we want in the middle.
<--Version 4 ^--xmld20--^ Intermediate stage-->

©2002-2008 Wayne Pearson