Internal Rules & Rulebooks

Yesterday I added an Internal Rule feature to the engine; it’s an extension of the Rulebook system with some interesting uses.

Rulebook Categories / Rule Groups

The Rulebook is now categorized, so every Rule belongs to a Rule Group. The current groups are:

  • Before (which is the default; rules I’ve previously created all go here)
  • After (new group for rules that run after regular action processing; they can’t interrupt actions)
  • Internal

I can add more Groups later that can be executed at different times, or based on specific types of events. This will be important both for functionality improvements and performance, since I can avoid running every rule on every tick.

Internal Rules

Internal rules are triggered directly by the ECS, and aren’t dependent (entirely) on action execution. They can happen during non-tick executions, and can have a variety of effects. The basic idea is that I can define an internal action called (for example) getLocationName, and then apply rules to that action as if it were a regular verb action. I can also supply a default function if no rules override it.

Internal Action: getLocationName


1
2
3
ECS.addInternalAction('getLocationName', function(data){
return data.location.name;
});

This defines the default action for the getLocationName, which simply returns the name of the location. This is used by the Place component to print the location name during place descriptions.

Ok, so far I’ve just complicated the place descriptions. Next up is the fun part: modifying location names based on rules.

Example

Internal Rule: inside object location name rule


1
2
3
4
5
6
7
8
understand('inside object location name rule')
.internal('getLocationName')
.attribute('actor.parent', 'is', 'holder')
.do(function(data){
data.self.responseText = " (inside "+ data.actor.parent.name +")";
return Rulebook.ACTION_APPEND;
})
.start();

This verbosely-named Rule checks to see if the actor (usually the player) is in/on an object in the location. They could be hiding inside a box, soaking in the hot springs, etc. If so, it appends a parenthetical description to the location name, e.g. “Hot Springs (inside pools)”.

Similar internal rules can be created for object names (appending object state or changing the name entirely), controlling which objects can be seen through a window, etc. Like any other rule, internal rules can be deregistered once they’ve served their purpose.