I've been plinking away at a new system for handling plots in computer games. I've come up with a tentative scripting meta-language which, in theory, can handle any kind of plot and allow a computer to change the plot slightly to account for player capability.
Of course, I can't decide what to call the language. I think that "plotz" and "plotalot" are both likely to have it die without ever being born. Heh. I guess I'll call it "Perkplot", at least for the moment.
Perkplot works as a constraint system using a few basic fundamentals which all plots share. Although Perkplot cannot come up with plots, it can modify plots to take into account a given player's capabilities by adding or relaxing constraints, and instantiate a full plot without requiring everything to be carefully scripted.
What's a plot?
A plot in Perkplot is a set of constraints and challenge markers. A challenge marker changes constraints and a constraint limits how you can reach or use a challenge marker. A constraint may be, but is not usually, a plot.
For ease of discussion, a plot is considered to have "nodes". A node is a given group of challenge markers and constraints.
For example, if you wake up in jail, the first plot node might involve getting out of the cell. The second might involve getting past the guards. The third might involve figuring why you're in jail. Each of these nodes probably has a fairly large number of constraints and challenge markers, but another node is not likely to share them.
These nodes are for simplicity of discussion: they are not actually inherent in the language of Perkplot.
Challenge markers are the heart of the plot. This is how plot moves forward. A challenge marker may be a place, an event, a thing, an acquisition, an action, or anything else that can be measured by the game. A challenge marker allows you to move from one plot node to the next because when it is triggered, it changes the constraints and challenge markers in play.
If multiple challenge markers are reached simultaneously, the one with the highest priority happens first. If there are two markers with the same priority, the one with the most constraints on it happens first.
This allows you to perform some detailed plot "trees". For example, if someone reaches a room, you can have two markers in it: a "reached room" marker and a "reached room with ally still alive" marker. In the latter case, there's a constraint on it: the ally still has to be alive. Therefore, it fires first. In firing, it erases the "reached room" marker.
They can also call other markers. So maybe the reached room and reached room w/ally markers both call another marker which is used for the results they share.
Anyhow, just traveling from marker to marker isn't terribly fun. Therefore, we put in constraints.
constraints are things which change the way the universe works. This allows plots to actually exist rather than just be a long line of challenge markers.
For example, if a plot is about a virulent space disease, then one of the constraints might be that certain people get sick and cannot travel. This sickness may even spread. This constraint changes the way the world works and also packs a strong emotional punch. This constraint sets it apart from another plot about space pirates or tribbles.
Anyhow, constraints are often used to keep players away from challenge markers. This is the challenge of a plot: to solve it despite the difficulties.
There are a few kinds of common constraints:
Data constraint: A data constraint is something which could theoretically be solved without any information, but is very difficult to. So you need to go hunting. It's very similar to a key constraint, but generally can be bypassed by walkthroughs or multiple playthroughs.
Key constraint: A key constraint is the classic widget hunt. Of course, not all widgets are physical. A key constraint can require a keycard, a code, a person, a decision, an attribute, and answer... anything, really. It's a very specific constraint often used when you need to highlight a given piece of information, person, or map area.
Character constraint: A character constraint is something which requires a character skill or attribute at a given level. For example, lockpicking. In simulationist games, you can usually use other characters to fulfill these constraints. In a less simulationist game, using another character's skill would fall under a key constraint rather than a character constraint. The biggest difference is that a key constraint always has a solution. A character constraint might not.
Red Herring constraint: This is a constraint which exists solely to make the player try to solve it, even though it is unsolvable. Perhaps it requires an impossibly high skill, or a character that's dead, or a widget that doesn't exist. These really piss players off.
Hunt constraint: A hunt constraint is a constraint that can be fulfilled by trawling the area. Whether social, physical, or locational, the hunt constraint offers a way "past" the other constraints without disabling them. For example, finding a hidden door or getting the king to write you a letter of recommendation.
Skill constraint: A constraint which the player must perform an actual skill-based game to fulfill.
Chain constraint: A chain constraint is a constraint which can only be fulfilled by reaching another challenge marker (and, usually, solving a bunch more constraints).
None of these constraints are actually different in terms of the language: they are differentiated specifically for discussion. In the language, you simply list the method(s) by which a constraint may be filled, whether that's a challenge marker or a ball-point pen. (This is why some of the "types" of constraint conflict.)
Can't Get No Sastisfaction!
The problem with simulationist games is that players will often find that a plot has become either very easy or impossible.
By creating a constraint satisfaction language for your plots, Perkplot allows the system to adjust the constraints to match the available resources.
When a constraint is introduced, Perkplot determines roughly how easily it can be satisfied. For example, if a constraint requires someone with red-level access and two of your party members already have it, the constraint is worthless. Therefore, new constraints need to be created to make the game a little more fair.
Each constraint has a supposed difficulty. Although they could be painfully marked one by one as the game is created, it's generally easier to just have "easy constraints" and "hard constraints", along with maybe a few "very hard constraints" for things like bosses. constraints which are created in play have this difficulty automatically calculated and compared to the difficulty they were intended to have.
If a constraint comes in as significantly easier than it should be, a new constraint is created at about half the difficulty difference. This means that making wise choices is still rewarded, but without making the game a cakewalk.
Creating additional constraints is one of the key elements of Perkplot. It uses what is pretty much simple graph theory to determine a valid additional constraint for the too-easy constraint in question. The constraint may go "above" the first constraint, requiring you to do something before you can fulfill it, or "below" the first constraint, meaning you do the first constraint and then realize you're not done.
An example of the first would be if your red-level clearance party member was kidnapped: you have to track him down to get your red-level clearance back. An example of the second type would be if after you open the door, a monster attacks you.
In addition, if a constraint turns out to be considerably harder than it should be (and is the only path to a marker), a new challenge marker is added that will bypass the too-hard constraint. For example, if you need red-level clearance but everyone with that level clearance was spaced, the "blow the hell out of the door" marker will be added, allowing you an alternate method of obtaining entry.
Of course, in a simulationist game, this is usually not needed. Although spacing the captain would make it harder to get that clearance you need, there should be a large number of other ways of accomplishing your goal through the "natural" laws of the universe. Crawling in through ductwork, or hacking the door, or blowing it up, or going back and finding the captain's spaced body.
Also, good designers will likely have several "routes" to any given marker. If a route is too easy, it is made harder. But if it is too hard, simply take another route.
Either way, we run into one of the problems that this system was created to prevent:
Very few games have every constraint spelled out to you. Moreover, even the ones which are spelled out usually have lots of steps which are not. However, an automated system cannot meaningfully choose if and how to represent constraints.
constraints are the part of the plot that give it an emotional appeal. As a writer, the designer needs to tell the constraints as best he can in order to make the player feel like something important is happening. The system cannot frame constraints such as "Dave just died" in ways which are both interesting and touching. That's the writer's job. They should write in a cut scene, or a piece of dialogue, or something.
But the system does create new constraints. These constraints have to be clearly stated, but need not have any emotional content. For example, if the door breaks and you can't get through, the game can simply tell the player, "The door is broken. Maybe there's another way around/Maybe there's a way to fix it." (Whichever is the case.) It doesn't have to try to inspire you to any emotion other than irritation.
This is the missing heart of the system: it generates no inherently emotional content, just balancing content.
Creating constraint series is what the whole game is about. Really, you just move from constraint to constraint during the course of any game, with occasional bouts of luck and skill in any given constraint.
For example, imagine a level from a game like, say, Doom. Each corridor and room can be thought of as a constraint: once acheived, new constraints are made available. The room off to the side. The collapsed rubble pile. The elevator.
A hallway can even be broken up into multiple constraints, if it is long enough for that to make sense.
These constraints would allow us to modify the level to change over time. If the level is too easy from point A to point B, one of the constraints fails. A hallway collapses. A door needs to be unlocked with a widget from point C. Etc.
Any physical level can be designed like this. Moreover, any nonphysical level can be designed like this.
Peoples' relationships can be defined as a set of constraints. People's positions can be constraints. People's beliefs can be constraints. What weapon can affect someone is a constraint. How much damage they can take is a constraint.
All of these constraints change the way your world works. They can be built with painstaking personal care, or they can be assembled by algorithms. They can be big, affecting the whole game, or small, affecting one corner of one room. They can be physical, mental, emotional - anything you want. You can have a constraint that says all type 1 doors can be blown off their hinges with explosives, or a constraint that says this particular door can be.
The key here is that constraints are a navigable graph. You can tell which constraints lead to which constraints, and thereby you can tell how many "nodes" and how much "difficulty" there is in trying to accomplish a specific task.
When the constraints gain too much complexity, things can start to become a little shaky due to the difference between the searching algorithm and the emotional player simply grokking the situation. But for most games, that's simply not a problem.
(Don't forget: a constraint can be long term. It's not like every time you hit a challenge marker all the constraints go away. The ammo you spent and the friends you lost stay spent and lost...)
Perkplot is useful for more than just making your plots adapt to a chaotic player presence. It's also useful for adapting your non-plot elements and allowing you to plot a plot in vastly more detail.
Preferably using a computer tool, you can reduce a given plot sequence down to a set of constraints and markers. You can bring in what the player is likely to have as resources, see if it works okay. Moreover, you can bring in the bizarre extremes that players are likely to bring in: the player who can't hit the broad side of a barn. The player who's been leveling for the past two weeks. The player who hates your stupid mascot character so much that he leaves her dead continuously. The player who forgot to buy a new weapon and is still weilding "pointy stick, mark one".
This is especially useful in more simulationist games. You can write a simple script to run through all the permutations. What if the player brings comes in a mage? An archer? A swordmaster? A berserker? A thief? What if he comes in with eight hundred packs of high explosives and no gun? (A valid tactic in surprisingly many games...)
What if the player is friends with group A? Group B? What if he hates both? What if he has them radically outclassed?
Now, there are parts of your game that might not technically be constraints. Like the NPC AI. I suppose you could make it a series of restraints, but it would be kind of messy. So, this simulation is far from perfect. But... it is helpful, don't you think?
It is easy to program in a system of adaptive constraints which allow for and more fully utilize pattern adaptation control, wolfpack memetics, and some other fun content adaptations using words nobody who hasn't read this blog has heard. :)
The grain is a little coarse, but it's still much better than existing systems, which don't have the capability at all.
Just in case it's hard to understand, here's an example.
Let's say it's a college hijinks game. You live in a dorm, as do many other characters.
The level constraints are relatively simple. In the dorm, each wing of each hall is a constraint. While fulfilling that constraint, you can go to stairwells, elevators, hallways, and rooms constraints which are fulfilled by the constraint you are currently standing in.
So, if you're standing in your room, the only constraint it might lead to is the hallway constraint. From there, you might take the elevator constraint to the lobby constraint and out into one of the campus constraints. We'll stick to our dorm for now.
Each person in the dorm has his own laundry list of constraints. Who they like, what their schedules are, which room is theirs, what they enjoy. This allows the player to interact with them in a more freeform manner. If correctly programmed, the constraints in this part are open to freeform alteration. Ellen likes Frank? You can intervene. Maybe get Frank to go out with her. Maybe get her to hate Frank. Whatever.
The exact level of response we can get from these characters depends on how we've built our restraints. In our game, we might be able to get Ellen to fall for us, or if reality doesn't bend that far, maybe not.
For plots, maybe we have a power failure. Our constraints come into play. It's dark. The elevator fails. The campus' overactive security doors slam down into "bulkhead" mode and the stairwells aren't accessable.
Our plot demands two people in the elevator: Gerard and someone else. Gerard is terrified of dark, enclosed spaces. Who else is in there?
Well, it could be random. Or we could have a specific person. Or, more likely, we can choose someone based on their connectivity with Gerard. Of course, to allow NPCs to freely change their opinion of other NPCs, we'd need a pretty solid social engine, but we could have scripted changes without too much issue. Maybe Gerard is stuck in the elevator with whatever's closest to an enemy. After a little while, they get in a fight. After that, they give up on being enemies and come to an understanding. After that, Gerard goes cannibal.
We could set it up however we like. That is why we write the plot, not the system.
How would you rescue Gerard and his enemy? Well, we can also define that, but remember that we already have a constraint net in place. We need to remember to disable the standard "hallway to elevator" constraints. Then we put in new constraints: turning the power on, breaking the doors open, whatever. We can put in some other constraints where we can shout to people on other floors, or even go out and in windows. Maybe we can hear Gerard yelling and pounding on the door.
All of this can be done with constraint management.
If you got this far, you are a patient person, and you have invested an absurd amount of time in this. So, invest a little more. Comment.