Sharpee Design Question

During unit testing, something funny shook out. One of the things rarely thought about in IF platforms is the object-oriented concept of encapsulation. The author can set any property on any object at any time and if there are negative consequences, so be it. Some hackery will ensue to make it all work “right”.

I designed Sharpee to adhere to some basic principles, specifically being loosely-coupled. In Sharpee, data is stored in an event source and a spatial index. These are only accessible through world model interfaces, like world.moveEntity(from, to). The moveEntity() function will validate what it’s doing before acting and fail if rules are broken.

So one of the integration tests is a closed medicine cabinet with medicine within. It should be simple enough to create an entity for an openable container that’s closed and another entity for medicine and place it inside the container.

But moveEntity won’t let you put anything in the closed medicine cabinet. The unit test would have to open the cabinet, move the medicine within, and close it, then run the test. This leads to other obvious setup and authorial configurations or world model state changes that should skip the normal rules. We don’t necessarily need the initial state of the game to be recorded in the event source. Or do we?

The proposed solution is to have two interfaces to the shared data storage. One is the current world.{behavior} that follows all rules and the new one would be author.{behavior} that skips the rules and does not fire events.

This seems, on the surface, like it would solve all of the problems, but this is an important decision and I wanted to see if anyone had thoughts.

Maybe the current behavior IS the correct behavior and any interaction with the world should follow all rules of physics at all times. Then we run into using magic, which has its own rules of physics, which would have to be accommodated within the Traits we have now. Or we’d need to make new Traits like MagicContainerTrait that allowed certain entities with the MagicTransportTrait to move into such a container.

I could easily punt this with the author interface. But it’s an interesting problem.

Further investigation opens up an extension that adds magical interfaces that has its own rules to interact with the world.

This seems like a very sensible approach. Sometimes we want to simulate actions as if the player was taking them (the medicine is placed in the cabinet by an NPC, so the sound of it opening/closing is audible), sometimes we want to magic the action without that (the medicine is teleported into the cabinet so it’s there the next time the player looks).

There’s a third case, though. Maybe we want to trigger the normal events, but without adhering to normal rules. The medicine appears inside a locked cabinet but also gets added to the list of contents of the cabinet (via an event). You could fake each of those things with more author actions, but the more things that respond to events, the harder the “faking” becomes.

So maybe that argues for a do x (with/without events) (with/without restrictions) as the right approach?

So in this scenario, we’d have:

worldModel - rules are processed and events are recorded
authorModel - rules are not processed and events are not recorded
authorEventModel - rules are not processed, events are recorded

This will work, but is it the best implementation.

maybe we have a flag on authorModel where every endpoint includes a recordEvents flag:

authorModel.moveEntity(‘Fridge’, ‘Kitchen’, true); // record events
authorModel.moveEntity(‘Fridge’, ‘Kitchen’, false); // don’t record events

I think I prefer this instead of the third authorEventModel, though from a design perspective, it’s a fine line

I do all my world state changes with the parser and not with interfaces. I mainly use the parser for authoring. That’s the real purpose of the parser in the Strand IF system.

OK, so that doesn’t answer your problem, but hopefully it will make my explanation make some sense:

When the player types > put medicine in cabinet world rules are used. When the author types > put medicine in cabinet it doesn’t. It jolly well puts the medicine in the cabinet no questions asked. No messin’

So who is the author? It’s any parser-like command in the game script that’s not typed in by a player.

To summarise:

  1. I use the same command for author and player
  2. player commands are always entered
  3. author commands are always part of the game script.
  4. internally the same actual “put” code is called but (2) is in user-mode and (3) is like “root”.

So there’s a kind of permissions model for the same interface. In my original “Brahman” system, the game itself created the world through its own parser commands then became mortal as the last command. And thereafter was the player. My new system doesn’t exactly work like that but it was an inspiring idea.

2 Likes

This was definitely one of the options discussed.

We’ll see how Sharpee shakes out.

There could be different rulesets. Most often they’d be similar, inheriting from the default ruleset, but then changing some things.

What if we see a ruleset as some kind of oracle that specializes in answering “Is it possible to …” questions, and if we assume that every person asking has a plan for “yes” and a plan for “no”, and we put the different rulesets in an order, in case they conflict and one has to trump.

You could cover the case of magic (which I see not as “acting without rules”, but rather “acting under different rules” - which sparked this whole idea), change the relevant default rule to “can float now”.

About assignment, subjects and objects of an action can act under different rulesets. I’m a magician, I can make myself float vs. I can make everything float that I touch. If one of the things that I touch has a special ruleset where one rule says “This object never looses ground contact”, the order (or weight) of rulesets come into play.

For authoring issues, you could design some rules into the author ruleset like “create objects out of nothing”, “teleport objects everywhere into every container” and alike.

One note, this is entirely hypothetical and theory, and most likely not entirely thought through.