feat(bridge): Economics on protocol 14 — pay, balances, adjust (PLAN_REDESIGNS §11.2) #31

Merged
whitlocktech merged 1 commits from feat/protocol-14-economics into edge 2026-10-12 07:40:25 -05:00
Member

What & why

The bridge half of PLAN_REDESIGNS.md §11.2.2: Wulf's Economics as an optional integration (D199). The spec is docs/rust-link/PROTOCOL.md §20.3 (docs PR alongside). It stays on protocol 14 (D332).

  • hello/status integrations.economics adds startingBalance and wipesWithMap. Both are read from Economics.json in the framework's config directory, re-read only when the file changes, and absent when the file can't say. Hello is re-sent when Economics loads or unloads.
  • economics.pay pays coins from an event step, and the coins are kept once paid (D335).
    • One main-thread call handles the whole list. Each deposit is measured as after − before, because Deposit answers true while rounding and clamping.
    • failed reasons are at-limit, refused, unmeasured and bad-id.
    • The key and its reply are kept seven days in data/RunicGateway/payments.json, so a retry answers repeat: true and pays nobody.
    • The optional message has {amount} replaced by what that player received. It is told now if they're awake, otherwise when they next wake (§20.2's rule).
  • economics.balances is bounded by PermMaxOps.
  • economics.adjust is for staff: deposit, withdraw or set.
    • A withdrawal above the balance is refused as insufficient, with the balance.
    • A deposit that moved nothing is refused as at-limit.
    • Keys are remembered in their own namespace, separate from payments.
  • player.tally gains balance, a value rather than a change. It is read at connect (D336), when Economics loads with players on, and from OnEconomicsBalanceUpdated. Offline players are included, and a frame carries a name only for a connected player.
  • economics.wiped comes from OnEconomicsDataWiped(IPlayer). newSave is true for the no-argument (new save) call.

Per the spike, every amount is boxed as double and only parsed Steam ids reach Economics. requires_plugins is unchanged. The README notes the plugin as optional.

How it was tested

  • node scripts/checkPlugin.js: protocol 14, 57 hooks, every one void and listed. node --test scripts/checkPlugin.test.js passes.
  • Compiled on both rigs: Oxide 2.0.7826 in 5.2 s and Carbon 2.0.262 in 3.0 s, on Rust 25877464. The first attempt found a duplicate DoubleField helper, which was fixed by using the existing one. Both rigs were then given back their protocol 13 bridge.
  • One line changed after the rig compile: player.IsConnected in OnEconomicsBalanceUpdated, a property the file already uses. Static checks were re-run.
  • The behaviour walk is deferred to the end-of-plan walk (D331). Its rows are in PLAN_REDESIGNS §11.2.3.

Checklist

  • I have read CONTRIBUTING.md.
  • The change builds and existing tests/checks pass locally.
  • I have added or updated tests/docs where it makes sense.
  • My commits are reasonably scoped with clear messages.

AI-assisted contributions (required)

  • No AI tools were used to produce this contribution.
  • AI tools were used. Tool(s): Claude Code (Claude Opus 5.5). I have reviewed and understand
    every change, and take responsibility for it. AI-authored commits are
    marked with a Co-Authored-By / Assisted-By trailer.

License

  • I agree that my contribution is licensed under this project's license
    (GNU GPL v3.0 or later), and I have the right to contribute it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

## What & why The bridge half of `PLAN_REDESIGNS.md` §11.2.2: Wulf's **Economics** as an optional integration (D199). The spec is `docs/rust-link/PROTOCOL.md` §20.3 (docs PR alongside). It stays on protocol 14 (D332). - **hello/status `integrations.economics`** adds `startingBalance` and `wipesWithMap`. Both are read from `Economics.json` in the framework's config directory, re-read only when the file changes, and absent when the file can't say. Hello is re-sent when Economics loads or unloads. - **`economics.pay`** pays coins from an event step, and the coins are kept once paid (D335). - One main-thread call handles the whole list. Each deposit is measured as *after − before*, because `Deposit` answers `true` while rounding and clamping. - `failed` reasons are `at-limit`, `refused`, `unmeasured` and `bad-id`. - The key and its reply are kept seven days in `data/RunicGateway/payments.json`, so a retry answers `repeat: true` and pays nobody. - The optional message has `{amount}` replaced by what that player received. It is told now if they're awake, otherwise when they next wake (§20.2's rule). - **`economics.balances`** is bounded by `PermMaxOps`. - **`economics.adjust`** is for staff: deposit, withdraw or set. - A withdrawal above the balance is refused as `insufficient`, with the balance. - A deposit that moved nothing is refused as `at-limit`. - Keys are remembered in their own namespace, separate from payments. - **`player.tally` gains `balance`**, a value rather than a change. It is read at connect (D336), when Economics loads with players on, and from `OnEconomicsBalanceUpdated`. Offline players are included, and a frame carries a `name` only for a connected player. - **`economics.wiped`** comes from `OnEconomicsDataWiped(IPlayer)`. `newSave` is true for the no-argument (new save) call. Per the spike, every amount is boxed as `double` and only parsed Steam ids reach Economics. `requires_plugins` is unchanged. The README notes the plugin as optional. ## How it was tested - `node scripts/checkPlugin.js`: protocol 14, 57 hooks, every one void and listed. `node --test scripts/checkPlugin.test.js` passes. - **Compiled on both rigs**: Oxide 2.0.7826 in 5.2 s and Carbon 2.0.262 in 3.0 s, on Rust 25877464. The first attempt found a duplicate `DoubleField` helper, which was fixed by using the existing one. Both rigs were then given back their protocol 13 bridge. - One line changed after the rig compile: `player.IsConnected` in `OnEconomicsBalanceUpdated`, a property the file already uses. Static checks were re-run. - The behaviour walk is deferred to the end-of-plan walk (D331). Its rows are in PLAN_REDESIGNS §11.2.3. ## Checklist - [x] I have read [CONTRIBUTING.md](CONTRIBUTING.md). - [x] The change builds and existing tests/checks pass locally. - [x] I have added or updated tests/docs where it makes sense. - [x] My commits are reasonably scoped with clear messages. ## AI-assisted contributions (required) - [ ] No AI tools were used to produce this contribution. - [x] AI tools were used. Tool(s): `Claude Code (Claude Opus 5.5)`. I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a `Co-Authored-By` / `Assisted-By` trailer. ## License - [x] I agree that my contribution is licensed under this project's license (**GNU GPL v3.0 or later**), and I have the right to contribute it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-10-12 07:16:04 -05:00
feat(bridge): Economics on protocol 14 — pay, balances, adjust (PLAN_REDESIGNS §11.2)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 10s
66fbbd6b57
Wulf's Economics as an optional integration (D199), as §11.2.2 designs it:

- hello/status `integrations.economics` adds startingBalance and wipesWithMap,
  read from Economics.json (cached by mtime) because its API has neither.
- `economics.pay`: coins from an event step, kept once paid (D335). One main-
  thread call for the list; each deposit measured as after - before, since
  Deposit answers true while rounding and clamping (`at-limit` otherwise).
  The key and its reply are kept in data/RunicGateway/payments.json for seven
  days, so a retry answers `repeat: true` and pays nobody. The optional
  message ({amount} = what landed) is told now if awake, else on wake.
- `economics.balances` (bounded by PermMaxOps) and staff `economics.adjust`
  (deposit / withdraw / set; a withdrawal above the balance is refused
  `insufficient` with the balance).
- `player.tally` gains `balance`, a value: read at connect (D336) and from
  OnEconomicsBalanceUpdated, offline players included.
- `economics.wiped` from OnEconomicsDataWiped(IPlayer), with `newSave`.

Amounts are boxed as double and only Steam ids are sent, per the spike.
Compiled on both rigs (Oxide 2.0.7826, Carbon 2.0.262), then restored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
whitlocktech merged commit 3db35cdd02 into edge 2026-10-12 07:40:25 -05:00
whitlocktech deleted branch feat/protocol-14-economics 2026-10-12 07:40:26 -05:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Rust-Plugins#31
No description provided.