Once again, we are back to knife-fighting in the pit. This is the traditional game design approach at Gaslamp Games; we fight to defend our ideas, using oversized weapons and our bare hands. Recently, however, somebody has been seen fashioning a rudimentary lathe – a troubling development that will either upset the balance of power or be absolutely useless.
So what have we been fighting about? Well, all sorts of things. Today, let’s talk about the AI. The AI Cabal – Nicholas, Chris Whitman, and myself – have been hashing things out, and what we have is a data-driven, XML-based monstrosity that is sure to please everybody. The whole goal of Clockwork Empires’ AI is to provide characters in the game (currently referred to, in-engine, as Citizens, although this is not something that makes David happy; after all, we are a monarchy) with unique, rational, and relatable behaviours. The plan is to start simply, and add layers of complexity to the game until the goals and aspirations of characters appear to the player naturally and gracefully.
A citizen job consists of three basic parts: a collection of requirements, a utility function, and a finite state machine that consists of a collection of other, smaller, finite state machines. Hooray for complexity.
When a citizen has no job, they poll the job blackboard (an invisible construct, as far as the player is concerned) asking for work. The jobs dispatcher looks at the list of all jobs that a citizen can perform (based on what, we don’t know – right now, it’s basically just a whitelist), and returns one job that it would like the citizen to do. The citizen then looks at all the jobs that it wants to do that aren’t on the blackboard – things like eating, sleeping, and ingesting opium pods – and ranks each of these jobs according to two things:
- Do I have enough resources to complete the job? If not, this job is invalid. (i.e. if there is no lumber, I can’t cut trees; if there are no opium pods, I cannot ingest opium pods.)
- How happy will this job make me?
The happiness of a job is determined using utility functions. The utility of a task is determined by a number of factors – basic constraints, variable constraints (how hungry am I? how mad am I?), and distance constraints (how far am I from the match factory?) Characters then color their utility function based on their own individual preferences: favourite pub, peaceful disposition, distrust of honeybees, general laziness, piousness, or whatever else we want. Some of these pieces of information come from a character traits system; characters with certain traits may be more likely (or less likely) to do certain things.
When we can do a job with more than one type of resource, we pick the best resource – the combination of resources which produces the highest utility. If a character can choose between drinking whiskey and gin, and the gin is closer but the whiskey is better, which one he chooses depends on how we set the weights of the utility function elements.
The character will then base their actions on these values. The FSM starts running, going through stages – walking to required objects, collecting required objects, walking to a job site, playing animations, and doing things. At any time, a citizen’s job may be interrupted – either by receiving a message requiring the citizen to re-evaluate his situation (“You are on fire now.” “You are being eaten by a bear.”) or if one of a certain category of possible jobs, which are evaluated sporadically during FSM execution, kicks in and is determined to be more useful than what he or she is currently doing. For instance, if a character is starving, at some point the “must find food” job becomes more useful than the “make widgets” job. At this point, we stop what we’re doing and switch tacts.
A job program (or FSM) consists of a collection of tasks, each of which (internally) are handled by other, smaller, finite state machines. Yay, progress.
Jobs also have event blocks attached to their XML. This tells the game some basic information about how the event affects the world. Events are tagged with a longevity and an importance; longevity indicates how long the event is remembered, and importance indicates how important the event is. (Importance scales exponentially.)
Since we’re creating a moddable game, we’re eating our own dog-food. All of this is data driven. A sample job might look like this:
<job name="Pick Berries" display_name="Pick Berries" mandatory_eval="0"> <requires_resource_source type="plant" flag="BERRIES" amount="1" tag="bush"/> <requires_stockpile type="food" tag="stockpile"/> <utility> <base_job_utility weight="1"/> <distance_from tag="bush" weight="-1"/> </utility> <fsm> <walk_to tag="bush"/> <harvest tag="bush"/> <walk_to tag="stockpile"/> <drop_item_in_stockpile tag="stockpile"/> </fsm> <event importance="1" longevity="1"> <newspaper headline="[CITIZEN] Engages in Leisurely Berry-Picking" subline="Grand Day of Not Starving Reportedly Enjoyed by All" norton="about the unsightly picking of berries by [CITIZEN]"/> <poem type="commemorating the plucking of berries from a bush by [CITIZEN]"/> <art type="the plucking of berries from a #TAG bush# by [CITIZEN]"/> <element name="berries" plural="1"/> <element name="[CITIZEN]" plural="0"/> </event> </job>
And there you have it. Clearly, berry-picking is not an important event; however, if nothing else is going on, it might show up in the Empire Times. The “norton” tag is used to indicate the name of the gentleman who consistently writes to the Empire Times; his primary function is to complain about things. This is based on, and named after, a real chronic letter-writer to the Times of London circa 1898. Element tags in the event block indicate what the things are in the event. For instance, this event involves berries, and whoever executes the event [CITIZEN]. Consequently, you might produce art, commemorating the plucking of berries by Jeremiah Widgetsocket, where Jeremiah’s expression is plaintive, and the berries are… berries, I guess.
Internally, this is all handled by our message-passing and scheduling architecture to try to make these decisions as efficient and as parallelizable as possible. It turns out that making useful decisions about what a character should do in any given frame is difficult and expensive; fortunately, we have the technology to make things faster. But that’s a story for another day.
(Also, Sean drew these. This can’t be good.)
So that is what a diggle looks like without a horn.
Thanks for those nightmares.
Really enjoying those behind-the-scenes posts, keep them coming!
One unrelated question, if I may: I know (and greatly enjoy) Gaslamp’s usual humorous take on things, but, well, Victorian colonialism was a pretty nasty thing overall both for the people they conquered and for the ordinary “citizen” in factories. Are you planning to deal with that nastier side?
I suppose it’s a tough question that crops up whenever a game, even if a fantasy one, touches upon “real” controversial historical periods, so I’d be interested to see your opinions on that. Thanks!
We will be including some of the darker side of Victorian colonialism, to be sure. One of the reasons that this time period was so attractive to us was that it has a high quantity of ethical quandaries.
For example, one of the things that we are still debating internally is whether (or how) to represent an indigenous population in any area that you’re “colonizing”. In this case, there’s a really interesting series of choices the player is faced with regarding whether you choose to cohabitate or not. Our task in this case would be to present the situation in such a way that, whichever choice the player makes, they will feel a profound impact on the game that will give that choice gravity.
We are going to be playing a lot with the balance of these choices to set the tone of the game. There will be a lot of humor – it’s what we do, after all – but I suspect a lot of it will be black humor.
To add to what Daniel was saying, we’ve had many internal discussions about this from the beginning. It is, of course, our intention not to make something horribly offensive. At the same time, one can portray something one considers evil (murder, exploitation, the implications of colonization) without condoning or approving of them — and without, even, bowdlerizing or whitewashing them as if they never existed, which is a course many games have taken. That said, we will of course be careful and see how far it is reasonable to take all of this with a good balance of tone, respect, and ultimately of course the goal of making a game.
I’ll say this again because it’s important: We do not want to make something horribly offensive.
Thanks for the replies, guys. My opinion would be that you should include indigenous populations – I could never really stomach the venerable Sid Meier Colonization because I always thought it unacceptable to try to depict colonization without slavery, for instance.
But I know that choosing to include them will lead to a lot of interesting decisions, so you guys should have some fun with that 🙂
Yeah, Colonization was exactly was I was thinking of. Played a ton of that as a kid.
Paradox Interactive’s games are interesting to discuss in this regard as they cover some very grim bits of history. Europa Universalis 2 (the one I played a ton of) had a very abstracted take on slavery and what amounted to colonial extermination. In their Hearts of Iron I played as Germany fairly often because from a mechanics standpoint you get to choose all your battles, but I really, really don’t think I could have stomached it if they’d actually used swastika flags and had Holocaust events. So I suppose it helped me enjoy the game. There are, however, some weird people obsessed with German WW2 revisionism that show up on the edges of the wargaming communities; I think Johan @ Paradox commented on the phenomenon in an interview at some point.
Does it do history disrespect to remove or highly abstract atrocities? My non-answer: The answer is no doubt extremely complex and thankfully Gaslamp is not making historical games so we can side-step or modify issues as we see fit.
(Though of course we intend to do it with respect to the history we reference.)
Thank you for being dedicated to not being horribly offensive with first nations/indigenous people. I am personally glad to hear this.
Well I hope it’s casually and tenderly offensive.
captcha: beamuma 11165
Probably you are already too far on this path, but may I suggest investigating other means of data-driving? For example, a scripting language such as Lua, or maybe Lisp?
Scripting languages aren’t a good model for what we want to do, or for our parallelism model.
“distrust of honeybees”
God I can’t wait for this game.
Thanks for these updates! I love the detailed programming talk. AI is a bit of a hobby of mine so this is a very cool read. Feel free to go on in great detail about your architecture for parallel tasks at some point – it’d be fascinating!
“Since we’re creating a moddable game, we’re eating our own dog-food. All of this is data driven.”
Speaking as one who will no doubt also consume and regurgitate and then your dog-food, I thank you heartily for your Pavlovian dedication to your modding community (and to science!). Your dog-food induced retching is music to my ears.
You guys are swell.
It occurs to me the swelling could also be an indication that you’re actually at this moment choking on a chicken bone that made it through the dog-food factory largely intact. If you need anyone to stick a finger down your collective throat, I’ll be the first to volunteer. I’m not entirely certain what I just volunteered to do, I just got carried away with the metaphor.
You’re swell either way, though, and I think we can all agree that that’s what really matters.
I haven’t had a chance to read the comments yet, but this is fascinating. I found myself going through decisions after reading it and realizing they are pretty closely associated with the FSM analysis of what I need to do, what order I can effectively do them in based on their relative distance and how long I could put things off.
Thank you for posting this. And the art 🙂
If CE depicts a monarchy, might not it be more appropriate to call the characters “subjects”? Or is that too broad a term with too many possible definitions? I don’t know, I think it would work.
I have been arguing strongly for calling them subjects all along!
Post some more XML, I want to see some pre-emptive modfare.
Also, whatever happened to the Docks & Frocks?
( Docks N’ Frocks also the #1 place for indecent air captains-for-hire)