refactor(rust): one placing verb per kind — rust.crate.place and rust.npc.place (D97)
Core learns which caps an action accepts by pricing its declared examples once, and drops a dimension priced at zero. A single rust.prefab.place whose cost moved between rust.prefabs and rust.npcs by its prefab param could only ever show the crates cap, so D89's separate dial for fights was unreachable. Two verbs, each pricing exactly one dimension, with the prefab source split to match (rust.options.crates / rust.options.npcs). The switchboard can now allow crates and leave NPCs off. The plugin's world.place is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -153,19 +153,19 @@ test('the world verbs are registered, and every budget has a verb that spends it
|
||||
|
||||
const actions = api.record.eventActions
|
||||
const budgets = api.record.eventBudgets
|
||||
assert.deepStrictEqual(actions.map((a) => a.id).sort(), ['rust.prefab.place', 'rust.zone.open'])
|
||||
assert.deepStrictEqual(actions.map((a) => a.id).sort(), ['rust.crate.place', 'rust.npc.place', 'rust.zone.open'])
|
||||
assert.deepStrictEqual(budgets.map((b) => b.id).sort(), ['rust.npcs', 'rust.prefabs', 'rust.zone.minutes'])
|
||||
|
||||
// D79/D89: no dimension without a verb that spends it. A crate step and an
|
||||
// NPC step are priced on different dials, and a zone on its minutes.
|
||||
// D79/D89/D97: every dimension has a verb that spends it, and each verb spends
|
||||
// exactly ONE — priced from its own declared examples, which is how core
|
||||
// decides which cap boxes the switchboard shows. A verb whose dimension moved
|
||||
// with its params would hide the other dial from every operator.
|
||||
const spent = new Set()
|
||||
const place = actions.find((a) => a.id === 'rust.prefab.place')
|
||||
for (const cost of [
|
||||
place.cost({ prefab: 'crate.elite', count: 3 }),
|
||||
place.cost({ prefab: 'npc.scientist', count: 2 }),
|
||||
actions.find((a) => a.id === 'rust.zone.open').cost({ minutes: 90 }),
|
||||
]) {
|
||||
for (const id of Object.keys(cost)) spent.add(id)
|
||||
for (const a of actions) {
|
||||
const example = Object.fromEntries(a.params.map((p) => [p.name, p.example]))
|
||||
const dims = Object.keys(a.cost(example)).filter((id) => a.cost(example)[id] > 0)
|
||||
assert.strictEqual(dims.length, 1, `${a.id} prices ${dims.join(', ')}`)
|
||||
spent.add(dims[0])
|
||||
}
|
||||
assert.deepStrictEqual([...spent].sort(), budgets.map((b) => b.id).sort())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user