Character Generation [technical/theoretical]

smetzger said:


Well strictly from a rules point of view there are no restrictions on skills based on your race. The race in question should have racial modifiers for certain skills that are difficult for the body type. However, quite often the d20 monster description does not include such things.

It really becomes difficult when you are asked to program something subjective, or 'common sense'. Computers lack this ability, and code can be very difficult to do. Especially while trying to keep things strictly data-oriented. And then you get into the problem of having 10,000 checkboxes for every possible situation, which makes things hard on the end user.
 

log in or register to remove this ad

Archimedes said:
Checking all these cascades at run time can be done using the Observer Design Pattern. See Gamma E., R. Helm, R. Johnson, et al. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, Reading, MA, 1995. The Observer pattern is trivial, but potentially expensive in computer resources. Since you're only checking a few hundred, it shouldn't be too bad. :D

Sam
I've heard of the book but haven't read it, I'll try to look it up. It's mentioned in some other books on OOP that I do have, but unfortunately they don't talk about the Observer pattern. Can you briefly describe it? (Since I haven't read about it, it's possible that I'm re-inventing it in the project I'm working on.)

Peter Donis
 

Hmm... Interesting concept.

Let me start by saying that i'm no programmer (i dabble), and some of the terms you use are only vaguely familiar (N-Bodies or example). But i think i understand what you want to do and i can 'brainstorm' with that.

My very first question would be, what exactly do you want to accomplish?

1.) DnD (like) generator
2.) D20 generator
3.) OGL generator
4.) RPG generator

The lower you get on the list, the more complex the program gets.

1.) The program needs to understand the concept of the DnD (like) game, things are not specifically hardcoded into the program. But it has only limited under standing of the game concept (six attributes, levels, hit points, etc.). You could effectively input just about any type of race, skill, feat, spell, class, item, etc.

2.) The program needs to understand thing like Magic, Damage, Levels, etc. For example, Call of Chtullu uses a totally different way of using magic, Wheel of Time does it also in a completly different way. There has to be a way to define concepts that can then be explained through an external file. This would only be done on a limited scale, Different ways on how to implement Magic, Damage, AC, and other new concepts.

3.) The program has to keep up with all the possibilities that the OGL brings with it. If someone makes a level less OGL game, the program needs a way to understand that without a complete rewrite.

4.) The program needs to understand the concept RPG character creation (if not the whole idea behind a RPG ruleset). You would have to look at just about every RPG out there (and think up some) and start to write guidelines on how RPGs operate (specifically character creation). Those guidelines need then to be rewritten into a program that (effectively) understands how a RPG works when fed the rules for it.

I personally think that #4 is the most interesting. It's the most usefull for everyone, RPG content is completely seperate from the program, and it's the most challenging.

My idea would be to structure it allong this way:
a.) RPG Interpreter
b.) Specific game concept files
c.) Game feature files

a.) The program that reads (b) and then understands (c).

b.) The files that define the rule concepts how to hit your opponent, how damage works, how magic works, etc.

c.) The files that define things like (for example for DnD) skills, feats, spells, items, races, classes, etc.

Now the RPG Interpretor (a) would be a monster of a program (i think), because it would have to be very flexible and open (there are so many different RPG systems out there). It would be rather inefficient in it's use of memmory and processor ussage.

A solution could be to use (a) as a compiler, if fed (b) then it would compile an optimized version of itself that would then accept (c). The compiled program should then be able to run on a standard machine without to much of a problem.

(b) and (c) should be standardized in it's notation, much like the .lst files that PcGen uses.

Now, pardon me if this was not what you meant, please move along then ;-)
 

Jamis,

I don't know if this reply will be much help, but after reading this thread is seems to me that one aspect of your problem has not been mentioned. The purpose of any generator is to create something viable. For example, when generating a character, you want that character to be effective (able to affect the campaign world in a useful manner) and survivable. Certain combinations of abilities, skills, feats, etc. are more effective than others.

Any useful generator would have to possess a mathematical model of "effective" - in essence, a goal to achieve. The user inputs certain limits on the generator (race, class, level, or whatever) and the generator tries to reach as close as it can to an optimal result. Since certain aspects of almost any generator are random (ability scores, hit points), the generator would theoretically never generate a 100% match to "optimal" - it would simply try to achieve the closest match, within the limits of the user's parameters and the random factors.

It seems to me that creating such a model of "effective" would be extremely complex - probably requiring a number of algorithms to take into account the common sense used by all game creators. Once created, however, users could conceivably add or modify the material, simultaneously modifying the values for "optimal". For instance, a 3E campaign that eliminates the sorcerer's limit on spells known, without making any other changes, should increase significantly the value for being a sorcerer vs a wizard. The program would then tend to generate many more sorcerers than wizards.

An example of using values in a related way is the anti-spam program written by Paul Graham. He assigns values to various text found in email messages, prioritizes them, then has the program search for, and add up, the values. He's able to identify spam something like 99.5% of the time using this method. Here's the link to his article : http://www.paulgraham.com/spam.html (If anyone is curious, I found this article through Infoworld.com). In effect, he's identified the components of something he doesn't want (spam) and the program tells him if it exists. A generator would check combinations for what it wants (optimal) and keeps trying until it gets reasonably close.

Again, not sure if this helps, but I thought I'd throw it out here.

Good luck!
 

SirWhiskers: thanks for your input. That was very appropriate, and something that I had not explicitly considered. I'll add it to my research objective document, which I'm drafting right now. :)

Cegorach and Scott: thanks also for your input. I'm afraid I'm still not being very clear in my objectives, and I hope to remedy that soon with a release of a formal document detailing my goals. For now, just let me state that I hope to formalize the theory of entity generators; not just d20, or even RPG entities, but even things like prepopulating databases for testing and validation purposes. The document I am drafting right now will hopefully clarify all of that.

This thread has already been extremely valuable to me, in that it has helped me solidify in my own mind what, precisely, my goals are. I know many of you will not share those goals, or even be remotely interested in them, but I hope to find at least one or two of you who won't mind thinking and researching this with me. Even failing that, I may at least come up with a proposal that I can present to my thesis committee for my own thesis. ;)

- Jamis
 

PeterDonis said:

I've heard of the book but haven't read it, I'll try to look it up. It's mentioned in some other books on OOP that I do have, but unfortunately they don't talk about the Observer pattern. Can you briefly describe it? (Since I haven't read about it, it's possible that I'm re-inventing it in the project I'm working on.)

Peter Donis

I’d be happy to.

I don’t know what languages you’re familiar with, so I’ll keep it general.

Start with two classes named something like Observer and Observed.

Give the Observer class a method that’s traditionally named Update. Pass a reference to an Observed as an argument since the Observer may be watching more than one Observed and it’ll need to get at the data anyway.

Give the Observed class a list with type Observer and two methods, Add & Delete, that accept a reference to Observer as arguments. These methods add and remove the given Observers from the list. Most importantly give the Observed a method that’s traditionally named Notify. This method loops through the Observer list calling Update on each Observer reference.

These classes are usually used as Mix-Ins in languages that support multiple inheritance. In something like Java you can use Interfaces or Delegation. In the class that inherits from Observer you’ll want to override the Update method according to purpose and use the Observed’s Add method to register with said Observed. The later is often done in the Observer’s constructor.

In the class that inherits from Observed you’ll want to add the Notify method to the end of whatever method is used to modify the Observed.

Setting up this pattern is trivial in languages like Python, Ruby, or even LISP(Someone did mention Paul Graham). It’s also fairly simple in C++, but a little harder than it needs to be in Java.

You can make your objects both Observer and Observed, with the Observer notifying it’s own Observers when updated. That’s how you can avoid writing those logic tables of cascades yourself.

You can get fancier with the Observer if you want, using different Notify method that call variant Update methods or even using a vector instead of a list and registering a callback to replace Update when calling the Add method.

Maybe that’s enough for you to start looking. You should be able to find examples written in your language of choice out there somewhere. :)

Sam
 

JamisBuck said:
This thread has already been extremely valuable to me, in that it has helped me solidify in my own mind what, precisely, my goals are. I know many of you will not share those goals, or even be remotely interested in them, but I hope to find at least one or two of you who won't mind thinking and researching this with me. Even failing that, I may at least come up with a proposal that I can present to my thesis committee for my own thesis. ;)

- Jamis

I'm somewhat interested in the research and don't mind thinking about the problems at all. Please remember that my background is more practical than theoretical so I'm not going to be familiar with some of your jargon at the start.

Sam
 

I have finished the rough draft of my research proposal document. I did it in LaTeX (as my first attempt to use that language), so of course you can view it in pdf, postscript, and HTML. ;)

http://www.jamisbuck.org/research_goal

PDF version

PostScript version (gzipped)

Please check it out and comment on it; I've tried to be very explicit in what I do and do not intend to accomplish with this project. If you feel any part to be ambiguous (a definite possibility), please let me know so I can clarify it.

If, after reading the document, you feel that this is something you want to be involved in, please email me. But please note: I want to avoid discussions of implementation.

Well, we'll see what happens. :)

- Jamis
 

workflow definition

jmettraux said:


If you google-search for "workflow definition" you'll be directed to a lot of products or article, picking the right one will be hard.

http://www.wfmc.org contains a reference document about workflows.

I haven't found anything instructive enough to show you about workflows, I could post some products screenshots, but I haven't got any such applications at my home office.

The classical workflow engines take as input a workflow definition (edited by a workflow designer / business process engineer) that is instantied (a workflow instance). The engine interprets the definition and manipulates the instance.

The generator could take as input a generation task definition : a document describing how to compose a character.
If it's generic enough there could even be definitions for treasures or dungeons, with the same engine.

Programming is setting the level of abstraction a bit higher, it is also said to be 'extending a language'.
Here, we would have a language describing how to generate a character.

with this approach there would be three 'roles' ;) :
engine-developers, definition-designers and end-users. (compliance-officers... a 4th role...)

The role of definition-designers could of course be taken by a genetic algorithm : running the engine a lot of time with different definitions against acceptation criteria would soon point to an adequate 'definition' for a given game system.


Luke is right when saying that 'use-cases' are required for setting the scope (boundaries) of the 'project'.

Yeah, this is what we (another company, totally non-gaming industry) did in coming up with a way to handle similar data from disparate systems in order to allow the business software from different companies to talk to each other and talk to the banking infrastructure; purchase orders, to shipment, to invoice, to payment, etc.

In that case, I was the workflow designer / business process engineer and did the database modeling.

What you end up realizing is that you can't accommodate EVERYTHING. But what you can do is accommodate all the common things, just use the occassional translator. It's enough to allow communication and to allow for recognizability of the different datasets.

You create an engine that takes information in, let's you tweak it according to what type it recognizes that information to be...d20, gurps, t20, d10, George's own homebrew rpg...whatever...and lets you spit it out. In this case, you don't necessarily have to allow for imports, though it'd be nice. Just create it and spit it out.

We do a lot of the same type of thing in Campaign Suite. In fact, the further in development we go the more we've discovered we could do in various gaming systems with the same piece of software that it's to the point we've discussed dropping the d20 logo entirely. Why limit ourselves?

But there's always something really off-the-wall that some writer does that you just can't handle and is so weird (read: imaginative) that not enough use it to justify accommodating it.

I think, ultimately, you end up with an interface and work-flow that the user defines to some extent, odd as that may seem. But I'm not sure how doable that is. What we've done is a bit of a compromise on the ideal as we know the compromise is doable.

Of course, if someone ever really creates a decent artificial or machine intelligence that learns rpg's... The fuzzier the better!
 

Archimedes said:

You can make your objects both Observer and Observed, with the Observer notifying it’s own Observers when updated. That’s how you can avoid writing those logic tables of cascades yourself.
Thanks for the lucid exposition. I understand the pattern, and it's basically what I was thinking, but the issue is that at run time, each object has to know as it's created which other objects it needs to register with. That's what you need the (potentially massive) database table for--the alternative is to have every object register with every other, but then each object, as it's notified of another object's change, has to know whether that change will affect it, and if so, how. So again you still need a database table that tracks these cascading effects. I'm not saying the problem isn't solvable or that the pattern you've described isn't the right way to go--just that, even if the basic concept of the pattern is trivial, the implementation still isn't.

Peter Donis

(edit--P.S.) Another issue is that some cascading effects can happen when you add or delete an object rather than just changing its data, so objects also have to notify other objects when they are created or destroyed, and the other objects have to know how to deal with that too.
 
Last edited:

Remove ads

Top