| <--Intermediate stage | ^--xmld20--^ |
How do we go about this? Let's look at the intermediate data for the armor class of the aboleth:
<AC total="16" touch="9" flatfooted="15"> <Base>10</Base> <Modifier type="size">-2</Modifier> <Modifier type="dexterity">1</Modifier> <Bonus type="natural">7</Bonus> </AC>The Base entry is something that should be automatically generated. Right? Or should that be something that's added from a base set of rules? I prefer this idea, since it allows for a more flexible system, and it doesn't matter for complexity whether the code to add it is in some external "d20 rules" file or hardcoded in. So what should that code look like?
We've decided that our scripting language will be in PHP, but that doesn't mean that we want to provide the raw instructions required to manipulate some internal structure; we want to provide interfaces to this structure that the user (that is, the person adding content to the system) can use without knowing the internals. This will come in the form of function calls for the most part, but PHP is available in general for other required logic. From what I've come up with so far, Most calculations are from Base, Modifier, Bonus or Penalty entries. These map well to functions, so let's start with that:
Base("AC",10);
This code would be in a default set of rules that are run for every
character, NPC and monster.
The next entry in the intermediate code is the size modifier. All that "creation" software should need to supply is the fact that the creature is Huge, and something else should take care of the numbers involved. What is this something? In fact, where is the size being stored? We're basically trying to come up with three things at once here: the format of the character data (the choices made by the player), the rules of the game (scripts based on d20 rules) and the code that knows how to merge it all together. Let's see if I can whip up a diagram of what I'm seeing.
So, the Character Data would look similar to the character sheet from
version 3, which looked something like this abbreviated version:
<Name>aboleth</Name>
<Race>aboleth</Race>
<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>
<Add type="Environment">Underground</Add>
<Add type="Organization" name="solitary"/>
<Add type="Organization" name="brood">2-4</Add>
<Add type="Organization" name="slaver brood">1d3+1</Add>
<Add type="Organization" name="slaver brood" subname="skum">7-12</Add>
<Set type="Treasure" name="standard">2</Set>
<Set type="Alignment" name="lawful" subname="evil">usually</Set>
<Add type="Advancement" name="huge">9-16</Add>
<Add type="Advancement" name="gargantuan">17-24</Add>
<Add type="LevelAdjustment">-</Add>
</Level>
<Level number="1" class="aboleth">
<Increase type="Skill" name="concentration">11</Increase>
<Increase type="Skill" name="knowledge" subname="any one">11</Increase>
<Increase type="Skill" name="listen">11</Increase>
<Increase type="Skill" name="spot">11</Increase>
<Add type="Feat" name="alertness"/>
<Add type="Feat" name="combat casting"/>
<Add type="Feat" name="iron will"/>
</Level>
We aren't using the Set/Add/Increase system anymore, so we need a way
to record this. We also don't want to convert this into script
itself; we just need these to be values that the rules know to access.
Whatever notation we use in the character sheet has to be understandable
by the rules code.
The Rules data will be PHP script, and will be multiple files. The scripts will be executed by the Rules Applier, which, I think, just needs to find a "main" section in the Rules data and then executes it. It also has to be aware of other Rules data that needs to be executed -- or is that the responsibility of the Rules data itself? This is the part that I'm a bit stuck on. What does the Character Data look like? What does the Rules Applier actually do? And what is the Internal Representation?
I have to keep in mind that the Rules need to be designed that a regular user with a little effort could modify them -- that a computer science degree isn't required. This journal's main purpose is to help me reason things through while explaining them to you, my millions of readers, so I might as well spit it out and see if a solution comes to me.
In this diagram, the SRD Data encompasses all of the SRD data, which
can include rules (and therefore scripts) for the feats, skills and
other such things. This is slightly different than the SRD Rules
bubble, which is a more abstract set of rules. Where the SRD Data has
"if the character has Weapon Focus on a weapon, then add +1 to the
to-hit", the SRD Rules has the more fundamental ideas of "there are
six abilities", "melee attack is calculated by...", etc. The Race
Data and Class Data are also scripts, but are separate from the SRD,
since they're a re-interpretation of the SRD version of the monster
(in the aboleth case). There should, of course, also be SRD Races and
SRD Classes for the player races and classes. Finally, Character Sheet
is not scripting code, but just data -- the decisions made by
the player upon creation, when decisions had to be made.
<Character>
<Name>aboleth</Name>
<Race>aboleth</Race>
<Ability name="strength">10</Ability>
<Ability name="dexterity">10</Ability>
<Ability name="constitution">10</Ability>
<Ability name="intelligence">11</Ability>
<Ability name="wisdom">11</Ability>
<Ability name="charisma">11</Ability>
<Level number="1">
<Class name="aboleth"/>
<SkillRanks name="concentration">11</SkillRanks>
<SkillRanks name="knowledge" subname="any one">11</SkillRanks>
<SkillRanks name="listen">11</SkillRanks>
<SkillRanks name="spot">11</SkillRanks>
<Feat name="alertness"/>
<Feat name="combat casting"/>
<Feat name="iron will"/>
</Level>
</Character>
This ignores the Organization, Treasure, etc. that are part of
non-specific monster entries. We'll deal with that later. It
also ignores that the aboleth class should be over multiple levels...
baby steps!
So, given the above, we as human readers can see that we need to go look up the aboleth race, the aboleth class, each of the skills listed, and all of the feats. But how is this processing done? Should the Rules Applier look up the Race entry and apply that script? Should it then look up each of the Class entries and apply those? Then do the Feats? What about the Feats supplied by classes for free?
I think the Rules themselves should be the ones that recursively call scripts in races, classes, feats and the rest. You can basically say that it's a "rule" that the race has any effect on the character whatsoever. So, to start, the Rules script should do the following:
| <--Intermediate stage | ^--xmld20--^ |