feat(rust): the live map draws monuments by label, minor labels hidden (PLAN_REDESIGNS §4, D196)

A switch per monument label, a fleet default and a per-server override, on
Admin -> Rust visibility's live map card. Substations, caves, train tunnels,
wells and the other minor labels start hidden; every other label is drawn,
so a monument a game update adds appears. GET /map leaves hidden labels out
of the answer, so the website and the app both lose them.

No schema change: rows are map.marker.<label key> in rust_settings and
rust_map_overrides. No wire change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-09-29 12:10:47 -05:00
parent eb184aaac8
commit 0da8f44b55
12 changed files with 759 additions and 26 deletions

View File

@@ -741,6 +741,12 @@ module.exports = {
description: 'The live map’s switches and each server’s picture (phase 14).',
properties: {
layers: { type: 'array', items: { type: 'string' }, example: ['world', 'events', 'players', 'bases'] },
minorLabels: {
type: 'array',
items: { type: 'string' },
description: 'D196: the monument labels hidden unless an admin turns them on. Every other label is drawn.',
example: ['Substation', 'Underground Cave', 'Train Tunnel'],
},
fleet: {
type: 'object',
properties: {
@@ -749,6 +755,7 @@ module.exports = {
players: { $ref: '#/components/schemas/RustAudience' },
bases: { $ref: '#/components/schemas/RustAudience' },
mates: { type: 'boolean', example: true },
markers: { type: 'object', description: 'D196: a monument label key (lower case) to true (drawn) or false (hidden). Only the labels somebody switched; every other label follows the default.', additionalProperties: { type: 'boolean' }, example: { substation: true } },
},
},
servers: {
@@ -758,8 +765,20 @@ module.exports = {
properties: {
id: { type: 'string', example: 'main' },
name: { type: 'string', example: 'Main · Vanilla' },
overrides: { type: 'object', description: 'Each layer and `mates`, or null to follow the fleet.' },
overrides: { type: 'object', description: 'Each layer and `mates`, or null to follow the fleet; `markers` holds only the labels this server switched itself.' },
effective: { type: 'object' },
markerLabels: {
type: 'array',
description: 'D196: the monument labels on this server’s current map, each once, with how many markers carry it.',
items: {
type: 'object',
properties: {
key: { type: 'string', example: 'substation' },
label: { type: 'string', example: 'Substation' },
count: { type: 'integer', example: 31 },
},
},
},
picture: {
type: 'object',
nullable: true,
@@ -852,7 +871,7 @@ module.exports = {
},
monuments: {
type: 'array',
description: 'Present only when the viewer may see the world layer.',
description: 'Present only when the viewer may see the world layer, and only the labels drawn on this server (D196): minor labels such as Substation are left out unless an admin turned them on.',
items: {
type: 'object',
properties: {
@@ -1120,8 +1139,8 @@ module.exports = {
},
map: {
type: 'object',
description: 'The live map’s switches. `fleet` maps a layer to an audience and `mates` to true or false; `servers` maps a server id to the same shape, where null follows the fleet.',
example: { fleet: { players: 'signed_in', mates: true }, servers: { pve: { players: 'public' }, pvp: { players: null } } },
description: 'The live map’s switches. `fleet` maps a layer to an audience and `mates` to true or false; `servers` maps a server id to the same shape, where null follows the fleet. `markers` (in either) maps a monument label key — the label in lower case, single-spaced — to true (drawn) or false (hidden); null clears it, so a server follows the fleet and the fleet the built-in list (D196).',
example: { fleet: { players: 'signed_in', mates: true, markers: { substation: true } }, servers: { pve: { players: 'public', markers: { substation: false } }, pvp: { players: null } } },
},
},
},