Sharpee Milestone - Cloak of Darkness

Over the last couple of nights my IF authoring platform hit a sizable milestone. Sharpee now can compile and run Cloak of Darkness. I don’t have a template that allows a user to play the story in a traditional IF client, but the test runs the commands and emits the correct events. Sharpee is built on the concept of an event source, which is like a log of “interesting things”.

This is the result with tracing for parsing and validation turned on. Note the Text Service used for this is specifically “dumping” everything in the event source. Another Text Service will eventually handle events and display a true IF client (command line, web, mobile app, or native OS client).

I’ve started adopting an old story of mine to Sharpee to solidify its capabilities. One thing that has already exposed itself is the location of certain interfaces and then naming conventions for Typescript interfaces. This was discovered when creating a custom extension for the story I’m creating. I’m currently in a wholesale, but shallow, refactor to alleviate this interface issue. Building extensions has to be as non-invasive as possible.

More can be read at: https://sharpee.plover.net/ and see the code at: GitHub - ChicagoDave/sharpee: Parser-Based Interactive Fiction Platform developed in Typescript · GitHub while the refactor work is on a separate branch.

=== Cloak of Darkness (Static Platform) ===
A Sharpee IF demonstration


[GAME EVENT]: game.story_loading - {"story":{"id":"cloak-of-darkness"}}
Moving player a01 to foyer r01

[GAME EVENT]: game.story_loaded - {"story":{"id":"cloak-of-darkness","title":"Cloak of Darkness","author":"Roger Firth (Sharpee implementation)","version":"1.0.0"},"gameState":"ready"}

[GAME EVENT]: game.starting - {"story":{"id":"cloak-of-darkness","title":"Cloak of Darkness","author":"Roger Firth (Sharpee implementation)","version":"1.0.0"},"gameState":"ready"}

[GAME EVENT]: game.started - {"story":{"id":"cloak-of-darkness","title":"Cloak of Darkness","author":"Roger Firth (Sharpee implementation)","version":"1.0.0"},"gameState":"running","session":{"startTime":1755238824882,"turns":0,"moves":0}}
Engine started successfully

> trace on

=== Turn 1 ===

Game Events:
  [TRACE.CHANGED] {"target":"all","enabled":true}

Location: Foyer of the Opera House [r01]

> look

=== Turn 1 ===

Game Events:
  [SYSTEM.PARSER] {"input":"look","parsed":{"action":"if.action.looking","pattern":"VERB_ONLY","confidence":1,"tokens":1}}
  [SYSTEM.PARSER.TOKENS] {"count":1,"tokens":[{"word":"look","normalized":"look","partOfSpeech":["VERB"],"position":0,"length":4,"candidates":[{"id":"if.action.looking","type":"verb","confidence":1}]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"look","head":"look"}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.looking","hasDirectObject":false,"hasIndirectObject":false}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.looking"}
  [IF.EVENT.LOOKED] {"actorId":"a01","locationId":"r01","locationName":"Foyer of the Opera House","isDark":false,"timestamp":1755238824892}
  [IF.EVENT.ROOM_DESCRIPTION] {"roomId":"r01","includeContents":true,"verbose":true,"timestamp":1755238824892}
  [IF.EVENT.LIST_CONTENTS] {"items":["i01"],"itemNames":["velvet cloak"],"npcs":[],"containers":[],"supporters":[],"other":["i01"],"context":"room","timestamp":1755238824892}
  [ACTION.SUCCESS] {"actionId":"if.action.looking","messageId":"contents_list","params":{"items":"velvet cloak","count":1}}

Location: Foyer of the Opera House [r01]

[SYSTEM EVENTS]:
  system.parser: {"input":"look","parsed":{"action":"if.action.looking","pattern":"VERB_ONLY","confidence":1,"tokens":1}}
  system.parser.tokens: {"count":1,"tokens":[{"word":"look","normalized":"look","partOfSpeech":["VERB"],"position":0,"length":4,"candidates":[{"id":"if.action.looking","type":"verb","confidence":1}]}]}
  system.parser.structure: {"verb":{"text":"look","head":"look"}}
  system.validation.start: {"action":"if.action.looking","hasDirectObject":false,"hasIndirectObject":false}
  system.validation.success: {"actionId":"if.action.looking"}

> examine cloak

=== Turn 2 ===

Game Events:
  [SYSTEM.PARSER] {"input":"examine cloak","parsed":{"action":"if.action.examining","pattern":"VERB_NOUN","confidence":1,"tokens":2}}
  [SYSTEM.PARSER.TOKENS] {"count":2,"tokens":[{"word":"examine","normalized":"examine","partOfSpeech":["VERB"],"position":0,"length":7,"candidates":[{"id":"if.action.examining","type":"verb","confidence":1}]},{"word":"cloak","normalized":"cloak","partOfSpeech":["UNKNOWN"],"position":8,"length":5,"candidates":[]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"examine","head":"examine"},"directObject":{"text":"cloak","head":"cloak","modifiers":[],"articles":[],"determiners":[]}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.examining","hasDirectObject":true,"hasIndirectObject":false}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.examining","directObject":"i01"}
  [SYSTEM.VALIDATION.SCOPE] {"directObject":{"entityId":"i01","entityName":"velvet cloak","scopeLevel":"carried","perceivedBy":["sight","hearing","touch"]}}
  [SYSTEM.VALIDATION.RESOLUTION] {"directObject":{"parsed":"cloak","resolved":"i01","name":"velvet cloak","location":"a01"}}
  [IF.EVENT.EXAMINED] {"targetId":"i01","targetName":"velvet cloak","hasDescription":true,"hasBrief":false,"isWearable":true,"isWorn":false}
  [ACTION.SUCCESS] {"actionId":"if.action.examining","messageId":"examined_wearable","params":{"description":"A handsome cloak of velvet trimmed with satin, and slightly splattered with raindrops. Its blackness is so deep that it almost seems to suck light from the room.","isWorn":false}}

Location: Foyer of the Opera House [r01]

[SYSTEM EVENTS]:
  system.parser: {"input":"examine cloak","parsed":{"action":"if.action.examining","pattern":"VERB_NOUN","confidence":1,"tokens":2}}
  system.parser.tokens: {"count":2,"tokens":[{"word":"examine","normalized":"examine","partOfSpeech":["VERB"],"position":0,"length":7,"candidates":[{"id":"if.action.examining","type":"verb","confidence":1}]},{"word":"cloak","normalized":"cloak","partOfSpeech":["UNKNOWN"],"position":8,"length":5,"candidates":[]}]}
  system.parser.structure: {"verb":{"text":"examine","head":"examine"},"directObject":{"text":"cloak","head":"cloak","modifiers":[],"articles":[],"determiners":[]}}
  system.validation.start: {"action":"if.action.examining","hasDirectObject":true,"hasIndirectObject":false}
  system.validation.success: {"actionId":"if.action.examining","directObject":"i01"}
  system.validation.scope: {"directObject":{"entityId":"i01","entityName":"velvet cloak","scopeLevel":"carried","perceivedBy":["sight","hearing","touch"]}}
  system.validation.resolution: {"directObject":{"parsed":"cloak","resolved":"i01","name":"velvet cloak","location":"a01"}}

> west

=== Turn 3 ===

Game Events:
  [SYSTEM.PARSER] {"input":"west","parsed":{"action":"if.action.going","pattern":"DIRECTION_ONLY","confidence":1,"tokens":1}}
  [SYSTEM.PARSER.TOKENS] {"count":1,"tokens":[{"word":"west","normalized":"west","partOfSpeech":["UNKNOWN"],"position":0,"length":4,"candidates":[{"id":"west","type":"direction","confidence":1}]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"","head":""}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.going","hasDirectObject":false,"hasIndirectObject":false}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.going"}
  [IF.EVENT.ACTOR_EXITED] {"actorId":"a01","direction":"west","toRoom":"r02"}
  [IF.EVENT.ACTOR_MOVED] {"direction":"west","fromRoom":"r01","toRoom":"r02","oppositeDirection":"east","firstVisit":true}
  [IF.EVENT.ACTOR_ENTERED] {"actorId":"a01","direction":"east","fromRoom":"r01"}
  [ACTION.SUCCESS] {"actionId":"if.action.going","messageId":"first_visit","params":{"direction":"west","destination":"Cloakroom"}}

Location: Cloakroom [r02]

[SYSTEM EVENTS]:
  system.parser: {"input":"west","parsed":{"action":"if.action.going","pattern":"DIRECTION_ONLY","confidence":1,"tokens":1}}
  system.parser.tokens: {"count":1,"tokens":[{"word":"west","normalized":"west","partOfSpeech":["UNKNOWN"],"position":0,"length":4,"candidates":[{"id":"west","type":"direction","confidence":1}]}]}
  system.parser.structure: {"verb":{"text":"","head":""}}
  system.validation.start: {"action":"if.action.going","hasDirectObject":false,"hasIndirectObject":false}
  system.validation.success: {"actionId":"if.action.going"}

> look

=== Turn 4 ===

Game Events:
  [SYSTEM.PARSER] {"input":"look","parsed":{"action":"if.action.looking","pattern":"VERB_ONLY","confidence":1,"tokens":1}}
  [SYSTEM.PARSER.TOKENS] {"count":1,"tokens":[{"word":"look","normalized":"look","partOfSpeech":["VERB"],"position":0,"length":4,"candidates":[{"id":"if.action.looking","type":"verb","confidence":1}]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"look","head":"look"}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.looking","hasDirectObject":false,"hasIndirectObject":false}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.looking"}
  [IF.EVENT.LOOKED] {"actorId":"a01","locationId":"r02","locationName":"Cloakroom","isDark":false,"timestamp":1755238824909}
  [IF.EVENT.ROOM_DESCRIPTION] {"roomId":"r02","includeContents":true,"verbose":true,"timestamp":1755238824909}
  [IF.EVENT.LIST_CONTENTS] {"items":["i01","s01"],"itemNames":["velvet cloak","brass hook"],"npcs":[],"containers":[],"supporters":["s01"],"other":["i01"],"context":"room","timestamp":1755238824909}
  [ACTION.SUCCESS] {"actionId":"if.action.looking","messageId":"contents_list","params":{"items":"velvet cloak, brass hook","count":2}}

Location: Cloakroom [r02]

[SYSTEM EVENTS]:
  system.parser: {"input":"look","parsed":{"action":"if.action.looking","pattern":"VERB_ONLY","confidence":1,"tokens":1}}
  system.parser.tokens: {"count":1,"tokens":[{"word":"look","normalized":"look","partOfSpeech":["VERB"],"position":0,"length":4,"candidates":[{"id":"if.action.looking","type":"verb","confidence":1}]}]}
  system.parser.structure: {"verb":{"text":"look","head":"look"}}
  system.validation.start: {"action":"if.action.looking","hasDirectObject":false,"hasIndirectObject":false}
  system.validation.success: {"actionId":"if.action.looking"}

> hang cloak on hook
Cloak hung on hook - bar is now lit

=== Turn 5 ===

Game Events:
  [SYSTEM.PARSER] {"input":"hang cloak on hook","parsed":{"action":"if.action.putting","pattern":"VERB_NOUN_PREP_NOUN","confidence":1,"tokens":4}}
  [SYSTEM.PARSER.TOKENS] {"count":4,"tokens":[{"word":"hang","normalized":"hang","partOfSpeech":["VERB"],"position":0,"length":4,"candidates":[{"id":"HANG","type":"verb","confidence":80}]},{"word":"cloak","normalized":"cloak","partOfSpeech":["UNKNOWN"],"position":5,"length":5,"candidates":[]},{"word":"on","normalized":"on","partOfSpeech":["PREPOSITION"],"position":11,"length":2,"candidates":[{"id":"ON","type":"preposition","confidence":1}]},{"word":"hook","normalized":"hook","partOfSpeech":["VERB"],"position":14,"length":4,"candidates":[{"id":"HANG","type":"verb","confidence":80}]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"hang","head":"hang"},"directObject":{"text":"cloak","head":"cloak","modifiers":[],"articles":[],"determiners":[]},"preposition":"on","indirectObject":{"text":"hook","head":"hook","modifiers":[],"articles":[],"determiners":[]}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.putting","hasDirectObject":true,"hasIndirectObject":true,"preposition":"on"}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.putting","directObject":"i01","indirectObject":"s01"}
  [SYSTEM.VALIDATION.SCOPE] {"directObject":{"entityId":"i01","entityName":"velvet cloak","scopeLevel":"carried","perceivedBy":["sight","hearing","touch"]},"indirectObject":{"entityId":"s01","entityName":"brass hook","scopeLevel":"reachable","perceivedBy":["sight","hearing","touch"]}}
  [SYSTEM.VALIDATION.RESOLUTION] {"directObject":{"parsed":"cloak","resolved":"i01","name":"velvet cloak","location":"a01"},"indirectObject":{"parsed":"hook","resolved":"s01","name":"brass hook","location":"r02"}}
  [IF.EVENT.PUT_ON] {"itemId":"i01","targetId":"s01","preposition":"on"}
  [ACTION.SUCCESS] {"actionId":"if.action.putting","messageId":"put_on","params":{"item":"velvet cloak","surface":"brass hook"}}

Location: Cloakroom [r02]

[SYSTEM EVENTS]:
  system.parser: {"input":"hang cloak on hook","parsed":{"action":"if.action.putting","pattern":"VERB_NOUN_PREP_NOUN","confidence":1,"tokens":4}}
  system.parser.tokens: {"count":4,"tokens":[{"word":"hang","normalized":"hang","partOfSpeech":["VERB"],"position":0,"length":4,"candidates":[{"id":"HANG","type":"verb","confidence":80}]},{"word":"cloak","normalized":"cloak","partOfSpeech":["UNKNOWN"],"position":5,"length":5,"candidates":[]},{"word":"on","normalized":"on","partOfSpeech":["PREPOSITION"],"position":11,"length":2,"candidates":[{"id":"ON","type":"preposition","confidence":1}]},{"word":"hook","normalized":"hook","partOfSpeech":["VERB"],"position":14,"length":4,"candidates":[{"id":"HANG","type":"verb","confidence":80}]}]}
  system.parser.structure: {"verb":{"text":"hang","head":"hang"},"directObject":{"text":"cloak","head":"cloak","modifiers":[],"articles":[],"determiners":[]},"preposition":"on","indirectObject":{"text":"hook","head":"hook","modifiers":[],"articles":[],"determiners":[]}}
  system.validation.start: {"action":"if.action.putting","hasDirectObject":true,"hasIndirectObject":true,"preposition":"on"}
  system.validation.success: {"actionId":"if.action.putting","directObject":"i01","indirectObject":"s01"}
  system.validation.scope: {"directObject":{"entityId":"i01","entityName":"velvet cloak","scopeLevel":"carried","perceivedBy":["sight","hearing","touch"]},"indirectObject":{"entityId":"s01","entityName":"brass hook","scopeLevel":"reachable","perceivedBy":["sight","hearing","touch"]}}
  system.validation.resolution: {"directObject":{"parsed":"cloak","resolved":"i01","name":"velvet cloak","location":"a01"},"indirectObject":{"parsed":"hook","resolved":"s01","name":"brass hook","location":"r02"}}

> east

=== Turn 6 ===

Game Events:
  [SYSTEM.PARSER] {"input":"east","parsed":{"action":"if.action.going","pattern":"DIRECTION_ONLY","confidence":1,"tokens":1}}
  [SYSTEM.PARSER.TOKENS] {"count":1,"tokens":[{"word":"east","normalized":"east","partOfSpeech":["UNKNOWN"],"position":0,"length":4,"candidates":[{"id":"east","type":"direction","confidence":1}]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"","head":""}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.going","hasDirectObject":false,"hasIndirectObject":false}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.going"}
  [IF.EVENT.ACTOR_EXITED] {"actorId":"a01","direction":"east","toRoom":"r01"}
  [IF.EVENT.ACTOR_MOVED] {"direction":"east","fromRoom":"r02","toRoom":"r01","oppositeDirection":"west","firstVisit":true}
  [IF.EVENT.ACTOR_ENTERED] {"actorId":"a01","direction":"west","fromRoom":"r02"}
  [ACTION.SUCCESS] {"actionId":"if.action.going","messageId":"first_visit","params":{"direction":"east","destination":"Foyer of the Opera House"}}

Location: Foyer of the Opera House [r01]

[SYSTEM EVENTS]:
  system.parser: {"input":"east","parsed":{"action":"if.action.going","pattern":"DIRECTION_ONLY","confidence":1,"tokens":1}}
  system.parser.tokens: {"count":1,"tokens":[{"word":"east","normalized":"east","partOfSpeech":["UNKNOWN"],"position":0,"length":4,"candidates":[{"id":"east","type":"direction","confidence":1}]}]}
  system.parser.structure: {"verb":{"text":"","head":""}}
  system.validation.start: {"action":"if.action.going","hasDirectObject":false,"hasIndirectObject":false}
  system.validation.success: {"actionId":"if.action.going"}

> south

=== Turn 7 ===

Game Events:
  [SYSTEM.PARSER] {"input":"south","parsed":{"action":"if.action.going","pattern":"DIRECTION_ONLY","confidence":1,"tokens":1}}
  [SYSTEM.PARSER.TOKENS] {"count":1,"tokens":[{"word":"south","normalized":"south","partOfSpeech":["UNKNOWN"],"position":0,"length":5,"candidates":[{"id":"south","type":"direction","confidence":1}]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"","head":""}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.going","hasDirectObject":false,"hasIndirectObject":false}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.going"}
  [IF.EVENT.ACTOR_EXITED] {"actorId":"a01","direction":"south","toRoom":"r03"}
  [IF.EVENT.ACTOR_MOVED] {"direction":"south","fromRoom":"r01","toRoom":"r03","oppositeDirection":"north","firstVisit":true}
  [IF.EVENT.ACTOR_ENTERED] {"actorId":"a01","direction":"north","fromRoom":"r01"}
  [ACTION.SUCCESS] {"actionId":"if.action.going","messageId":"first_visit","params":{"direction":"south","destination":"Foyer Bar"}}

Location: Foyer Bar [r03]

[SYSTEM EVENTS]:
  system.parser: {"input":"south","parsed":{"action":"if.action.going","pattern":"DIRECTION_ONLY","confidence":1,"tokens":1}}
  system.parser.tokens: {"count":1,"tokens":[{"word":"south","normalized":"south","partOfSpeech":["UNKNOWN"],"position":0,"length":5,"candidates":[{"id":"south","type":"direction","confidence":1}]}]}
  system.parser.structure: {"verb":{"text":"","head":""}}
  system.validation.start: {"action":"if.action.going","hasDirectObject":false,"hasIndirectObject":false}
  system.validation.success: {"actionId":"if.action.going"}

> examine message

=== Turn 8 ===

Game Events:
  [SYSTEM.PARSER] {"input":"examine message","parsed":{"action":"if.action.examining","pattern":"VERB_NOUN","confidence":1,"tokens":2}}
  [SYSTEM.PARSER.TOKENS] {"count":2,"tokens":[{"word":"examine","normalized":"examine","partOfSpeech":["VERB"],"position":0,"length":7,"candidates":[{"id":"if.action.examining","type":"verb","confidence":1}]},{"word":"message","normalized":"message","partOfSpeech":["UNKNOWN"],"position":8,"length":7,"candidates":[]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"examine","head":"examine"},"directObject":{"text":"message","head":"message","modifiers":[],"articles":[],"determiners":[]}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.examining","hasDirectObject":true,"hasIndirectObject":false}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.examining","directObject":"y01"}
  [SYSTEM.VALIDATION.SCOPE] {"directObject":{"entityId":"y01","entityName":"message in the sawdust","scopeLevel":"reachable","perceivedBy":["sight","hearing","touch"]}}
  [SYSTEM.VALIDATION.RESOLUTION] {"directObject":{"parsed":"message","resolved":"y01","name":"message in the sawdust","location":"r03"}}
  [IF.EVENT.EXAMINED] {"targetId":"y01","targetName":"message in the sawdust","hasDescription":true,"hasBrief":false,"isReadable":true,"hasText":true}
  [ACTION.SUCCESS] {"actionId":"if.action.examining","messageId":"examined_readable","params":{"description":"The message, neatly marked in the sawdust, reads...","text":"You have won!"}}

Location: Foyer Bar [r03]

[SYSTEM EVENTS]:
  system.parser: {"input":"examine message","parsed":{"action":"if.action.examining","pattern":"VERB_NOUN","confidence":1,"tokens":2}}
  system.parser.tokens: {"count":2,"tokens":[{"word":"examine","normalized":"examine","partOfSpeech":["VERB"],"position":0,"length":7,"candidates":[{"id":"if.action.examining","type":"verb","confidence":1}]},{"word":"message","normalized":"message","partOfSpeech":["UNKNOWN"],"position":8,"length":7,"candidates":[]}]}
  system.parser.structure: {"verb":{"text":"examine","head":"examine"},"directObject":{"text":"message","head":"message","modifiers":[],"articles":[],"determiners":[]}}
  system.validation.start: {"action":"if.action.examining","hasDirectObject":true,"hasIndirectObject":false}
  system.validation.success: {"actionId":"if.action.examining","directObject":"y01"}
  system.validation.scope: {"directObject":{"entityId":"y01","entityName":"message in the sawdust","scopeLevel":"reachable","perceivedBy":["sight","hearing","touch"]}}
  system.validation.resolution: {"directObject":{"parsed":"message","resolved":"y01","name":"message in the sawdust","location":"r03"}}

> read message

=== Turn 9 ===

Game Events:
  [SYSTEM.PARSER] {"input":"read message","parsed":{"action":"if.action.reading","pattern":"VERB_NOUN","confidence":1,"tokens":2}}
  [SYSTEM.PARSER.TOKENS] {"count":2,"tokens":[{"word":"read","normalized":"read","partOfSpeech":["VERB"],"position":0,"length":4,"candidates":[{"id":"if.action.reading","type":"verb","confidence":1}]},{"word":"message","normalized":"message","partOfSpeech":["UNKNOWN"],"position":5,"length":7,"candidates":[]}]}
  [SYSTEM.PARSER.STRUCTURE] {"verb":{"text":"read","head":"read"},"directObject":{"text":"message","head":"message","modifiers":[],"articles":[],"determiners":[]}}
  [SYSTEM.VALIDATION.START] {"action":"if.action.reading","hasDirectObject":true,"hasIndirectObject":false}
  [SYSTEM.VALIDATION.SUCCESS] {"actionId":"if.action.reading","directObject":"y01"}
  [SYSTEM.VALIDATION.SCOPE] {"directObject":{"entityId":"y01","entityName":"message in the sawdust","scopeLevel":"reachable","perceivedBy":["sight","hearing","touch"]}}
  [SYSTEM.VALIDATION.RESOLUTION] {"directObject":{"parsed":"message","resolved":"y01","name":"message in the sawdust","location":"r03"}}
  [IF.EVENT.READ] "You have won!"
  [ACTION.SUCCESS] {"actionId":"if.action.reading","messageId":"read_text","params":{"item":"message in the sawdust","text":"You have won!"}}
  [STORY.VICTORY] "Congratulations! You have won!"

Location: Foyer Bar [r03]

[SYSTEM EVENTS]:
  system.parser: {"input":"read message","parsed":{"action":"if.action.reading","pattern":"VERB_NOUN","confidence":1,"tokens":2}}
  system.parser.tokens: {"count":2,"tokens":[{"word":"read","normalized":"read","partOfSpeech":["VERB"],"position":0,"length":4,"candidates":[{"id":"if.action.reading","type":"verb","confidence":1}]},{"word":"message","normalized":"message","partOfSpeech":["UNKNOWN"],"position":5,"length":7,"candidates":[]}]}
  system.parser.structure: {"verb":{"text":"read","head":"read"},"directObject":{"text":"message","head":"message","modifiers":[],"articles":[],"determiners":[]}}
  system.validation.start: {"action":"if.action.reading","hasDirectObject":true,"hasIndirectObject":false}
  system.validation.success: {"actionId":"if.action.reading","directObject":"y01"}
  system.validation.scope: {"directObject":{"entityId":"y01","entityName":"message in the sawdust","scopeLevel":"reachable","perceivedBy":["sight","hearing","touch"]}}
  system.validation.resolution: {"directObject":{"parsed":"message","resolved":"y01","name":"message in the sawdust","location":"r03"}}

[GAME EVENT]: game.ending - {"gameState":"ending","session":{"startTime":1755238824882,"endTime":1755238824938,"turns":9,"moves":9},"ending":{"reason":"victory"}}

[GAME EVENT]: game.won - {"gameState":"ended","session":{"startTime":1755238824882,"endTime":1755238824938,"turns":9,"moves":9},"ending":{"reason":"Message read without disturbing the sawdust","score":0,"type":"victory"}}

[GAME EVENT]: game.ended - {"gameState":"ended","session":{"startTime":1755238824882,"endTime":1755238824939,"turns":9,"moves":9},"ending":{"reason":"Message read without disturbing the sawdust","score":0,"type":"victory"}}

=== Story Complete ===

1 Like

Congrats. It really is a significant milestone to compile and run even a small game – not many people can appreciate the amount of engineering it takes just to reach “basic functionality” :slight_smile:

4 Likes