Skip to content

game: admin /treasury — list and top up Bali place treasuries - #317

Merged
chiliec merged 1 commit into
mainfrom
game/treasury-topup
Sep 9, 2026
Merged

game: admin /treasury — list and top up Bali place treasuries#317
chiliec merged 1 commit into
mainfrom
game/treasury-topup

Conversation

@chiliec

@chiliec chiliec commented Sep 9, 2026

Copy link
Copy Markdown
Member

Closes the second of the three open items in docs/BALI_SPEC.md §4.

Since #315 the Bali engines never mint — a window pays out at most staked + pool. That closes the faucet, but it also means a place that has paid out its seed stays poor forever with no way to refill it. This PR is the budget line.

The command

  • /treasury — every playable place, its pool, and the total. A place with no PlaceState document yet is marked (unseeded) and reported at its seed, so an operator doesn't top up a place that has simply never been played.
  • /treasury <place> <amount> — moves one pool and echoes the result. Negative drains and is floored at 0.

Admin-only, and capped at 1,000,000 per call: this is now the only faucet into Bali and the only place $CUBE is created there, so a fat finger has no undo. Larger budgets are several deliberate calls.

Notes

  • addToPool uses $inc, so concurrent top-ups compose. The resolver still writes the pool with an absolute $set at a window boundary, so a top-up landing in that microsecond is lost — flagged in the code, and the command echoing the resulting pool is how an operator notices. Not worth a transaction for a manual admin action that runs a few times a year.
  • Registered in buildAdminChatCommands so it shows up in the admin command menu.
  • Pure handler + composer per the project pattern; treasury-handler.test.ts covers the listing, top-up, drain-to-floor, unseeded fallback, the cap, and that no bad input ever reaches the database (6 tests).

npm run lint && npm run typecheck && npm run test:backend && npm run smoke:api → clean, 650/650.

Still open after this: whether the minority places should get a real move — they currently have no move at all, so the name describes turnout, not strategy.

Since #315 the engines never mint: a window pays out at most what its
visitors staked plus what the place treasury already held. That closes
the faucet, but it also means a place that has paid out its seed stays
poor forever with no way to refill it. This is the budget line.

/treasury lists every playable place, its pool and the total, marking
places with no PlaceState document yet as unseeded so an operator does
not top up a place that has simply never been played.

/treasury <place> <amount> moves one pool. Capped at 1,000,000 per call
because a fat finger here mints $CUBE into the game with no undo;
negative drains and is floored at 0.

This is now the only faucet into Bali and the only place $CUBE is
created there, which is why it is admin-only, capped, and echoes the
resulting pool.

addToPool uses $inc so concurrent top-ups compose; the resolver still
writes the pool with an absolute $set at a window boundary, so a top-up
landing in that microsecond is lost — noted in the code, and the command
echoing the pool is how an operator notices.
@chiliec
chiliec merged commit f73cb34 into main Sep 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant