Files
Rust-Plugins/overlay.toml
wtclaude 210c35f904 feat(bridge): protocol 11 — the map (phase 14)
Four verbs (PLAN.md §30.2), all outside EventsEnabled because none of them
changes the world:

- map.info: the map key, the picture's source (the Rust+ cache, a render
  kept on disk, or none), its size, SHA-256 and slice count, the game's own
  grid, and the monuments the in-game map shows. The cache is read by
  reflection by name only, never enumerated (it holds the Rust+ secret).
  The hash is computed on the thread pool.
- map.fetch: one 512 KiB base64 slice, encoded on the thread pool, refused
  `stale` when the key or hash moved.
- map.render: the admin fallback (D109). Answers `accepted` at once and
  renders on a later frame, keeping the result in data/RunicGateway/map.jpg
  beside its key so a restart within the map does not render again.
- map.live: every layer at once (world events, event-owned zones/crates/NPCs,
  players and sleepers, TCs and player vending machines as positions only).
  The sets are kept by OnEntitySpawned/OnEntityKill and seeded by one sweep
  at OnServerInitialized. MapMaxSleepers/MapMaxBases bound the two layers.

Also fixes Grid() (D119): it used a 146.3 m cell, but the game fits whole
cells to the world (20 x 150 m on a 3000 map), so rows could be one off.
It now asks MapHelper.PositionToString, the in-game map's own labeller.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-25 00:33:51 -05:00

59 lines
3.3 KiB
TOML

# Release metadata for the deployable overlay.
#
# Consumed by the release workflow, which folds these values into the
# manifest.json shipped inside the overlay tarball. The Runic Gateway installer
# reads that manifest to decide what it is deploying and whether it is compatible
# with the sidecar it is about to install.
#
# There is deliberately NO version key here. The release version is derived from
# git tags and conventional commits by the release workflow, so there is no bump
# commit to keep in sync and no way for this file to disagree with the tag.
# ── The loopback wire-protocol version this overlay speaks ───────────────────
#
# The plugin half of the compatibility contract. It MUST equal the sidecar's
# PROTOCOL_VERSION (Rust-Link's sidecar/src/main.rs) for a deployment to work:
# the sidecar rejects a mismatched WEBSITE with 409, and a mismatched PLUGIN is
# worse, because the game link has no such check — it would simply mis-parse.
#
# That asymmetry is why this file exists. The plugin announces its protocol in
# `server.hello`, which is only readable after the game server has booted with it
# loaded — far too late for an installer to refuse a bad pairing. This
# declaration is what lets the bundle CI check the pair BEFORE an operator
# installs either half.
#
# Keeping it honest is a manual duty: when the protocol changes, bump it here in
# the same change that alters the emitters, exactly as the sidecar bumps
# PROTOCOL_VERSION and the module bumps its own constant.
#
# Current: 10 — the transport, the read path, identity, the permission mirror,
# configuration from the site, first-party clans, a raid frame that names who
# lives there, the event leases, the world verbs events place and give back, and
# the rewards: a run's participation tally, kit credits and chat (PROTOCOL.md §16),
# and the map: its picture and everything that moves on it (PROTOCOL.md §17).
protocol = 11
# ── Oxide compatibility ──────────────────────────────────────────────────────
#
# The overlay only ADDS a file — one plugin into `oxide/plugins/` — and patches
# nothing, so it is expected to work on any reasonably current Oxide. This is the
# oldest build it is known good on.
#
# There is no `patches_verified_against` key, and there is no `patches/` tier:
# Rust's server is a binary and Oxide's hook API is the supported way in, so
# there is nothing to diff against. That is the whole reason the Rust payload is
# simpler than the ServUO one.
min_oxide_version = "2.0.7585"
# The `oxide/plugins/` files this overlay expects to find already installed. They
# are not shipped here — they are third-party plugins an operator installs from
# uMod — and the installer's `doctor` reports a missing one rather than
# installing it. Listing them is what turns a missing reward or zone into a
# named prerequisite.
#
# The uMod **Clans** plugin is deliberately NOT listed (docs/modules/rust/PLAN.md
# D47). Teams come from Rust's own clan system, which that plugin never touches,
# so requiring it would split a server's players across two unrelated clan
# systems. It belongs to phase 17's optional tier.
requires_plugins = ["Kits", "PopupNotifications", "ZoneManager"]