From e1789c1df42cbbcba2e1b791ae65221612e1f5af Mon Sep 17 00:00:00 2001 From: wtclaude Date: Fri, 9 Oct 2026 01:24:19 -0500 Subject: [PATCH] feat(zones): a blank dome stack is 3 spheres, not 1 (runicnpc 9e, D326) The org lead chose 3 by eye at noon in RunicNPC's 9d player session. The zone step sends it when its stack is left blank, and the field's hint says so. The wire is unchanged: the module always sends a stack, and the bridge's own default for a dome without one stays 1. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY --- server/eventWorld.js | 6 ++++-- server/test/zones.test.js | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/server/eventWorld.js b/server/eventWorld.js index 276629e..5b190e1 100644 --- a/server/eventWorld.js +++ b/server/eventWorld.js @@ -60,6 +60,8 @@ const ZONE_MAX_RADIUS = 150 const ZONE_MAX_MINUTES = 7 * 24 * 60 const ZONE_MESSAGE_MAX = 256 const DOME_STACK_MAX = 10 +/** A blank stack: 3 spheres, chosen by eye at noon in RunicNPC's 9d player session (D326). */ +const DOME_STACK_DEFAULT = 3 /** * ZoneDomes' own sphere types, by the number its API takes (D194). Only Standard @@ -725,7 +727,7 @@ const ACTIONS = [ description: 'A ZoneDomes dome over the zone. "standard" is a full shaded dome; the colours show only where the sphere meets the ground or a building. Needs ZoneDomes and RunicGatewayDomes.cs on the server. Blank is no dome.', }, - { name: 'domeStack', type: 'int', required: false, example: 1, description: `How many spheres the dome stacks, 1 to ${DOME_STACK_MAX}; more is darker. Left blank, 1.` }, + { name: 'domeStack', type: 'int', required: false, example: DOME_STACK_DEFAULT, description: `How many spheres the dome stacks, 1 to ${DOME_STACK_MAX}; more is darker. Left blank, ${DOME_STACK_DEFAULT}.` }, ], async perform({ runId, idempotencyKey, params, verify }) { @@ -777,7 +779,7 @@ const ACTIONS = [ } const missing = domeMissing(mods) if (missing) return { ok: false, retry: false, error: missing } - dome = { type: kind.type, stack: stack === undefined ? 1 : stack } + dome = { type: kind.type, stack: stack === undefined ? DOME_STACK_DEFAULT : stack } } // The dry run stops here, and has checked everything it can without the diff --git a/server/test/zones.test.js b/server/test/zones.test.js index 5fd10b8..6b95c3f 100644 --- a/server/test/zones.test.js +++ b/server/test/zones.test.js @@ -224,6 +224,16 @@ test('a zone crosses with its flags, settings, messages in the chat voice, and i }) }) +test('a dome with its stack left blank stacks 3 spheres (D326)', async (t) => { + stubZones(t, { servers: [server('main', { domes: PATCHED })] }) + const calls = stubWorld(t) + const result = await action('rust.zone.open').perform({ + runId: 7, idempotencyKey: 'k', params: { monument: 'main/a', radius: 40, minutes: 5, dome: 'standard', domeStack: '' }, + }) + assert.strictEqual(result.ok, true, result.error) + assert.deepStrictEqual(calls[0].body.dome, { type: 0, stack: 3 }) +}) + test('a zone with no options crosses exactly as it always did', async (t) => { stubZones(t) const calls = stubWorld(t)