6.1 KiB
External Observability and Tooling Boundaries
This note describes the safest current boundaries for external tools that need to observe activity in a TinyMUX game.
It is documentation, not a feature proposal. It does not define a structured event API, and it does not cover external command submission or remote control of the game.
The central distinction is simple:
- player-visible output is text for humans;
- event classification should happen inside the game, before activity is flattened into prose.
A human reader can usually understand a line of output from context. External tooling cannot safely make the same assumption unless the game has already tagged or formatted the activity in a deliberate way.
Ordinary Client Sessions
An ordinary client session is the supported way for an external tool to observe what a connected player or observer can see.
This is appropriate when the tool needs to capture the same view that a normal client receives.
However, player-visible output is best-effort human-readable text. It is not a stable machine-readable integration contract.
Output can vary with:
- ANSI/color settings;
- client width;
- encoding negotiation;
- Pueblo mode;
- server configuration;
- permissions;
- release-to-release formatting changes.
For that reason, ordinary session output is useful for observation, debugging, and transcript capture, but it should not be treated as a stable event stream.
Why Text Parsing Is Fragile
A line of output may be clear to a person while still being ambiguous to a tool.
For example, an external tool may need to distinguish between:
- speech;
- poses;
- emits;
- movement;
- connection notices;
- room descriptions;
- command results;
- channel traffic;
- text generated by local game logic.
Once activity has been rendered as prose, some of its original meaning may no longer be explicit. The text may still be correct for a player, but it may not be reliable as a machine-readable boundary.
If event classification matters, avoid scraping normal player-visible output.
Softcode Relay Pattern
The long-standing MUSH-family answer is to classify activity with softcode.
A puppet, listener object, or @listen / @ahear object can observe activity within normal permission boundaries and re-emit it in a local machine-friendly format.
This keeps the classification close to the source of the activity.
Instead of an external process trying to guess what a line of prose means, the game can decide what kind of activity occurred and format that information intentionally.
This pattern is useful when a site wants read-only external observation without depending on the exact formatting of normal client output.
@log
@log <name>=<message> provides a small delivery surface for caller-controlled output.
Current behavior:
@logis wizard-only;- it appends to a pre-created
logs/M-<name>.log; - the target file must already exist;
- the log name is restricted to alphanumeric characters, at most 30 of them;
- the message payload is caller-controlled;
- color is stripped;
- a newline is added;
- no timestamp, prefix, or additional prose is added by
@log.
This makes @log suitable for softcode-emitted JSON, TSV, or another local structured format.
Example caller-defined payload:
{"event_type":"room_say","actor":"#2","room":"#3","text":"Hello."}
This is only an example of a local payload shape. It is not a built-in TinyMUX event schema.
Combined with the softcode relay pattern, @log lets a site produce unambiguous observer output without parsing normal player-visible prose.
General Server Logs
General server logs are operational and administrative.
They are not scoped to what a particular player or observer can see, and their formats are not stable integration contracts.
They are useful for server administration, but they are not the recommended surface for player-visible observation tooling.
muxscript
muxscript is located under mux/script/.
It loads the game engine without the networking layer. It reads softcode commands from standard input and writes output to standard output.
This is useful for:
- deterministic smoke tests;
- command replay;
- regression fixtures;
- testing softcode behavior;
- removing transport-layer variability.
It avoids issues such as telnet negotiation, SSL, descriptors, keepalives, and client connection behavior.
However, muxscript still produces human-readable TinyMUX output. It removes transport variability, not output-format ambiguity.
If the goal is unambiguous event records, use softcode classification and a caller-controlled delivery surface such as @log.
testcases/
The smoke suite under testcases/ can serve as non-normative reference material for current behavior.
It documents what the tree currently does. It should not be treated as a promise that player-visible output is a stable external integration API.
This makes testcases/ useful for regression detection, but not as a general event contract.
Decision Guide
Use an ordinary client session when the tool needs to observe what a connected player or observer sees and can tolerate human-readable output.
Use a softcode relay when the tool needs activity to be classified before it becomes prose.
Use @log when softcode should emit caller-controlled machine-readable lines for an external consumer.
Use general server logs for operational and administrative review, not player-scoped observability.
Use muxscript when deterministic command execution or replay matters more than exercising the network/client layer.
Use testcases/ as reference material for current expected behavior, not as a stable integration contract.
Summary
TinyMUX can be observed from outside the server, but the safest boundary depends on what the external tool needs.
For human-facing observation, ordinary client output is appropriate.
For reliable event-like tooling, do not scrape player-visible prose if avoidable. Classify the activity inside the game with softcode, then deliver caller-controlled records through a narrow surface such as @log.
For deterministic tests and replay, use muxscript where the network layer is not part of what needs to be tested.