This is another post about Blindside, the text-only realtime RPG I'm working on. At the moment, I'm both looking at tools and options for building game maps, and implementing tools for the game's AI.
The game is intended to be large and complex enough that I am creating it in two pieces: "engine" and "content". Let me explain, if you're unfamiliar with these ideas. The engine is software, and it does all the housekeeping like keeping track of your location, stats, inventory and health, and also figuring out what you can see, who you can attack, where you can move, and so on. The content is the all the stuff the engine needs in order to tell a story. So there's maps, descriptions, dialogue, lists of NPCs and so on.
In a sense, the engine is like a video game console. It doesn't do anything until you add some content in the form of a game. And then it comes alive. (Oldbies will be familiar with game engines like SCUMM, used for the Lucas Games graphic adventures; and the Z-machine, used by Infocom for their text adventures.)
The great thing about splitting apart the engine from the content is that if you design the engine right, you won't have to change it once it's finished. You just start the engine up and point it at the content. And you can then spend the rest of your development time working on content, and even keep making more content even while the game is running.
Because I want the monsters and NPCs in the game to have very different responses to the player, have some decent agency, and to actually be difficult to beat in a fair fight, the AI system needs to be both powerful and flexible. And when you want to teach a computer to do things both powerfully and flexibly, inevitably you'll want to create a language to do that. And, traditionally, when a game engine has a language built into it, it's called a "scripting" language, because you're creating a script for the characters, locations and items in the game.
So Blindside will have a scripting language of its very own. But wait, I can hear the wailing of the nerds -- there are scripting languages out there already! Why invent a new one? You could be creating content or making your engine better, why waste time on making a new language too? There are often justifications for making a new language, especially when the use for that language is very specialized.
One problem with many modern computer languages is that they are so generic -- so applicable to any problem -- that while they can do almost anything, you have to be extremely verbose and specific about exactly what you want done. You might like to think of generic languages as a big pile of 2x4 lumber and a huge pail of nails. You can build almost anything from a doghouse to a four story apartment building with these components, but it's going to take a long time and you have to be very careful and precise. A custom language, gives you the equivalent of panels for a prefabricated house. While you can only build certain kinds of rectangular houses of certain sizes with these panels, they go together very quickly and they work very well.
In computer science more broadly these kinds of specialized languages for making "prefab" houses are Domain Specific Languages, or DSLs, in that they're languages specifically made for a particular domain/use.
The goals for the AI language are that it should be very easy to understand (so one can review it at a glance), very easy to write (so I can teach it to others), be both terse and obvious, and still be flexible enough to allow lots of different tactics.
The language is still in flux but I thought I'd show you a bit of what it will look like. This little bit of code might be attached to an NPC that is part of a team of fighters, or maybe even a friend or companion to the player.
See if you can figure out what this does just by reading it.
first ally poisoned having health<25% order by health
definitely cast remove poison order by speed
possibly use remove poison having quantity>3
It should be pretty clear: If there are any allies who are poisoned and dangerously low on health, pick the one who has the least health and cast the fastest spell available to cure their poison and then end the turn, but if no such spell is available or we can't cast it, then if we have at least four items in our inventory that can cure poison then we might use one, but we'll also check for other things to do.
This is some pretty complex behaviour expressed in a fairly concise fashion.
And this code actually works, at least to a degree. What is happening right now is that the above three lines are converted by a compiler into about twenty lines of Javascript that do exactly what is described. (I'm not going to show it that because it's huge and ugly).
The cool thing about a compiling the AI code right into the same language that the engine is written in is that the AI code runs just as quickly as the engine itself. This is kind of unusual for DSLs and scripting languages in general -- usually they're interpreted step by step by the main engine program, or by a helper program called a library.
But making this a compiler is great news for Blindside -- it means the AI can be quite complex and still not bog down the system even if there's a few thousand creatures roaming around with their own little agendas. It also means my job creating the engine is somewhat harder, but that's a good trade-off. As a programmer, my job is to make computers useful and helpful.
And if by putting a little more effort into my work makes the work of others much easier, then that is what I like to call design leverage. If I spend an extra hour, or week, or month, in making something better so that all of the dozens or thousands or millions of people who use it can get an extra second, or minute, or hour of time back or make their use of my project more enjoyable, or at least suck less, then that is time very well bargained.
And now we're at risk of veering into my whole philosophy of engineering so I think I'll wrap this up now. Thanks for reading, if you made it this far, and thanks for trying, if you didn't.
Oh heavenly, fertile writing ground.
I can smell the tertiary syphilis from here.
share this with him. it might help, it might not.
I write fictitious plays based on true people and events. what I do is I read as much as possible about the true people and events. then I sit back and think about them until I come up with what the characters want, how they intend to get it, and what obstacles are in their way. Then I think about how they're likely to end up as a result.
then I think about what actions they need to take to get what they want.
then I write the play.
hope it's helpful.