Monday, May 15, 2017

Planning for Computerized Characters

The project I am currently planning can be broken down into several iterations on the same theme. I'll try and break it down here, noting that this is not a finalized roadmap, just my current headspace. There's bound to be some overlap and messiness as I sort these concepts out.

Digital Representation


Player characters are represented in a digital format. I do generate character background with a program which takes the six ability scores, sex, and character class as input; however, the generated info is then printed onto paper and used as a supplement to the character sheet, so it doesn't remain digital. Note that for this stage I am only talking about a computational object which represents the character.

The tough parts here include inventory and currently-equipped items. I'll circle back to these.

All-Digital Generation


All of character generation save for the initial 6 dice rolls, rolling for HP (class and mass), and probably something else I'm forgetting, are handled digitally. While, again, the combination of character background traits is already generated digitally, this stage would at minimum require me to program the computer-logic versions of ability score lookup tables  like these. At the most basic, these computerized versions would allow for the generator to automatically include ability bonuses (e.g. +1 melee attack for a high Str) for easy reference.

Live Updating


So I upgrade the character generator to create a complete character, not just their background, and that includes looking up ability-score bonuses, as above. So what? Here's what: suppose a character gets hit by a spell which lowers their Strength. Using a "communication mechanism", I will discuss shortly, the character record is updated to move their Strength from 15 to 11.

Now what we want is for the bonus on the character sheet to change to reflect that drop (using my tables, that would mean going from a +2/+1 melee attack/melee damage to +0 on both.) That means writing code to monitor the ability score, and when it changes (through said mechanism), making the appropriate values drop. This in turn would require dropping the character's current total attack bonus, no? There's a cascade of effects.

And of course we'd have to be careful not to write the code such lowering one's Constitution into a different bonus-HP bracket wiped out the bonus HP earned for HD from previous levels! Oh no!

"Communication Mechanism"


When I say "communication mechanism" above, I am referring to some way of reading and writing  the data in the character record.

The end goal looks a little like this: I send the message "Arvak, thirty foot fall, soft ground, 45 degree angle, jump was not intentional" to a controller program which can read in data for my players' characters. The controller fetches Arvak's data, and then fetches the computer-logic form of the falling algorithm. It tests the appropriate conditions, it rolls the appropriate dice, it accesses Arvak's Dexterity if necessary. It outputs the damage to Arvak and writes the change in his HP to his record, and therefore to his computer screen.

All of the above is possible to construct. I am describing here a domain-specific language (DSL) in which game actions can be expressed and their results applied to the computer records which represent game entities.

Suppose I code the message "decrease HP." This message (function) requires someone who will have their HP decreased and an amount to decrease it by. It returns the modified record. No checking is done to see if this kills them. That is the province of  part of the update system, which sends the "die" message to entities whose HP drops below -10 (or -4 if they're unleveled -- see, we have to track these things.)

Consider where we can go from here. We can write a more advanced message, "decrease HP with respect to damage reduction", which internally uses "decrease HP", but checks to see if the person who is to lose HP has any DR, and if so what type it protects against -- and then all of a sudden we need to know what type of damage is being dealt ...

You see that there is a shitload of complexity here, no? That's why I have to start very very simple and build big stuff out of small stuff. Start with a "decrease HP" primitive message that doesn't give a flying fuck about the rules for death, or DR, or temporary health, or whatever. Now, we DON'T want to use the basic "decrease HP" message for real: we'll build more sophisticated structures on top of it, like "decrease HP as a result of some-damage-type with respect to DR" and then we can build "deal fire damage" as a specialized version of that, and then we can build "deal variable fire damage" as a specialized version of that ...

And then things start getting really interesting, because we want to start thinking about locations. Areas. Zones. That's going to require the next huge shift, the one I've been trying to get started for years but haven't found an entry point: representing THE GAME WORLD digitally, the places and locations and the positions of the characters too. (That's beyond the scope of this post, though.)

Once locations exist -- and we're talking maybe 5 years from now -- then we can express the message "deal variable fire damage as a function of the mage level of Entity A to all entities in the area encompassed by the circle starting at the given point and having a 40 foot diameter."

Perhaps you know that one as "Fireball."

A Note on Intentionality


My philosophical goal while considering and while building these systems is as follows:

I decide whether a rule applies, and if it does, the computer calculates its effect.


Consider the example above, with dealing damage to Arvak because of a fall. Don't you, reader, think that whether or not Feather Fall has been cast on Arvak, should affect the algorithm's decision?

Well, yes, that's the ideal, but the concept of reifying spell effects as messages is, as I've alluded to above, many years off.

Luckily I'm a DM and I can just say, "You've got Feather Fall so you can fall that distance no problem, it'll take this long to drift down gently, no damage is suffered."

No need to run the falling damage algorithm and see if anything happens, because as a DM I know when certain rules override each other.

At the end of the day, all I am really trying to do here is codify, in a programmatic way, the rules that run my game, so that I can give myself the option of shifting the execution of rules to the computer when convenient. As the system grows more sophisticated, I allow it to do more of the "decisions" (i.e. checking rules interactions) so that I am not above the law.

Wrapup


Well, that all turned into a bit of a whirlwind tour of where my head is at, no? Vlad, you left the comment last time that sparked this post. What do you think?

All of this starts with digitalized characters. Once characters are digital, once entities are digital, then I can write a system that manipulates them, that codifies game actions into algorithmic form, along the lines of the "message" metaphor I've been using here.

And one day, one day, one day, I will have a spell list that works on the message system, too. And I have BIG PLANS for that.

But those are beyond the scope of this post.

3 comments:

  1. Hello !

    First, many thanks for the post-as-answer. All is very much clear now.

    Although the scope is big, but the roadmap looks solid to me.

    As someone that started such a thing in the past (but got sidetracked by life, big time), I had more or less the same (however, I started on a Dice Roller to allow for the character sheet to make dice rolls, as it was a major pain in my ass then).

    I'd recommend not going too deep on any one of your steps before having a workable version. Having a full Digital Representation is all good and well, but if you have to code it again because it lacks keys elements that you discovered when doing the Live Updating, that'll discourage you.

    A first stage would be to have a barebone Representation (Ability Scores, Ability Bonuses, HP, Attack Score), the associated Generation (ability scores to ability bonuses to HP & Attack Score), and a barebone Live Updating (update Ability Score, update Ability Bonus, update HP, update Attack Score).
    Then you test-run the whole, and you'll have a far better grasp on what's needed. Then you will probably have to rebuild some parts of it.

    Next stages would be cycles : determine what you will add => modify Representation => modify Generation / Data => modify Live Updating => test.

    The idea is to always start small but wide, covering lightly lots of ground to ensure that the general process is sound - because this general process will be the heart of your program, and going back cost motivation and time.

    That's all for now (and only my own advice), I must leave, but I'll be following ! ^^

    ReplyDelete
  2. Vlad, thank you. Your advice is sound. You've described more or less exactly how I typically approach projects: get the smallest working version of Part A, and then get the smallest working version of Part B which manipulates Part A. From there on it's a process of first upgrading A and then upgrading B to match.

    I've been dragging my feet a bit for no good reason, so I'm not quite done with a prototype, and that's embarrassing. I will say I have the basic Representation done, as well as the codification (heh) of the rules for fighters getting such and such attack bonus at such and such level, and the attack/damage bonuses for Strength. A post is in the works, and, as I am facing some air travel time this weekend, I aim to have the prototype and/or a blog post discussing it done within three days.

    ReplyDelete
    Replies
    1. Thanks ^^

      Well, I didn't say anything extraordinary, but it's nice to know you have the same approach. I think it'd fit this one well.

      What is the programming language you'll be using ? Are you sure it's good enough for your "Communication Mechanism" ? As it really seems to be the heart of the project, you need to have one that does it without much work.

      I'm impatient to see your next post !

      Delete