Add SITREP inspection feature#19
Open
gitosaurus wants to merge 12 commits into
Open
Conversation
Lay the Archetype-side groundwork for the situation report feature: - Extract 'ROLL CALL' as a reusable method on main, called after initialization and after each turn's events - Add 'INVENTORY NAMES' message to list_inventory, which gathers inventory item names into a list without printing them - Refactor 'INVENTORY' to use 'INVENTORY NAMES' internally, so the name-gathering and display logic are separated - Add 'SITREP' method on main that assembles exits, visible objects, and inventory as a structured PairValue list of key-value pairs - SITREP is not called automatically; it is available on demand Rewrite inspect_universe for proper RDF/Turtle output The --inspect flag now produces well-formed Turtle with: - Proper prefixes: archetype:, type:, object:, attr:, msg:, xsd: - Attribute values rendered via asRDF() (e.g., attr:desc "dank cellar") instead of just listing attribute names - Type hierarchy via rdfs:Class and rdfs:subClassOf - Instance typing via rdf:type (Turtle 'a' shorthand) - Vocabulary: verb/noun phrases as archetype:verbPhrase and archetype:nounPhrase predicates on each object - Proximate objects as archetype:proximate on archetype:situation - Methods (--full flag): archetype:respondsTo msg:MESSAGE_NAME with URI-encoded message names Without --full, only object identity, types, and attribute values are emitted — this is the "state-only" view suitable for external parsers or AI systems that need to understand the game situation without knowing the internal method implementations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> The SITREP must contain the same information a SystemParser uses: actual object references, not human-readable strings. A consuming program needs to know that the exit is object:south (an Archetype object it can reference), not the string "south". - Add 'INVENTORY OBJECTS' message to list_inventory, which gathers member objects (filtered by visibility) as a list of ObjectValues - Change 'SITREP' to use 'INVENTORY OBJECTS' instead of 'INVENTORY NAMES' for exits, visible objects, and inventory - Add player.location as the "location" key - Add it.referent as the "it" key when a pronoun is set The existing 'INVENTORY NAMES' and 'INVENTORY' (display) paths are unchanged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Use type:/obj: prefixes to distinguish prototypes from instances Replace per-type instance prefixes (room:, wearable:, etc.) with a single obj: prefix for all instances. The type relationship is already captured by rdf:type triples, so encoding it in the URI is redundant. This gives a clean two-prefix scheme: type: for prototypes, obj: for instances. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Add TestInspectUniverse test suite Covers class/type emission for null-parent and typed instances, Turtle well-formedness of the vocabulary block (no stray leading semicolon), and the proximate list (no stray leading comma). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Brackets: list literals now use [...]; {...} is exclusively a compound
statement. Parser, PairValue::display, intrptr.arch sources, and tests
updated. See list_design.md for the rationale (spreadsheet-model
preservation, ending the list/block homoglyph).
REPL: results now print as `=> value` using display() only. Dropped the
trailing stringConversion tail, which duplicated scalar output (`8 8`)
for values whose display and string forms happen to match. Matches
Python/Ruby/Lisp convention.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR lays groundwork for a “SITREP” (situation report) feature and modernizes the --inspect output to emit RDF/Turtle, alongside a syntax change for Archetype list literals from {} to [].
Changes:
- Add an optional
--sitreppath to--updateto append a structured situation report (SITREP + parser context). - Rewrite
--inspectto emit Turtle with richer type/attribute/method modeling and parser vocabulary/proximity output. - Introduce
Value::asRDF()and switch list literal display syntax from{}to[], with updated/added tests.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/update_universe.hh | Extends update_universe API to optionally append sitrep output. |
| src/update_universe.cc | Implements sitrep emission and parser-context dump after UPDATE. |
| src/main.cc | Adds --sitrep and --full flags and wires them into update/inspect flows. |
| src/inspect_universe.hh | Extends inspect_universe signature with include_methods toggle. |
| src/inspect_universe.cc | Rewrites inspection output as Turtle with prefixes, types, attributes, methods, and parser vocabulary/proximity. |
| src/Value.hh | Adds asRDF() to the Value interface and concrete value types. |
| src/Value.cc | Implements asRDF() for values and updates PairValue display + RDF rendering. |
| src/TestValue.cc | Updates list display expectations to the new [] syntax. |
| src/TestInspectUniverse.hh | Adds a new test suite for Turtle output structure. |
| src/TestInspectUniverse.cc | Adds tests for type output and Turtle syntax constraints for vocabulary/proximity. |
| src/TestExpression.hh | Adds tests for list literal parsing and REPL output formatting. |
| src/TestExpression.cc | Implements list literal parsing tests and REPL display regression test. |
| src/SystemParser.hh | Updates friend declarations to match new inspect signature and sitrep helper. |
| src/SystemObject.hh | Updates friend declarations to match new inspect signature and sitrep helper. |
| src/ReadEvalPrintLoop.cc | Adjusts REPL output formatting to => <display> only. |
| src/Object.hh | Updates inspect_universe friend declaration signature. |
| src/Expression.cc | Switches list literal parsing from {} to []. |
| src/CMakeLists.txt | Adds new TestInspectUniverse to the build. |
| games/intrptr.arch | Adds ROLL CALL and SITREP methods and refactors inventory listing; updates list literal usage to []. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Emit archetype:verbPhrase / nounPhrase values through a local escape_literal helper so quotes and backslashes in phrases stay valid Turtle. The helper mirrors escape_string in Value.cc, kept local to avoid a cross-TU dependency. In intrptr.arch, rename the local variable inside 'INVENTORY OBJECTS' from 'names' to 'items' to reflect that it collects objects, not strings, and declare 'items' on list_inventory alongside the existing 'names' attribute used by the sibling methods.
The parser-context portion of --sitrep was emitting a custom text format (PROXIMATE/NOUNS/VERBS s-expressions) out of step with the Turtle produced everywhere else. Unify on Turtle and promote the parser to a first-class RDF entity. Changes in inspect_universe: - Factor the RDF emission into dump_universe_rdf (no deserialization) and write_parser_rdf, both callable independently. inspect_universe now deserializes and delegates. - Collapse archetype:verbPhrase and archetype:nounPhrase into a single archetype:matchesPhrase predicate. The kind of match (verb vs noun) is already conveyed by the object's rdf:type. - Add archetype:matchesNow, the subset of noun phrases whose referent is currently proximate. Pre-baked here so LLM-style consumers without SPARQL can answer "what can the player type right now?" with a direct scan. - Replace the standalone archetype:situation block with an archetype:parser block (a archetype:SystemParser) carrying mode, proximate, playerCommand, normalized, and parsedValue. This is the natural home for what was previously emitted as ad-hoc text. Changes in update_universe: - Delete sitrep_parser_context. --sitrep now appends proper Turtle via write_parser_rdf with prefixes. - Add an inspect parameter; --update --inspect appends the full post-turn universe (via dump_universe_rdf), closing the UX gap where there was no single invocation to get SITREP plus full game state. Tests in TestInspectUniverse updated to match the unified predicates and the relocated proximate block.
- TestInspectUniverse::testParserBlock_ drives the parser through a PLAYER CMD so playerCommand_ and normalized_ are populated, then pins archetype:parser a archetype:SystemParser along with mode, playerCommand, and normalized in the Turtle output. - New TestUpdateUniverse suite exercises update_universe() across its three modes: plain (no RDF appended), --sitrep (prefixes + parser block appended), --inspect (full universe dump appended). Uses a minimal null-parent main object so the assertions don't depend on standard.arch vocabulary.
The --sitrep path was still emitting the old ad-hoc header
SITREP ( ( "location" obj:cell ) ... )
which is a Turtle collection floating without a subject/predicate —
not a valid triple. Walk the list returned by 'SITREP' (a sequence
of [ "key" value ] pairs) and emit each pair as its own predicate on
archetype:situation, an instance of archetype:SituationReport. This
gives consumers proper RDF they can query directly
(?s archetype:inventory ?x) instead of traversing a nested list.
Key names are sanitized to valid Turtle local-name characters;
non-identifier characters fold to underscore. Trusting the game-side
convention that SITREP keys are short identifier-ish words.
Extends TestUpdateUniverse with testSitrepUnpacksPairs_ to pin the
predicate-per-pair shape and guard against regression to the old
"SITREP (" label.
Address PR #19 feedback: dispatch_to_universe("SITREP") calls Messages.index(), which inserts a new ID when the message is absent. Because update_universe serializes the universe back to disk after its work, this silently grew the message table of any saved game that lacked a SITREP handler. Guard the dispatch with Messages.find() so the table is only consulted, never mutated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address PR #19 feedback: the previous code called evaluate() on every attribute expression without setting self, which could yield wrong values for self-referential expressions and could trigger side effects for non-literal attribute defaults. Limit emission to attributes whose expressions are ValueExpression (the form Object::setAttribute stores into) and wrap the evaluation in a ContextScope, matching the pattern used in AttributeValue::dereference_(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously the option parser stuffed any --name[=value] token into the opts map and the rest of main() only count()ed the names it knew about. A misspelled flag (e.g. --compile in place of --create) was silently accepted, causing the interpreter to run in a different mode than the user intended. Refactor each consumer to find() and erase-by-iterator (single lookup, O(1) amortized erase), then validate opts and args at every exit path. Anything left over now produces a diagnostic and exit code 1. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address PR #19 feedback: dump_universe_rdf emitted the parser block (vocabulary, matches, proximity) unconditionally even when include_methods was false, mixing world state with parser internals. Move that block under the same flag that gates method signatures. After this change: --inspect world state only (objects, types, attribute values) --inspect --full state plus methods and parser vocabulary --update --inspect state only (post-turn snapshot) --update --sitrep parser block plus per-key situation report Update the --inspect and --full help text to match. Adjust TestInspectUniverse's helper to take an include_methods argument so the vocabulary/proximate/parser-block tests can request the fuller output. Rename TestUpdateUniverse::testInspectAppendsFullRdf_ to testInspectAppendsStateRdf_ and invert its parser-block assertion to reflect the new contract. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address PR #19 feedback: ObjectValue::asRDF, ObjectValue::display, and ObjectValue::identifierConversion each performed a linear scan over ObjectIdentifiers to find the name bound to an object, making RDF emission and display O(N^2) in the number of named objects. Add a parallel std::map<object_id, identifier_id> on Universe, kept in sync at the single write site (assignObjectIdentifier) and rebuilt after deserialization. Expose it via Universe::identifierForObject, which the three call sites now use directly. inspect_universe.cc also built its own local reverse map twice (build_reverse_ids / obj_name_for) to dodge the same problem within a single emission; drop that duplication and call the Universe API. No behavior change: every entry in ObjectIdentifiers represents a unique (identifier, object) pair under current Archetype syntax (assignObjectIdentifier is only invoked at declaration time and there is no syntactic path to bind a second name to an existing object), so the reverse map is well-defined. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add SITREP inspection feature: a "SITuation REPort" of an ACX file, with object state, proximity, and vocabulary as RDF. Intended to be enough information to understand the game state — and how the parser sees the world — without having to read the binary ACX directly.
Archetype-side groundwork
ROLL CALLas a reusable method onmain, called after initialization and after each turn's eventsINVENTORY NAMESmessage tolist_inventoryto gather inventory item names into a list without printing themINVENTORYto useINVENTORY NAMESinternally, separating name-gathering from displaySITREPmethod onmainthat returns a list of key/value pairs:location,exits,visible,inventory, and (when set)itRDF/Turtle output from
--inspectProduces well-formed Turtle:
archetype:,type:,obj:,attr:,msg:,xsd:,rdf:,rdfs:rdfs:Class/rdfs:subClassOf; instance typing viardf:type(theashorthand)asRDF()(e.g.,attr:desc "dank cellar") rather than just attribute names. Only materialized values appear — uninitialized default expressions are skipped--inspectalone is state-only (objects, types, attribute values). Pass--fullto also include:archetype:matchesPhrasefor every verb/noun phrase the parser recognizesarchetype:matchesNowfor phrases whose referent is currently proximatearchetype:parser a archetype:SystemParserwitharchetype:mode,archetype:proximate,archetype:playerCommand,archetype:normalizedarchetype:respondsTo msg:MESSAGE_NAME(URI-encoded)New flags on
--update--update --sitrepappends the parser block followed by anarchetype:situation a archetype:SituationReportblock with one predicate per SITREP key (archetype:location,archetype:exits, etc.)--update --inspectappends a state-only universe dumpOther changes
{}was visually easy to confuse with compound statements.--compilein place of--createused to silently run the interpreter in a different mode.)