# Normalized module API v1 ## Conventions All operations are cancellable and receive a host-enforced deadline. IDs and text returned by a game are untrusted, size-bounded UTF-8. Timestamps use RFC 3339 UTC. Unknown fields are rejected at typed ABI boundaries for V1. Standard errors: ```text unsupported invalid_configuration unauthorized unreachable timeout rate_limited invalid_response conflict game_error internal_module_error ``` Errors contain a safe user message, stable code and optional retryability. Raw credentials, authorization headers and unbounded game responses are prohibited. ## Required exports ### `initialize(config) -> module_info` Validates declared configuration and returns module ID/version, API version and capabilities. It must not perform long-lived background work. ### `test_connection() -> connection_result` Makes the smallest safe request needed to validate reachability/authentication and reports server/API version hints when available. ### `get_server_status() -> server_status` Returns `starting`, `ready`, `degraded`, `stopping`, `offline` or `unknown`, plus a bounded safe reason. Every module implements these three exports. ## Optional capability exports | Capability | Export | Result | |---|---|---| | `server_info` | `get_server_info()` | name, game version, max players, optional world/version fields | | `metrics` | `get_metrics()` | bounded current gauges/counters, no long-term history | | `player_list` | `list_players()` | stable game player ID, display name, optional joined time/ping | | `online_save` | `save_world()` | acknowledgement that the game completed/persisted the save | | `graceful_shutdown` | `shutdown(request)` | accepted/completed state and safe message | | `announcement` | `send_announcement(message)` | accepted result | | `kick` | `kick_player(player_id, reason?)` | action result | | `ban` | `ban_player(player_id, reason?)` | action result | | `unban` | `unban_player(player_id)` | action result | An optional export cannot exist as an enabled UI action unless manifest, runtime report, template and permission agree. ## Host functions ### `http_request(instance_api, request)` Request fields: relative path, allow-listed method, bounded headers excluding host/connection overrides, bounded body and timeout not exceeding runtime maximum. The host fixes scheme, authority and destination port, validates redirects and bounds the response. ### `tcp_exchange(instance_api, request)` Available only when declared. Sends and receives bounded bytes on the bound declared TCP integration port with fixed connect/read/write deadlines. It is not a general socket handle. ### `get_secret(key)` Returns only a manifest-declared secret configuration item for the current instance. The value cannot be logged through diagnostics and should be consumed immediately. ### `emit_diagnostic(level, code, message)` Accepts bounded structured diagnostic data. The host redacts and rate-limits it. Modules cannot write directly to application logs. ## Semantic requirements - `save_world` success means the game acknowledged completion, not merely request dispatch. - `shutdown` never stops a Docker container directly; lifecycle code observes container exit and uses the agent for timeout fallback. - Player actions use stable game IDs, not only display names. - Metrics use documented normalized names/units. Unknown game-specific metrics may be omitted rather than smuggled into arbitrary maps in V1. - All calls are side-effect-free except save, shutdown, announcement and player-action exports.