Hadean Lands: HL Debug

Copyright 2014-6 by Andrew Plotkin.

This source code is provided for personal, educational use only. The story and text of Hadean Lands belong to me; you may not use them or create derivative works which contain them. However, you have permission to use the programming techniques of this game in your own works, and you may use the source code excluding game text.



Version 1 of HL Debug by Andrew Plotkin begins here.
 
Use authorial modesty.
 
 
Book - Universal
 
Chapter - Debug Conditional
 
To decide whether release mode: (- (~~DEBUG_BOOL) -).
 
Include (-
#ifdef DEBUG;
Constant DEBUG_BOOL 1;
#ifnot;
Constant DEBUG_BOOL 0;
#endif; ! DEBUG
-) before "Parser.i6t".
 
Chapter - Improved Debug Grammar
 
Include (-
 
[ testcommandthing obj o2;
    switch (scope_stage) {
        1: rtrue; ! allow multiple objects
        2: objectloop (obj)
            if ((obj ofclass Object) && (obj has mark_as_room || obj has mark_as_thing) && (obj provides KD_Count))
                PlaceInScope(obj, true);
        3: print "There seems to be no such object anywhere in the model world.^";
    }
];
 
[ testcommandnoun obj o2;
        switch (scope_stage) {
            1: rtrue; ! allow multiple objects
        2: objectloop (obj)
                if ((obj ofclass Object) && (obj provides KD_Count))
                PlaceInScope(obj, true);
        3: print "There seems to be no such object anywhere in the model world.^";
    }
];
 
{-testing-command:abstract}
    * scope=testcommandthing 'to' scope=testcommandthing -> XAbstract;
{-testing-command:actions}
    *                                           -> ActionsOn
    * 'on'                                      -> ActionsOn
    * 'off'                                     -> ActionsOff;
{-testing-command:gonear}
    * scope=testcommandthing                     -> Gonear;
{-testing-command:purloin}
    * scope=testcommandthing                     -> XPurloin;
{-testing-command:random}
    *                                           -> Predictable;
{-testing-command:relations}
    *                                           -> ShowRelations;
{-testing-command:rules}
    *                                           -> RulesOn
    * 'all'                                     -> RulesAll
    * 'on'                                      -> RulesOn
    * 'off'                                     -> RulesOff;
{-testing-command:scenes}
    *                                           -> ScenesOn
    * 'on'                                      -> ScenesOn
    * 'off'                                     -> ScenesOff;
{-testing-command:scope}
    *                                           -> Scope
    * scope=testcommandnoun                     -> Scope;
{-testing-command:showheap}
    *                                           -> ShowHeap;
{-testing-command:showme}
    *                                           -> ShowMe
    * scope=testcommandnoun                     -> ShowMe;
{-testing-command:showverb}
    * special                                   -> Showverb;
{-testing-command:test}
    *                                           -> TestScript
    * special                                   -> TestScript;
{-testing-command:trace}
    *                                           -> TraceOn
    * number                                    -> TraceLevel
    * 'on'                                      -> TraceOn
    * 'off'                                     -> TraceOff
    * 'goal'                                    -> TraceGoals
    * 'goals'                                   -> TraceGoals
    * 'tutor'                                   -> TraceTutorial
    * 'tutorial'                                -> TraceTutorial;
{-testing-command:tree}
    *                                           -> XTree
    * scope=testcommandnoun                     -> XTree;
 
! Display goal performance requirements as they are encountered.
Global goal_tracing_flag = 0;
[ TraceGoalsSub;
    goal_tracing_flag = ~~goal_tracing_flag;
    print "(DEBUG) Goal-tracing ";
    if (goal_tracing_flag) print "on";
    else print "off";
    print ".^^";
];
 
! Mark action goals as ever-done as soon as they're known.
Global goal_practice_flag = 0;
[ PracticeGoalsSet val;
    goal_practice_flag = val;
];
 
! Display tutorial nodes as they're triggered.
Global tutorial_tracing_flag = 0;
[ TraceTutorialSub;
    tutorial_tracing_flag = ~~tutorial_tracing_flag;
    print "(DEBUG) Tutorial-tracing ";
    if (tutorial_tracing_flag) print "on";
    else print "off";
    print ".^^";
];
 
-) instead of "Grammar" in "Tests.i6t".
 
[This will appear after Tests.i6t, but outside the #ifdef DEBUG.]
Include (-
! These constants were defined for the DEBUG case, but not the release case.
 
#ifndef goal_tracing_flag;
Constant goal_tracing_flag 0;
#endif; ! goal_tracing_flag
 
#ifndef goal_practice_flag;
Constant goal_practice_flag 0;
#endif; ! goal_practice_flag
 
#ifndef tutorial_tracing_flag;
Constant tutorial_tracing_flag 0;
#endif; ! tutorial_tracing_flag
-).
 
Chapter - Release-Mode Debug Dumps
 
Understand "dbdump goals" as a mistake ("[dbdump-goals]").
 
To say dbdump-goals:
    say "Goal state (in addition to 'recall rituals'):[para]";
    say list of ever-done not recallable action-goals;
 
Book - Conditional - not for release
 
Zapping is an action applying to one visible thing.
Omni-zapping is an action out of world applying to nothing.
Omni-test-zapping is an action out of world applying to nothing.
Practice-zapping is an action out of world applying to nothing.
See-zapping is an action out of world applying to one visible thing.
Unsee-zapping is an action out of world applying to one visible thing.
Recite-zapping is an action out of world applying to one visible thing.
Symbol-zapping is an action out of world applying to one symbol-type and one visible thing.
Persona-zapping is an action out of world applying to one persona and one visible thing.
Locktest-zapping is an action out of world applying to two things.
Reset-zapping is an action applying to nothing.
Generic-takeable-performing is an action applying to one visible thing.
Env-setup-performing is an action applying to one ritual-env.
Offstage-zapping is an action out of world applying to one visible thing.
 
Understand "zap [something]" as zapping.
Understand "zap [any alien-glyph]" as zapping.
Understand "zap-goal [any goal]" as zapping.
Understand "zap-omni" as omni-zapping.
Understand "zap-omni test" as omni-test-zapping.
Understand "zap-practice" as practice-zapping.
Understand "zap-see [any thing]" as see-zapping.
Understand "zap-see [any room]" as see-zapping.
Understand "zap-see [any formula]" as see-zapping.
Understand "zap-see [any action-goal]" as see-zapping.
Understand "zap-unsee [any action-goal]" as unsee-zapping.
Understand "zap-symbol [symbol-type] on [something]" as symbol-zapping.
Understand "zap-persona [persona] on [something]" as persona-zapping.
Understand "zap reset", "zap-reset" as reset-zapping.
Understand "zap-offstage [any thing]" as offstage-zapping.
Understand "zap-recite [any thing]" as recite-zapping.
Understand "zap-recite [any room]" as recite-zapping.
Understand "zone-test" as a mistake ("[debug-display-zones]").
Understand "proper-test" as a mistake ("[debug-display-proper-nouns]").
Understand "lock-test [something] with/by [something]" as locktest-zapping.
Understand "lock-test [something] in/on [something]" as locktest-zapping (with nouns reversed).
Understand "env-test" as a mistake ("[debug-current-environment]").
Understand "bestenv-test" as a mistake ("[debug-best-environment-objects]").
Understand "best-env-test" as a mistake ("[debug-best-environment-objects]").
Understand "descrip-test" as a mistake ("[debug-descriptor-types]").
Understand "grouping-test" as a mistake ("[debug-list-grouping]").
Understand "reqenv-test [ritual-env]" as env-setup-performing.
Understand "require-test env [ritual-env]" as env-setup-performing.
Understand "require-test [any thing]" as generic-takeable-performing.
 
Include (-
! Declare some verbs to be meta at the dictionary level.
Dictionary 'zap' 2;
Dictionary 'zap-see' 2;
Dictionary 'zap-unsee' 2;
Dictionary 'zap-omni' 2;
Dictionary 'zap-practice' 2;
Dictionary 'zap-offstage' 2;
-).
 
Include (-
! Some of my debug actions are not meta. This checks for all the possibilities.
[ ActionIsDebug act;
    if (meta)
        rtrue;
    if (act == (+ reset-zapping action +) )
        rtrue;
    rfalse;
];
-).
 
Carry out omni-zapping:
    now every room is visited;
    now the Abstraction Layer is not visited;
    now every recallable thing is ever-seen;
    now every action-goal is ever-done;
    repeat with G running through recallable ever-done action-goals:
        mark G as done; [ensure it's in known-rituals]
    repeat with B running through tidbits:
        mark B as known;
    repeat with F running through formulas:
        if F is not no-word:
            mark F as known;
    repeat with G running through earsolvent-synthesis-action-goal:
        let T be the solvent form of the mineral-used of G;
        now the creation-action of T is G;
    omni-zap everything else;
    say "Now you've been everywhere, seen everything, and done it all."
 
Carry out omni-test-zapping:
    now every test-action-goal is ever-done;
    repeat with G running through recallable ever-done test-action-goals:
        mark G as done; [ensure it's in known-rituals]
    say "Test goals are now ever-done."
 
Carry out practice-zapping:
    set goal-practiced to true;
    let N be the number of ever-done recallable action-goals;
    now every known recallable action-goals is ever-done;
    let N2 be the number of ever-done recallable action-goals;
    say "(DEBUG) Practice flag set";
    if N2 is not N:
        say "; marked [N2 minus N] known rituals as ever-done";
    say "."
 
To set goal-practiced to (val - truth state): (- PracticeGoalsSet({val}); -).
 
Carry out generic-takeable-performing:
    if the noun is not takeable:
        instead say "The [objname noun] is not a takeable.";
    mark test-generic-takeable-goal as done;
    now the proxy-thing of the test-generic-takeable-goal is the noun;
    try performing the test-generic-takeable-goal;
    now the proxy-thing of the test-generic-takeable-goal is no-thing;
    stop the action.
 
Carry out env-setup-performing:
    mark test-env-setup-goal as done;
    now the proxy-env of the test-env-setup-goal is the ritual-env understood;
    try performing the test-env-setup-goal;
    now the proxy-env of the test-env-setup-goal is no-env;
    stop the action.
 
Carry out see-zapping:
    if the noun is a formula:
        mark the noun as known;
        say "[The noun] is now known.";
    else if the noun is a room:
        if the noun is not recallable:
            instead say "[The noun] (room) is not recallable, sorry.";
        if the noun is visited:
            now the noun is not visited;
            now the noun is not visited-this-cycle;
            say "[The noun] has now never been visited (this cycle, or ever).";
        else:
            now the noun is visited;
            say "[The noun] has now been visited.";
    else if the noun is a thing:
        if the noun is not recallable:
            instead say "[The noun] [is-are noun] not recallable, sorry.";
        if the noun is ever-seen:
            now the noun is not ever-seen;
            say "[The noun] has now never been seen.";
        else:
            now the noun is ever-seen;
            say "[The noun] has now been seen.";
    else if the noun is an action-goal:
        if the noun is recallable and the noun is not known:
            mark the noun as known;
            say "[The noun] is now known to you.";
        else:
            if the noun is ever-done:
                say "[The noun] has already been done.";
            else:
                now the noun is ever-done;
                say "[The noun] has now been done.";
            [special cases...]
            if the noun is aura-imi-quartz-inscription:
                mark aura-imi-either-inscription as done;
                now the proxy-goal of aura-imi-either-inscription is the noun;
                say "(Now g-im-either proxy is [the proxy-goal of aura-imi-either-inscription].)";
            if the noun is aura-imi-jade-inscription:
                mark aura-imi-either-inscription as done;
                now the proxy-goal of aura-imi-either-inscription is the noun;
                say "(Now g-im-either proxy is [the proxy-goal of aura-imi-either-inscription].)";
            if the noun is aura-imi-either-inscription:
                if the proxy-goal of aura-imi-either-inscription is impossible-goal:
                    now the proxy-goal of aura-imi-either-inscription is aura-imi-jade-inscription;
                else if the proxy-goal of aura-imi-either-inscription is aura-imi-jade-inscription:
                    now the proxy-goal of aura-imi-either-inscription is aura-imi-quartz-inscription;
                else:
                    now the proxy-goal of aura-imi-either-inscription is impossible-goal;
                say "(Now g-im-either proxy is [the proxy-goal of aura-imi-either-inscription].)";
            if the noun is lead-light-cg-inscription:
                mark lead-light-either-inscription as done;
                now the proxy-goal of lead-light-either-inscription is the noun;
                say "(Now g-ll-either proxy is [the proxy-goal of lead-light-either-inscription].)";
            if the noun is lead-light-at-inscription:
                mark lead-light-either-inscription as done;
                now the proxy-goal of lead-light-either-inscription is the noun;
                say "(Now g-ll-either proxy is [the proxy-goal of lead-light-either-inscription].)";
            if the noun is lead-light-either-inscription:
                if the proxy-goal of lead-light-either-inscription is impossible-goal:
                    now the proxy-goal of lead-light-either-inscription is lead-light-cg-inscription;
                else if the proxy-goal of lead-light-either-inscription is lead-light-cg-inscription:
                    now the proxy-goal of lead-light-either-inscription is lead-light-at-inscription;
                else:
                    now the proxy-goal of lead-light-either-inscription is impossible-goal;
                say "(Now g-ll-either proxy is [the proxy-goal of lead-light-either-inscription].)";
            special-case zap-see the noun;
    else:
        say "Don't know how to see [the noun]."
 
Carry out unsee-zapping:
    if the noun is an action-goal:
        now the noun is not ever-done;
        say "[The noun] has now never been done.";
    else:
        say "Don't know how to unsee [the noun]."
 
Carry out symbol-zapping:
    let T be the second noun;
    if T is not inscribable:
        instead say "[The T] is not inscribable.";
    if the symbol-type understood is no-symbol:
        uninscribe T;
        instead say "Uninscribed [the T].";
    else:
        inscribe T with the symbol-type understood;
        instead say "Inscribed [the T] with [symbol-type of T]."
 
Carry out persona-zapping:
    let T be the second noun;
    if T does not provide the property persona:
        instead say "[The T] is not persona-able.";
    now the persona of T is the persona understood;
    instead say "Inscribed [the T] with [persona of T]."
 
Carry out reset-zapping:
    say "(DEBUG) Reset the world! (Counter was [reset-counter][if forced-reset-counter > 0], [forced-reset-counter] involuntary[end if].)";
    invoke reset.
 
Carry out offstage-zapping:
    if the noun is off-stage:
        say "[The noun] [is-are noun] already offstage.";
    else:
        now the noun is handled;
        now the noun retired to no-fate;
        now the noun is off-stage;
        say "[The noun] [is-are noun] offstage."
 
Carry out recite-zapping a thing:
    say "'[Noun]': ";
    say "[The noun] [is-are noun] somewhere; you love [it-them noun]";
    say ". You don't know where to get ";
    if noun is plural-named or noun is mass-named:
        say "more";
    else:
        say "another one";
    say "."
 
Carry out recite-zapping a room:
    say "'[Noun]': Stuff is [refer-preposition of noun] [refer-name of noun]."
 
To say debug-display-proper-nouns:
    say "Things which are proper-named:.";
    repeat with T running through proper-named things:
        say "... [T].";
    say "Rooms which are proper-named:.";
    repeat with R running through proper-named rooms:
        say "... [R].";
    say "Formulas which are proper-named:.";
    repeat with F running through proper-named formulas:
        say "... [F].";
    say "Rituals which are proper-named:.";
    repeat with G running through proper-named recallable action-goals:
        say "... [G].";
    say "Tidbits which are proper-named:.";
    repeat with Z running through proper-named tidbits:
        say "... [Z].";
 
To say debug-display-zones:
    say "Canon-rooms:[br]";
    repeat with Z running through room-goals:
        if Z is no-zone:
            continue the loop;
        let R be the canon-room of Z;
        say "  [Z] -- [R].";
        if R is nothing:
            say "    (BUG) nothing!";
        if Z is not the zone of R:
            say "    (BUG) mismatch [zone of R]!";
    say "Zoneless rooms:";
    repeat with R running through zoneless rooms:
        say "; [R]";
        if the near-zone-room of R is not nothing:
            say " (near [near-zone-room of R])";
    say "."
 
To set env-influence-tracing to (val - truth state): (- envinfluence_trace = {val}; -).
 
To say debug-current-environment:
    if a ritual-bound (called B) is in the location:
        set env-influence-tracing to true;
        let E be the ritual environment of location with B;
        set env-influence-tracing to false;
        say "Current environment: [E] ([color of E], [a E] nature)";
        say " (temp object: [temp best object for E]).";
    else:
        say "No bound in current location!"
 
To say debug-best-environment-objects:
    say "List of best ritual-env objects...";
    repeat with E running through ritual-envs:
        if E is terminator-env:
            break;
        if the best object for E is not nothing:
            say "[E]: [best object for E].";
    if best-amalgam-wire is not no-thing:
        say "quicksilver footnote: best wire is [best-amalgam-wire].";
 
To say debug-descriptor-types:
    repeat with D running through descriptor-types:
        if D is not no-descriptor:
            say "- [D]: [list of descriptor-compatible things that descriptor-match D].";
    say "- (metallic): [list of metallic things].";
    say "- (mineralish): [list of mineralish things].";
    say "- (glassy): [list of glassy things].";
    say "- (readable): [list of readable things].";
 
To decide what number is the list_together of (T - thing): (- ({T}.list_together) -).
 
To say debug-list-grouping:
    repeat with T running through takeable-things:
        let N be the list_together of T;
        if N is not zero:
            say "- [T]: [N].";
 
Carry out locktest-zapping:
    let flag be whether or not lock the noun really matches key the second noun;
    say "Is [the noun] unlocked by [the second noun]? [flag].";
 
 
Section - Zapping Rules
 
Carry out zapping the lead-rod:
    if the symbol-type of lead-rod is no-symbol:
        now the symbol-type of lead-rod is ponderosity-symbol;
    else if the symbol-type of lead-rod is ponderosity-symbol:
        now the symbol-type of lead-rod is gossamerity-symbol;
    else:
        now the symbol-type of lead-rod is no-symbol;
    say "(DEBUG) The lead rod's symbol is now [the symbol-type of lead-rod]."
 
To zap-toggle-fire the noun:
    if the noun is not alight:
        now the noun is alight;
    else:
        now the noun is not alight;
        if the noun provides max-burn-life:
            now the burn-life of the noun is the max-burn-life of the noun;
    update fire consumption;
    say "(DEBUG) Behold the [noun], which [if noun is alight]is now[else]is now not[end if] alight."
 
Carry out zapping the phlo-gold:
    zap-toggle-fire the noun.
 
Carry out zapping the phlo-electrum:
    zap-toggle-fire the noun.
 
Carry out zapping a wood-splint:
    zap-toggle-fire the noun.
 
Carry out zapping an alien-glyph:
    if the noun is not consumed:
        now the noun is consumed;
    else:
        now the noun is not consumed;
    say "(DEBUG) Okay, [the noun] is now [if the noun is not consumed]not consumed[else]consumed[end if]."
 
Section - Extended Purloin
 
Include (-
[ XPurloinSub;
    if (noun.component_parent) {
        print "[First dis-parting from play...]^";
        RemoveFromPlay(noun);
    }
    if (XTestMove(noun, player)) return;
    move noun to player; give noun moved ~concealed;
    give noun (+ ever-seen +);
    say__p = 1;
    "[Purloined.]";
];
-) instead of "Purloin Command" in "Tests.i6t".
 
 
Section - Debug Recallable Goals
 
A test-action-goal is a kind of action-goal.
A test-action-goal is always recallable.
The description of a test-action-goal is usually "(DEBUG) Test goal: [printed name of the item described]."
The short-description of a test-action-goal is usually "perform [printed name of the item described]".
 
The test-env-setup-goal is a test-action-goal. The printed name is "test env-setup".
["reqenv-test ..."]
The test-env-setup-goal has a ritual-env called the proxy-env. The proxy-env of the test-env-setup-goal is no-env.
The short-description of test-env-setup-goal is "perform test env-setup: [proxy-env]".
 
Goal prereqs rule for test-env-setup-goal:
    let E be the proxy-env of test-env-setup-goal;
    attain-or-fail environment E noting drop-envtool;
    auto-drop drop-envtool;
    say "Success.";
    rule succeeds.
 
The test-generic-takeable-goal is a test-action-goal. The printed name is "test generic-takeable".
The test-generic-takeable-goal has a thing called the proxy-thing. The proxy-thing of the test-generic-takeable-goal is no-thing.
The short-description of test-generic-takeable-goal is "perform test generic-takeable: [objname proxy-thing]".
 
Goal prereqs rule for test-generic-takeable-goal:
    let T be the proxy-thing of test-generic-takeable-goal;
    if T is nothing or T is no-thing:
        say "No proxy-thing. (Try 'require-test'.)";
        rule fails;
    if T is not takeable:
        say "Proxy-thing [objname T] is not takeable.";
        rule fails;
    require-or-fail T;
    say "Success.";
    rule succeeds.
 
The test-ignite is a test-action-goal. The printed name is "test ignite".
Understand "test ignite" as test-ignite.
 
Goal prereqs rule for test-ignite:
    require-or-fail the ignite-goal;
    let drop-lighter be the auto-drop-lighter of ignite-goal;
    auto-drop the torch-lighter if drop-lighter;
    say "Success.";
    rule succeeds.
 
The test-el-air is a test-action-goal. The printed name is "test el-air".
Understand "test el-air" as test-el-air.
 
Goal prereqs rule for test-el-air:
    require-or-fail el-air-goal;
    resolve the el-air-goal;
    say "Success. (Air used up.)";
    rule succeeds.
 
The test-ll-either is a test-action-goal. The printed name is "test ll-either".
Understand "test ll-either" as test-ll-either.
 
Goal prereqs rule for test-ll-either:
    require-or-fail lead-light-either-inscription;
    say "Success.";
    rule succeeds.
 
The test-im-either is a test-action-goal. The printed name is "test im-either".
Understand "test im-either" as test-im-either.
 
Goal prereqs rule for test-im-either:
    require-or-fail aura-imi-either-inscription;
    say "Success.";
    rule succeeds.
 
 
Section - Debug-Mode Rules
 
Last reset rule (this is the reset sanity-checking rule):
    sanity-check the empty buckets.
 
 
HL Debug ends here.