• NOW LIVE! Into the Woods--new character species, eerie monsters, and haunting villains to populate the woodlands of your D&D games.

Open Source d20 API/Engine

Regarding history, I'm inclined to make characters aggregate rather than snapshot based. You might have:
Code:
<ability id="int" name="Intelligence" base="16">
  <boost value="1" reason="lvl4" uid="1293801"/>
  <boost value="1" reason="lvl8" uid="1295920"/>
</ability>
The uid is a unique identifier for a "change set" (e.g. all changes from advancing a level) so all related changes can be ignored to see an earlier version of the PC.
reanjr said:
If a developer wants to ignore history altogether, they can simply ignore anything with a snap-id whose snap-current is not set to true. This allows for complete interop between apps that do support rollback and those that don't. I don't think it is appropriate to force an application to start at the beginning and build up through the changes (and it's probably quite inefficient, too). It's much better to start at the latest and work back through changes. I'll leave the implemention details of how you delete data as you go back to someone else. Perhaps snap-delete="true" deletes the entire tag, while snap-delete-attributes="name id" could be used to, for instance, delete the name and id attributes of the tag. Anything specified (name="reanjr") is changed and anything unspecified is left identical.
I agree that a sequential build-up should never be required. But fundamentally, I think that the character should be stored in aggregate rather than final form.
 

log in or register to remove this ad

Planesdragon said:
As you know by know if you're on the d20-XML or FGA-Prometheus Yahoogroups (or if you've just checked www.theFGA.com), the FGA is going ahead with our XML plan.

I'll attach our first draft of an XML standard. It details a few of the basics, and as a sample file and sample XSLT included.

One thing that I feel is a good idea that's only possible in XML is the <rule> object: a selection of text that describes one rule, with a few subrules. Ordinarilly this is shown as headings and text, but if we add a specific markup to it an author or user or programmer can have software seperate rules and not-rules (such as setting information and whatnot.)

(Beyond the <rule> and a subest of xhtml, included are formats for races, classes, skills, feats, and spells.)
Cool. I'll take a look.
 

Currently I'm working on a Python-based character generator for my campaign, and I have a couple of observations that might be of use to you.

1) RDF/OWL is better than pure XML. RDF without OWL ends up being really, really hard to read because the XML format is horrible, but OWL lets you write stuff that looks like regular XML.
The thing about RDF is that you can define things piecemeal, extending definitions arbitrarily. For example, you could easily add new rogue abilities when you come across them, instead of having to modify the core SRD list. RDF is also *much* better for defining exceptions.

2) Complete dynamic UIs kill usability. One of the reasons I am doing my own generator is because every generator I've seen is a horror when it comes to being usable. There's no need for that.

3) Have a character template that encodes all the basic assumptions, like when a character gets feats, what the basic abilities are, etc. That lets you handle variations like AU or Traveller easily by modifying the character template. It also avoids the most common hard-coding I see.

4) Model armour and weapon proficiencies explicitly, rather than generalizing them as class/race abilities or feats. You have no idea how much it simplifies your life.

5) You can write a mini-language for evaluating expressions like (CHA/2)+2. Mine is based on MathML.

6) An awful lot of modifiers are conditional. Many generators forget this.

My code is GPL, but I'm not releasing it publicly until it's cleaned up a bit more. I figure it'll hit a 0.6 public release in about six months.
 

JBowtie said:
1) RDF/OWL is better than pure XML...
Thanks for the thoughts, JBowtie. I'll have to check out RDF+OWL--I'm not well acquainted with it.
JBowtie said:
2) Complete dynamic UIs kill usability. One of the reasons I am doing my own generator is because every generator I've seen is a horror when it comes to being usable. There's no need for that.
I agree with you there. On both points. I think a solid engine would allow people to develop excellent UIs for specific purposes. A character generator has different usability considerations than a DM's table manager. My chief concern is that at the end of the day, the data and engine do not force usability or mechanical concessions in either of those potential applications.
JBowtie said:
3) Have a character template that encodes all the basic assumptions, like when a character gets feats, what the basic abilities are, etc. That lets you handle variations like AU or Traveller easily by modifying the character template. It also avoids the most common hard-coding I see.
So you mean wrap up all of the basic non class-specific rules in that?
JBowtie said:
4) Model armour and weapon proficiencies explicitly, rather than generalizing them as class/race abilities or feats. You have no idea how much it simplifies your life.
That makes sense.
JBowtie said:
5) You can write a mini-language for evaluating expressions like (CHA/2)+2. Mine is based on MathML.
makes sense.
JBowtie said:
6) An awful lot of modifiers are conditional. Many generators forget this.
Yeah, that's one part I'm still thinking a lot about. How to capture the conditions (both character and game) that trigger certain rules and rule changes.
 

nopantsyet said:
Thanks for the thoughts, JBowtie. I'll have to check out RDF+OWL--I'm not well acquainted with it.I agree with you there.
Best place to start is the OWL guide(http://www.w3.org/TR/owl-guide/). Using OWL has opened up whole new realms of possibility for random character generation.
Skip the RDF specs, they're badly written and only confuse people (because their idea of XML syntax is absolutely hideous and makes people run screaming).

nopantsyet said:
On both points. I think a solid engine would allow people to develop excellent UIs for specific purposes. A character generator has different usability considerations than a DM's table manager.
I strictly seperated the UI from the underlying model; the engine has its own unit tests that exercise the API. Some assumptions are hardcoded into the UI (only handles 4 feats a level), but the engine actually is more flexible than that (can handle arbitrary number of feats).

nopantsyet said:
So you mean wrap up all of the basic non class-specific rules in that?
That's exactly what I mean. For example, my SRD template says a character receives a feat at first level. My AU template says a character gets two feats at first level and specifies the categories (ceremonial for one and talent or general for the other). A Blue Rose template would have a feat slot at every level. Currently the only things left hard-coded in my engine are a few formulas and rules about bonus stacking. Those will eventually migrate to the XML as well.

nopantsyet said:
Yeah, that's one part I'm still thinking a lot about. How to capture the conditions (both character and game) that trigger certain rules and rule changes.
For the general case, I have a optional condition attribute for all bonuses which contains the text of the condition; for <bonus condition="vs goblinoids">1</bonus> on the stat block/character sheet I print out "+1 vs goblinoids" (though I also specify bonus type in the actual XML).
When I'm ready to actually start evaluating actual conditions I can use OWL expressions, which will resolve automatically.
 
Last edited:

Well, I know you said you're not going to release your code until it's polished, but if you'd be willing, I'm really interested to see a simple example of how you're utilizing OWL. The ontological approach seems to encapsulate a number of the design principles I've had in mind. But I'm curious, does it really provide enough power and flexibility to be able to incorporate alternate rules? You mentioned AU and Blue Rose, so it sounds like it is. But what exactly does it do with a component like "vs goblinoids?"
 

nopantsyet said:
Regarding history, I'm inclined to make characters aggregate rather than snapshot based.

That's a huge pain for those who just want to use the program to input their character and be done with it or those who don't care about the letter of the rules. There's already dozens of programs out there that strictly support the rules. I don't really see a need for another one with just a different file format.

If you have automatically stored versions of the character at each level (or any other change you want to keep updated), then this history data is self-evident without forcing the developer or user into using one particular model.

That said, I think there is room for that sort of thing, but it shouldn't be enforced.
 

nopantsyet said:
I agree that a sequential build-up should never be required. But fundamentally, I think that the character should be stored in aggregate rather than final form.

But by putting it in that form, you are forcing the application to support it. What you want to do is instead put:

Code:
<ability id="int" name="Intelligence" score="18">
  <boost value="1" reason="lvl4" uid="1293801"/>
  <boost value="1" reason="lvl8" uid="1295920"/>
</ability>

If the app supported going backwards, it could figure out the original Int was 16 and apps that didn't support this could read that the score is currently 18, regardless of how it got there.

You have to have the data in its final aggregated form or you are forcing aggregation.
 

JBowtie said:
Currently I'm working on a Python-based character generator for my campaign, and I have a couple of observations that might be of use to you.

2) Complete dynamic UIs kill usability. One of the reasons I am doing my own generator is because every generator I've seen is a horror when it comes to being usable. There's no need for that.

I agree. I think the UI should support some dynamic elements, but overall it needs to understand what's it is trying to do.

5) You can write a mini-language for evaluating expressions like (CHA/2)+2. Mine is based on MathML.

I also agree with this, though I am going for something leaps more powerful (yet simpler) than MathML. I'm going for something Lisp-like (since XML lends itself well to that structure).
 

Yeah, I see your point in that context. Just as easy to work backwards as forward. I'm fine with the idea of storing the score rather than the base, and separating the aggregate to work backwards.

I was actually thinking Python since it's appropriate for semantic processing and it's easy to embed. But if some functional XML syntax is capable of providing the same level of functionality without embedding script, I'm liking that.
 

Into the Woods

Remove ads

Top