Back in my post on Coding Away, Thur. May 30 2019, I had a brilliant idea. That, as it turns out, was complete shit. I'm picking through the wreckage of the code and I don't think it ever really worked right. And worse, I can't understand what on Earth I thought I was getting out of making things so complicated.
The mess is bad enough that I'm more or less starting the development of clay stage from scratch. I had a sense that I was going to have to do that to some extent anyway, to facilitate threading. But I'm basically back to square one as far as figuring out what it was I wanted from my interaction engine.
So partly for your benefit, and mostly for mine, I'm going to lay out what exactly the engine is supposed to do.
The design of the Stage is heavily influenced by my work in a past life with the Department of Defense's High Level Architecture. Years of programming in Tcl/Tk's event loop have also influenced me heavily. The "Stage" is my answer to the Run-Time infrastructure. Under clay-stage, objects post events to the Stage, and other objects are notified of those events and react by updating their own internal state, and posting their own events.
Not all objects in the simulation are on the Stage at any given time. Thus, objects can ask to be brought on stage in response to key events. Objects can also request other objects be brought on stage. And, when entering the stage, every actor can review all of the events that have happened while they were off-stage.
Player interactions through the game world take place on one stage at a time. However, a game may have several stages going on at once. These stages need not be physical locations. They just simply mark where multiple objects can interact according to a set of rules. Different stages may have different rules for interaction.
One has to draw lines at some point on how far an interaction can go, however. So events are marked with a scope. A private scope of an event is strictly between two objects, though other objects may snoop. A local scope of an event is intended to be observed by all participants in a stage. A global scope of an event is intended to be observed by all objects in the game.
So let's handle some bread and butter interactions, and walk through the process by which clay stage will manage those interactions.
Every room on the ship is its own local stage. The player exiting the room they were in before causes an event recording that the player left. The player entering the room causes an event recording that the player entered. Likewise, other characters entering and leaving also trigger events.
In my perfect world, many of the AIs are capable of independent movement. A shopkeeper goes home at night, stops for coffee in the morning, may or may not keep a regular working schedule, and even has a hobby or a favorite hangout. The player may overhear two AIs exchanging information.
The problem with that perfect world is that the engine would need to run every AI and the player would have to track down individuals. I would also be limited to running the world in real-time. This system would also be hellishly slow and get slower as more characters are added. In IRM I can get away with 60 or so agents running around because there is only one crisis on the ship at any given time. Most of the agents are standing around waiting for orders.
So... I need to allow for "quantumn" characters. These are character actions and interaction that take place probabilistically and in the background. Two NPCs may fall in love, or start a feud. How the fell in love, or what started the feud is not very important. What is important is that over time the effects of those interactions DO start to matter to the game.
For the purpose of example, lets say that we have two best friends that fall for the same boy. Becky manages to score a date with David, and Jenny suddenly feels like Becky betrayed her. As David and Becky's relationship develops, Becky and Jenny's falls apart.
The player character may barely know Becky, Jenny, and David at the beginning of these events. And the player may only become aware of them after a catfight breaks out between Becky and Jenny months later. Or perhaps he sees Becky and David out on a date. Or... both a few days apart. Or perhaps the player will just hear gossip about the events.
One approach would instead of scripting events, script the probability of likely events given one relationship or another. Part of the probability will be is the player character likely to be present, or hear of the event second hand, or only hear of the event as part of plot development.
There is a lot we know happens when people fall in love. They have a first date, at some random point close to the beginning of the relationship. Assuming they like each other enough after that, they may continue dating. If they continue dating, they'll probably have sex. After a few weeks or months they may tire of each other, or may decide to move in. I could develop a psychological model, but honestly, a random encounter table is about as reliable.
They key thing is that, given the nature of the interactions, virtually everything about how human relationships develop is private. Information leaks occasionally, either from a public display of affection (PDA), or someone overhearing lovemaking through a wall. But all of that is just the tip of the iceberg. You just hear that two people are in an item and you just sort of assume the rest. I just need to simulate those occasional PDAs or the roommate who doesn't get much sleep.
As far as feuds go, again, most of the interactions are private. Occasionally an argument spills into a public forum. But in the closed confines of a ship, all of the parties involved will be encouraged to settle it themselves, and preferably in a way that everyone can continue working.
No matter what I end up doing, I seem to be returning to AIs doing a lot of improv. I also seem to be on the hook for a lot of chains of events with probabilistic outcomes. Think of them like a flow chart.
I'm imagining that every relations turns into a subroutine that runs once per day.
But before I get too far, Let's start a fresh thought.