I often find myself wishing that the debugging commands (particularly RULES and RELATIONS, maybe also SHOWME) were more versatile.
Some examples:
- Some rulebooks might be called a lot, such as
deciding the concealed possessionsordeciding the scope. If you’re trying to debug something unrelated to concealment or scope, it would be a great help if such rulebooks could just be skipped over – ie, don’t show them even when rule debugging is enabled. - On the other hand, sometimes you might want to debug a specific rulebook, so it would be nice if you could ask to show the rules only for that one rulebook.
- If there are a lot of relations in the game, it would be much easier to be able to select one and list it, rather than arbitrarily listing every relation. The
show relationphrase does help with that a bit, but it’s not a command, so if you run into an issue and want to check the relation, you need to rebuild and replay. - Besides which, listing every relation doesn’t list every relation. What if you want to chart the containment relation? It’s not possible. Even the
show relationphrase doesn’t work, despite it being a well-defined relation that you can easily iterate over. Calculated relations can’t be charted either. (Sometimes it wouldn’t make sense to do so, but if they’re relating objects, there’s no reason why you can’t loop over every object to test what it relates to.)
In the case of RULES, I noticed that you can define a rule based rulebook, which means you could in theory do something like this:
Silly little debug-hiding example
Debug is a rule based rulebook.
Debug the standard looking under rule: rule fails.
Include (-
[ DB_Rule R N blocked;
if (R==0) return;
! Begin modification
FollowRulebook((+ debug rulebook +), R, true);
if(RulebookFailed()) return;
! End modification
print "[Rule ~", (RulePrintingRule) R, "~ ";
#ifdef NUMBERED_RULES; print "(", N, ") "; #endif;
if (blocked == false) {
"applies.]";
}
print "does not apply (wrong ";
if (blocked == 1) print "scene";
if (blocked == 2) print "action";
if (blocked == 3) print "actor";
if (blocked == 4) print "context";
print ").]^";
];
-) replacing "DB_Rule".
If you run the game and try looking under something, it no longer announces that the standard looking under rule was triggered. However, it instead announces that the Debug the standard looking under rule was triggered, so as-is it’s not very useful.
It would be more useful if it could skip an entire rulebook, but that doesn’t work[1] I have a feeling the above approach wouldn’t extend well to rulebooks (you’d probably have to override FollowRulebook, which is a bit of a crazy endeavour, as it’s a huge routine).
It’s possible to debug rules for only one specific rulebook as follows:
Single-rulebook debugging
Rule-debugging is a truth state that varies.
Rule-debugging variable translates into I6 as “debug_rules”.
First deciding the concealed possessions of rule: now rule-debugging is true.
Last deciding the concealed possessions of rule: now rule-debugging is false.
But that’s not accessible as a command, so you’d need to rebuild to use it. Plus, it breaks normal RULES if active.
Does anyone know a way to filter RULES to include or exclude certain ruleb ooks?
For RELATIONS, it’s relatively easy to provide phrases that chart arbitrary relations, even the spatial ones. For example:
Sample relation charter
An object can be marked for listing.
To chart relation (R - an equivalence relation of objects):
say "Tracing [the R] (grouping):[line break]";
let singular elements be a list of objects;
clear marked for listing objects;
repeat with current target running through all objects:
if the current target is not relation-testable, next;
if the current target is marked for listing, next;
let L be a list of objects;
repeat with T running through the list of objects which relate to the current target by R:
now T is marked for listing;
add T to L;
if the number of entries in L is 1:
add the current target to singular elements;
otherwise if L is not empty:
say " [L in brace notation][line break]";
clear marked for listing objects;
if singular elements is not empty:
say " and [singular elements] are singular";
The main difficulty in this case comes in understanding the relation in the parser, so that you can type something like SHOWREL CONTAINMENT to chart the containment relation, or SHOWREL LOCK-FITTING to chart the lock-fitting relation, and so forth. Currently the best I can come up with for this is to manually enumerate every relation in a table and assign it a name for understanding.
There’s also a difficulty in that the kinds a relation relates are part of the type, so, for example, the above sample charter won’t work on relations dealing with kinds of value, which means the number of charting phrases could rapidly get out of hand. Hopefully you can get away with only considering “object” and “value” as the types (using kind variables to accept any kind of value that’s not an object), but I haven’t investigated that; even then, however, you need to consider every combination of “object” and “value” (though, admittedly, there are only 4 possible combinations there). And this also means multiple tables are required if that’s the method to assign a relation a name. (Hopefully just 4 tables is sufficient…)
In putting that together, I also noticed that the empty adjective doesn’t work on the spatial relations, which is kinda weird since it should be pretty easy to check if those relations are empty.
Anyway, I’ve been wondering: is there any better way to understand a relation than building a huge table?
The primary issue with the table is that you need to manually add every new relation, including ones from extensions. I’d like it if there were a way to automatically account for any relation that’s defined. This would probably require having an adjective like iterable or such to determine whether a given relation can be charted (I think only relations of numbers or texts to numbers or texts are truly unchartable, though generalizing it to any relation of a non-enumerable kind to a non-enumerable kind would probably be the way to go).
Then there’s the SHOWME command. I frequently find myself wanting to know whether a particular adjective applies to a particular object, and the SHOWME command should logically be the optimal place to get that information. But SHOWME only shows properties, not arbitrary adjectives. (Many adjectives are property values, so it often works; but many adjectives are calculated definitions instead.)
Unfortunately, I don’t believe adjectives are enumerable, so there might be no way to generically support this… but is there maybe a way to add a specific dynamic adjective to SHOWME’s output?*
Has anyone else tried ways of improving or augmenting the built-in debug commands? Other than the one Zed gave me awhile ago to add timing info to RULES (I’m still using that, though it’s only occasionally helpful), or the collapsing duplicate objects in SHOWME from a recent thread.
To be clear, you can totally define a
Debugrule that takes a rulebook rather than a rule, but the rules in that rulebook are still announced – in other words, it doesn’t do anything. In fact, that rule is never called – I guessDB_Ruleis only called for single rules, not for rulebooks.
Also, as an aside, I couldn’t find a way to define aDebugrule applying to thedebug rulebook. ↩︎