<--Part II, part 2 ^--xmld20--^ Rethink, continued-->

xmld20 - an XML Schema for d20 gaming systems - rethink

I hate the word rethink as a noun, so use it here tongue-in-cheek...

While coding further, I hit a little snag which tickled something in my brain, and told me to stop.

Specifically, the problem was with the way that the new statblock and the old statblock displayed different things for the Special Qualities entry... the old statblocks would detail all of these qualities in a list (abbreviating groups into things like "undead traits"). The new statblock handles certain Qualities in different ways, like qualities that affect the senses being listed at the top, qualities that affect defensive features beside the armor class, and so on.

While trying to code my way around this, the weight of trying to support two statblocks started to sink in, but the main thing that really hit me was that they were creating their output from something that I had hand-coded, where really that was an intermediate stage of the data -- what we really want is for the whole monster entry to be generated.

Character classes and monster classes

This brings us back to the idea of monster classes, and character classes, and recording instead the progression of a character, NPC or monster through these classes, having the software generate as a final product the being they have become.

For PCs and NPCs, this sounds easy, since the books have the progression tables listed right there for you. But monster classes only have the extra work (and for some, fun and interesting work) of creating these tables -- the end result is that we will need code that can traverse these tables and combine the levels together to get a final product.

The problem

The biggest problem with trying to implement level increases programmatically is that, while the d20 system is quite logical and calculatable, it's not perfectly so, and some (much?) requires human interpretation. The question is whether this interpretation can be codified, or notated in a way to describe the interpretation to code.

The problem was touched upon in the d20xml mailing list, where it was discussed that there must be a line between what is hard-coded and what exists in the data files.

Some of the problems that we'll face are as follows: during a level progression table, base attacks, saving throws, hitdice and skill points all go up in an incremental fashion -- that is, you gain another point in your base attack, in your Will save, etc. Even something like the sneak attack dice for rogues and other classes can be coded to as increases to dice damage, and can be made to handle the first increase as a "gain", and subsequent ones as increases.

But how do we code feat gains? Sure, the gain every three levels can be dealt with in code, so the character generator code knows that when you gain your third, sixth, ninth, etc. level, it should ask the user which feat was gained, and it should also know how to check for pre-requisites (which themselves are another matter).

But what about levels where you replace something instead of just increase it? The monk, one of the most complicated player classes, has some good examples.

The monk has a Slow Fall ability, which increases by 10' every two levels. That in itself isn't a problem, but when the monk hits 20th level, the number is technically infinite, shown as "any distance" in the table. So, we may need to support "increase" values as well as "set" values.

The monk has a Ki Strike, which isn't a numerical value, but instead gains new values, such as magic, lawful, and adamantine, which all stack, and should all be recorded. How should those be stored? Now we need "increase", "set", and perhaps a "add"?

Another minor thing is standardizing the names of values that are affected. While ability scores, saving throws and base attacks are all common themes in d20, and thus will be well-defined, what about the monk's unarmed damage? Her flurry of attacks? Character sheet generators need to be in-tune with the names of these abilities to know how to display them; battle simulators need to know how to find them; and prestige class developers need to know how to define these abilities so their class stacks with the abilities of a previously-taken class.

examples

The fighter is one of the easiest class progressions to deal with. All a fighter gets is extra feats on top of the usual base attack, saves, etc. These feats must come from a subset of all provided, but that's a minor problem, relatively speaking.

Let's try to design how to represent the level one entry for the fighter class.

<Class name="fighter">
  <Levels>
    <Level number="1">
	<HD size="10"/>
	<BaseAttack value="1"/>
	<FortSave value="2"/>
	<RefSave value="0"/>
	<WillSave value="0"/>
	<Skill number="2"/>
	<BonusFeat type="fighter"/>
    </Level>
  </Levels>
</Class>
First of all, I know that some people would prefer to avoid the attributes, and put the values instead as the body of the element, like this:
<Class name="fighter">
  <Levels>
    <Level number="1">
	<HD/>10
	<BaseAttack/>1</BaseAttack>
	<FortSave/>2</FortSave>
	<RefSave/>0</RefSave>
	<WillSave/>0</WillSave>
	<Skill/>2</Skill>
	<BonusFeat type="fighter"/>
    </Level>
  </Levels>
</Class>
That's fine, and I don't disagree with that, but that's the least of our problems.

First of all, I've shown this example as a "set" example, so the next level might look like

    <Level number="2">
	<HD/>10
	<BaseAttack>2</BaseAttack>
	<FortSave>3</FortSave>
	<RefSave>0</RefSave>
	<WillSave>0</WillSave>
	<Skill>4</Skill>
	<BonusFeat type="fighter"/>
    </Level>
The glaring problem with this is that it assumes no multiclassing; that is, it's saying "when going to level two fighter, set the base attack as 2, the fort save as 3...". This is going to be a big problem for multiclassing, so the "set" idea doesn't work globally -- it's really unfortunate that the class progression tables aren't reworked to show the "increase" at a level instead of requiring the player to figure it out.

Here are our two levels reworked as an incremental value:

<Class name="fighter">
  <Levels>
    <Level number="1">
	<HD/>10
	<BaseAttack>1</BaseAttack>
	<FortSave>2</FortSave>
	<RefSave>0</RefSave>
	<WillSave>0</WillSave>
	<Skill>2</Skill>
	<BonusFeat type="fighter"/>
    </Level>
    <Level number="2">
	<HD/>10
	<BaseAttack>1</BaseAttack>
	<FortSave>1</FortSave>
	<RefSave>0</RefSave>
	<WillSave>0</WillSave>
	<Skill>2</Skill>
	<BonusFeat type="fighter"/>
    </Level>
  </Levels>
</Class>
We might consider setting the value to "+1" instead of just "1", to signify to the code that this is an "increase" instead of a "set". I'm going to hold off on that thought for a minute, to go back to a previous point.

I mentioned that while the above values are very typical statistics that we will want to change, there are many others that are specific to a class, or perhaps a monster, or haven't been created yet. While I can add a SneakAttack or SlowFall element for rogues and monks, this would possibly require my code to know about these elements to handle them (although the XML code can adapt by reading the name of the element instead).

I propose something different instead of using a BaseAttack element and a SneakAttack element. Instead, we should have a generic Increase element, which takes the statistic name as an attribute. We would then write our first two Fighter levels as this:

<Class name="fighter">
  <Levels>
    <Level number="1">
	<Increase name="HD">10</Increase>
	<Increase name="BAB">1</Increase>
	<Increase name="Fort">2</Increase>
	<Increase name="Ref">0</Increase>
	<Increase name="Will">0</Increase>
	<Increase name="Skill">2</Increase>
	<Add name="Feat" type="fighter"/>
    </Level>
    <Level number="2">
	<Increase name="HD">10</Increase>
	<Increase name="BAB">1</Increase>
	<Increase name="Fort">1</Increase>
	<Increase name="Skill">2</Increase>
	<Add name="Feat" type="fighter"/>
    </Level>
  </Levels>
</Class>
This brings up a few other issues. We see that a fighter gets a feat at first and second level, but which ones? That he gets 2 skill points (plus int bonus, plus possible racial bonus) per level, but where do those points go?

The issue is that this is a generic progression, but it doesn't represent an individual...
<--Part II, part 2 ^--xmld20--^ Rethink, continued-->

©2002-2017 Wayne Pearson