tinymux/docs/external-observability.md
Stephen Dennis 1297de78c5 docs: note 30-character @log name limit
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 12:51:22 -06:00

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:

  • @log is 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.