Files
brass-and-sigil/docs/economy-system.md
T
Matt 121ae4c603 docs: economy v0.3 — custom mod + UI approach + tier ladder + spawn plots locked
Architectural revisions:

- UI approach: custom companion mod (working name 'bnstoolkit') built
  on FTB Library's UI framework. Polished GUI screens for Quest Log,
  Bounty Board, Tier upgrade, Shop browser, Plot purchase. Quest
  progress as a custom HUD render layer (no stacked vanilla bossbars).
  All player interaction through GUI + NPC dialogue, no chat commands
  to memorise. FTB Library UI chosen for visual consistency with the
  rest of the FTB stack already in the pack.

- Tier ladder locked: 8 tiers, Civic theme, starting at Peasant.
  Peasant -> Citizen -> Patron -> Notable -> Baron -> Noble -> Lord
  -> Sovereign. Replaced Burgess with Baron; reordered ascending.

- Tier perks: full table with chunks claimable, spawn plot slots,
  sethome count, daily bounty slots, shop fee, chat colour, join
  broadcast tier, /back access. JSON-configured at
  config/bnstoolkit/tiers.json, hot-reloadable. Easy to tune any
  column without code changes.

- Spawn plots clarified as distinct from wilderness chunk claims:
  predefined regions at spawn, purchased individually for spurs,
  primary use is shops, slot-limited by tier. Purchase happens
  inside the FTB Chunks map UI via custom mod mixin. Plot data
  lives in the custom mod, not in FTB Chunks.

- Wilderness chunk claims: tier-allocated, free within allowance,
  refused above. NO per-chunk pricing (dropped from v0.2). Powered
  by FTB Ranks -> FTB Chunks permission nodes.

- Phasing updated to add Phase 0c (mod scaffolding) and reorder
  Phases 1-7 to fit the mod-supplied UI work.

- Implementation notes: KubeJS script layout, custom mod package
  layout, state data locations, config file locations all
  documented.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 22:27:06 +00:00

492 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Brass and Sigil — Economy & Quest System Design
> Status: architecture + UI approach locked (v0.3). Custom companion mod confirmed.
> Owner: matt
> Last updated: 2026-06-06
---
## 1. Goals
- **One unified currency** — spurs (Numismatics).
- **Multiple ways to earn, each one bounded.** No infinite money printer.
- **Multiple sinks that scale with progression.** Money disappears as you advance, so wealth never dwarfs the cost of new ambitions.
- **Spatial design that gives spawn personality.** Themed guild buildings, each with a clear purpose, each tied to the same wallet.
- **Forward-compat with a proper quest line** via FTB Quests, while supporting daily/repeatable activities at spawn.
- **Anti-automation by design**, not by patches.
---
## 2. Core architecture
```
┌────── MONEY IN (bounded) ──────┐
│ │
Adventurer's Guild — Daily bounties (cooldowns, scaling)
Merchant's Bazaar — Sell shop (fixed + DR), dynamic exchange
Mint — Capped emerald → spur conversion *
First-time milestones — One-shot per player
FTB Quests — Progression milestone payouts
┌───────────────────┐
│ Player wallet │ ← Numismatics
│ (spurs) │
└───────────────────┘
┌────── MONEY OUT (scaling) ──────┐
│ │
Civic Office — Plot claim costs (FTB Chunks override)
Civic Office — Tier upgrades (FTB Ranks integration)
Merchant's Bazaar — Player-to-player job board (no minting)
Villagers — Re-priced trades, net sink
Custom services — Warps, sethomes, premium cosmetics
```
\* Only if we keep emeralds; see §5 — we're moving villagers to spurs, which probably retires the Mint as a currency-conversion station and repurposes it as a wallet/info hub.
---
## 3. Spawn — themed guild buildings
Each guild is a destination. The guild's NPC is both the **entry point** (accept work) and **exit point** (return to claim reward). This pattern applies universally — see §4.
| Building | Purpose | Primary mechanics inside |
|---|---|---|
| **Adventurer's Guild** | Combat & exploration | Bounty board (daily mob hunts), boss-kill quests, dungeon-delve quests (future) |
| **Merchant's Bazaar** | Trade & raw-mat economy | Numismatics sell shop, dynamic exchange counter, player-driven job board |
| **Civic Office** | Land & status | Tier upgrade screen, spawn plot registry (purchase / view your plots), sethome/warp services. NOTE: regular wilderness chunk claiming uses the FTB Chunks map and is tier-allocated, not paid per chunk — see §4. |
| **Library / Academy** | Knowledge & magic | FTB Quests anchor NPC, Ars Nouveau themed quests, lore terminals |
| **Tavern** | Social & onboarding | First-time newbie quests, casual NPCs, food/buff vendor |
| **Foundry / Workshop** | Crafting & commissions | Create-themed contracts, crafting orders, raw-material market |
| **Mint** | Currency information | Wallet info, currency tutorial, possibly emerald exchange |
### Forward-compat with a full quest line
The architecture is naturally dual-track:
- **FTB Quests** = the *progression* backbone — chapter-by-chapter pack content, one-time rewards, story arcs. The campaign.
- **Spawn-building NPCs** (Easy NPC + KubeJS) = the *daily/repeatable* layer — bounties, sell shops, services. The live activities.
Both pay into the same wallet. Players run the campaign at their pace and the daily content for income/replay value. They reinforce each other rather than compete.
---
## 4. Tier system & spawn plots
Two distinct land/status systems that often get conflated. Keeping them clean:
### 4a. Civic tier ladder
Every player has a Civic rank. Higher rank unlocks perks. Players spend spurs at the Civic Office NPC to upgrade. Powered by FTB Ranks under the hood (permission nodes drive what each rank unlocks).
| # | Title | Cost to reach | Wilderness chunks claimable | Spawn plot slots | Sethomes | Daily bounty slots | Shop fee | Chat colour | Join broadcast | `/back` after death |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | **Peasant** | free (starter) | 9 | 0 | 1 | 3 | -0% | grey | no | no |
| 2 | **Citizen** | 500 | 25 | 1 | 2 | 3 | -0% | white | no | no |
| 3 | **Patron** | 2,000 | 60 | 1 | 3 | 4 | -2% | yellow | no | yes |
| 4 | **Notable** | 6,000 | 100 | 2 | 4 | 4 | -5% | green | simple | yes |
| 5 | **Baron** | 15,000 | 160 | 2 | 5 | 5 | -8% | cyan | simple | yes |
| 6 | **Noble** | 35,000 | 240 | 3 | 7 | 5 | -10% | purple | fancy | yes |
| 7 | **Lord** | 80,000 | 350 | 4 | 10 | 6 | -12% | gold | fancy | yes |
| 8 | **Sovereign** | 200,000 | 500 | 5 | unlimited | 6 | -15% | red | epic | yes |
Numbers are first-pass calibration. The full perk table lives in a single JSON (`config/bnstoolkit/tiers.json`) that's hot-reloadable via `/bnstoolkit reload`. Easy to tune any column without code changes.
**Wilderness claims:** at every tier above Peasant, you get a flat allowance of N chunks you can claim anywhere outside spawn via the FTB Chunks map. Claiming is **free** within your allowance, refused above. No per-chunk pricing. Driven by FTB Ranks → FTB Chunks permission nodes (`ftbchunks.max_claimed_chunks`).
### 4b. Spawn plots
Spawn plots are a **separate system** from wilderness claims.
- **Pre-defined regions** at spawn — single chunks or small fixed clusters — designated by admins as "plots." Visible as fenced/bordered areas on the spawn map.
- **Purchased with spurs** at additional cost per plot (separate from tier upgrade cost). Indicative pricing: standard plot ~2,000 spurs, premium (corner / prime location) ~5,000 spurs.
- **Primary use:** shops. Players set up Numismatics shop blocks on their plots and sell to other players. Residence is allowed but secondary.
- **Slot-limited by tier:** your civic rank determines how many spawn plots you can own simultaneously (column above). Hit the limit, you can't buy another until you upgrade or release a plot.
- **Purchase happens inside the FTB Chunks map UI** — clicking a plot region in the map opens a confirmation screen (provided by our custom mod's mixin) showing cost + your remaining slots. Same UI you use for wilderness claims, integrated.
- **Plot data lives in the custom mod** (`bnstoolkit:plots`), not in FTB Chunks. Plots are a separate ownership system that uses the FTB Chunks map as its visual surface.
---
## 5. Quest & bounty flow (universal pattern)
**Core principle:** for any guild, the player **accepts** work from an NPC, **completes** it in the world, then **returns** to that NPC to **turn it in** and claim the reward. No instant payouts. This:
- Anchors guilds as destinations
- Creates risk/reward tension (die on the return, lose the reward)
- Encourages waypoint use and travel
- Lets the server centrally control payouts and detect cheating
### State machine
Each quest, per player, lives in one of these states:
```
AVAILABLE ─[player accepts]─► ACTIVE ─[objective met]─► READY ─[turned in]─► COMPLETED
▲ │
└──────────────────────[cooldown elapses]───────────────────────────────────────────┘
```
- **AVAILABLE** — NPC offers the quest in dialog. Player has no current copy of it.
- **ACTIVE** — Player accepted. KubeJS tracks objective progress via relevant events (`EntityEvents.death` for kills, `ItemEvents.firstRightClicked` for explorations, etc.).
- **READY** — Objective met. Reward is *promised but not yet paid.* NPC dialog now offers a turn-in option.
- **COMPLETED** — Reward paid out. Quest goes on cooldown for this player.
- **AVAILABLE** (again) — after the cooldown, the NPC will offer it again.
### Worked example — daily bounty
1. **Adventurer's Guild NPC** has 5 randomized daily quests (e.g. "Slay 10 Plunderers — 50 spurs").
2. Player right-clicks NPC → Easy NPC dialog → "Accept: Slay 10 Plunderers."
3. KubeJS writes `quest:plunderer_10` to the player's quest state with `count: 0`.
4. Player kills Plunderers in the world. `EntityEvents.death` for `supplementaries:plunderer` increments the count.
5. At count=10, KubeJS flips state to **READY** and notifies the player ("Return to the Adventurer's Guild to claim your reward.").
6. Player returns. Right-click NPC. Easy NPC dialog detects READY state and offers "Turn in: Slay 10 Plunderers."
7. KubeJS pays 50 spurs into the player's Numismatics wallet, flips state to **COMPLETED**, sets cooldown to 24h.
### Universal applicability
The same accept → complete → return pattern works for every guild:
| Guild | Accept | Complete | Return |
|---|---|---|---|
| **Adventurer's** | "Hunt 10 plunderers" | kill them | NPC pays bounty |
| **Merchant's** | "Procure 32 diamonds for our buyer" | gather them | NPC pays inflated price + completes |
| **Civic** | "Survey 5 unclaimed chunks" | walk through them | NPC pays survey fee |
| **Library** | "Recover this lost tome" | find the book in a structure | NPC pays + grants reputation |
| **Foundry** | "Craft 10 Andesite Casings" | craft them | NPC pays commission |
### Player-facing UI (locked)
Polished, integrated, no chat commands to memorise. All player interaction happens through GUIs and NPC dialogue. Custom companion mod (working name `bnstoolkit`) provides the screens; FTB Library's UI framework is the visual basis so our screens match FTB Quests, FTB Chunks, and FTB Teams natively.
| Surface | Implementation |
|---|---|
| **Quest Log screen** | Custom mod screen. Tabs: Active / Available / Completed. Click a quest to inspect, cancel from the detail panel. Opened via keybind or by clicking a Quest Log block at any guild. |
| **Bounty Board screen** | Custom mod screen, opened by right-clicking the Adventurer's Guild Quartermaster NPC OR clicking the in-world Bounty Board block. Lists today's available daily bounties with descriptions, rewards, and "Accept" buttons. |
| **Tier upgrade screen** | Custom mod screen, opened at the Civic Office NPC. Visual ladder, your current tier highlighted, next-tier cost, perks unlocked at each rank, big Upgrade button. |
| **Plot purchase popup** | Custom mod mixin into the FTB Chunks map UI. Hover a plot region → cost + slots tooltip. Click → confirmation popup. Owned plots also clickable to see plot info. |
| **Shop browser** | Numismatics shop blocks render their existing inventory UI by default; optional richer browser screen for the central Merchant's Bazaar inventory. |
| **Quest progress HUD** | Custom mod render layer — styled HUD element showing active quest names + progress bars. NOT stacked vanilla bossbars. |
| **NPC dialogue + buttons** | Easy NPC handles all NPC interactions: accept/turn-in, info, tutorials, "click for details" buttons. Players learn the system through NPC dialogue, not by reading docs. |
### Why custom mod, on FTB Library's UI framework
- **Visual consistency:** FTB Quests, FTB Chunks, FTB Teams all use FTB Library's widget framework. Our screens built on the same framework will look and feel like part of the same product.
- **Already a pack dependency:** no new mod added just for the UI layer.
- **Mixin compatibility:** our spawn plot mixin into the FTB Chunks map operates on FTB Library widgets natively — no translation layer between vanilla MC widgets and FTB Library widgets.
- **Less boilerplate than vanilla MC Screen API:** Panel, BlockButton, IconButton, Tooltip, TextField widgets already exist and behave consistently with how players already know FTB UIs to work.
- **Forking FTB is off the table:** FTB mods are "All Rights Reserved" — depending on FTB Library as a library is fine (that's what libraries are for), forking FTB Quests or FTB Chunks for redistribution is not legally clean. Custom mod alongside the FTB stack is the correct architecture.
### Why NOT FTB Quests for daily bounties
FTB Quests stays for **long-form progression** (Phase 5+), not for daily bounties. Source review confirms:
- No abandon/cancel event (Ctrl+Shift+R reset fires no event we can hook)
- Cooldown is per-team, not per-player
- Visibility is per-team, not per-player — rotating "5 of 20 daily" doesn't fit cleanly
For long-form progression where one-shot rewards + team scope are fine, FTB Quests is great. Our custom bounty engine handles the daily/repeatable pattern with its own UI.
### Quest slot limit
Players have a **maximum of 3 active quests at a time.** This is the friction that makes cancel meaningful:
- Forces players to pick which quests they actually want — no "accept all 5, see what's easiest, cancel the rest" RNG-shopping.
- Keeps the state files small.
- Makes ready-to-turn-in queues meaningful (you can hold 3 unrewarded quests in your back pocket).
A quest moving to READY frees the slot for accepting a new one even before turn-in.
### KubeJS implementation — locked specifics
- **State storage:** per-player JSON in `world/data/bns_quests/<uuid>.json`. Schema:
```json
{
"active": [
{
"id": "advg_plunderer_10",
"acceptedAt": 1717684800,
"progress": 7,
"target": 10,
"rewardSpurs": 50,
"source": "adventurers_guild",
"bossbarId": "bns:quest_advg_plunderer_10_<uuid>"
}
],
"completed": {
"advg_plunderer_10": { "cooldownUntil": 1717771200, "completions": 3 }
}
}
```
- **Event tracking:** KubeJS event handlers (`EntityEvents.death`, `ItemEvents.pickedUp`, `BlockEvents.broken`) read the player's active quests and increment progress + update bossbar value.
- **Bossbar lifecycle:** on quest accept, KubeJS creates a unique per-player bossbar via `server.runCommandSilent('bossbar add <id> <name>')`, assigns it to that player only, updates `value` and `max` on progress. On turn-in or cancel: `bossbar remove`.
- **Numismatics integration (direct Java access — no events shipped, no KubeJS bindings):**
```js
const Numismatics = Java.loadClass('dev.ithundxr.createnumismatics.Numismatics');
const ReasonHolder = Java.loadClass('dev.ithundxr.createnumismatics.content.backend.ReasonHolder');
const acct = Numismatics.BANK.getAccount(player); // ServerPlayer
const balance = acct.getBalance(); // int (spurs)
acct.deposit(50); // pay quest reward
const ok = acct.deduct(100, ReasonHolder.empty()); // returns false if broke
Numismatics.BANK.markBankDirty(); // force persistence
```
- **Dialog branching:** Easy NPC dialog branches on scoreboard objective `bns.quest.<npc_tag>` that KubeJS mirrors quest state into. Dialog `Command` action triggers `/bns_quest accept <id> <npc_tag>` which routes to KubeJS.
- **Commands:** registered via `ServerEvents.commandRegistry` in KubeJS. Scoped to the player who runs them. The custom `/bns_quest` namespace handles NPC-triggered actions; `/quests` is the player-facing tracker.
- **FTB Chunks claim cost (Phase 2):** requires `FTB XMod Compat` mod. Then:
```js
FTBChunksEvents.before('claim', event => {
const player = event.source.player;
const acct = Numismatics.BANK.getAccount(player);
const cost = computeClaimCost(player);
if (acct.getBalance() < cost) {
event.setResult(ClaimResult.YOU_DO_NOT_HAVE_ENOUGH_SPURS); // custom enum value
return;
}
acct.deduct(cost, ReasonHolder.empty());
});
```
**Note:** the `.before` may fire twice (sim + real). Guard with idempotent state, or do balance check in `.before` and deduct in `.after('claim')`.
---
## 5. Villager rebalance
**Decision:** move all villagers to **spurs** (not emeralds). Thematic consistency over preserving vanilla mental model.
**Decision principles:**
- Villagers are **net money sinks** — players spend more on villagers than they earn from them.
- **Useful trades stay** — enchanted books, tools, food, decorative blocks. Reasonable spur prices.
- **Trash trades get deleted** — no one ever wanted to sell rotten flesh or buy paper.
- **Sell-to-villager trades exist but are bad** — `64 wheat → 1 spur`, `16 leather → 1 spur`. Farms still possible, but ~10× slower than any other income source.
### Price guidance (initial calibration — tune via playtesting)
#### Buy-from-villager (player pays spurs)
| Item | Tier-1 | Tier-3 | Tier-5 |
|---|---|---|---|
| Standard enchanted book (random) | 50 spurs | 120 spurs | 250 spurs |
| Mending book | — | — | 800 spurs |
| Diamond tool (unenchanted) | — | 80 spurs | — |
| Diamond tool (enchanted) | — | — | 350 spurs |
| Bookshelf | 15 spurs | — | — |
#### Sell-to-villager (player gets spurs)
| Item | Spurs per unit |
|---|---|
| Wheat | 1 per 64 |
| Paper | 1 per 32 |
| Leather | 1 per 16 |
| Iron ingot | 2 per 1 |
| Diamond | 8 per 1 *(matches sell-shop fixed price — players use whichever is closer)* |
### Scope
~60 trades × 5 profession tiers = ~300 trade entries to redesign. One-time data-design pass, implemented via `ServerEvents.villagerTrades` in KubeJS.
---
## 6. Money inflow sources (detailed)
| Source | Cap / DR mechanism | Rough rate |
|---|---|---|
| **Daily bounties** | Per-player per-quest cooldown (24h) | ~200-500 spurs/day for an active player |
| **Sell shop (fixed price + DR)** | Lifetime sales tracker per player, 10% price drop per 64 sold | ~50-200 spurs/hr while diamond stockpile lasts |
| **Dynamic exchange** | Global supply pool — price drops with sales | Self-balancing |
| **First-time milestones** | One-shot per player (`hasFlag`) | 5-50 spurs per milestone, ~10 milestones total |
| **FTB Quest progression** | One-time per quest | Varies; cluster rewards at chapter completion |
| **Villager sell trades** | Inherently slow + bad prices | ~50 spurs/hr from a serious villager farm |
---
## 7. Money outflow sinks (detailed)
| Sink | Cost curve | Why this scales right |
|---|---|---|
| **Plot claims** | Free up to 9 chunks. 50 spurs/chunk to 25. 200 spurs/chunk beyond. | New players claim free starter areas; ambitious players pay real money |
| **Tier upgrades** | Cumulative cost: 500 → 2k → 8k → 30k spurs | Endgame sink, status display |
| **Buy-from-villager** | See §5 | Constant outflow as you build up |
| **Premium cosmetics** | 100-2k spurs each | Optional sink for cash-flush players |
| **Services** | Sethome: 50 spurs, warp: 25 spurs, /back: 10 spurs | Convenience taxes |
---
## 8. Mod stack (locked)
### Already in pack
| Need | Mod | Version |
|---|---|---|
| Currency + wallets + shop blocks | Numismatics | 1.0.20 |
| NPC dialog presentation | Easy NPC | 6.16.x (6.17.0 available, minor bump) |
| Plot claims | FTB Chunks | 2101.1.14 |
| Team management | FTB Teams | 2101.1.9 |
| Core library | FTB Library | 2101.1.31 |
| Cross-mod compat | Architectury API | 13.0.8 |
| Glue, commands, state | KubeJS | 2101.7.2 |
### Adding in Phase 0a (mod-additions PR — blocks everything else)
| Mod | Version | Reason |
|---|---|---|
| **FTB Quests** | 2101.1.25 | Progression quest UI (Phase 5+) |
| **FTB XMod Compat** | latest 1.21.1 NeoForge | KubeJS hooks for FTB Chunks claim events + FTB Quests events |
| **FTB Ranks** | 2101.1.3 | Tier system. CurseForge only, no Modrinth listing. |
### Building our own (custom companion mod)
**`bnstoolkit`** (working name) — a small companion mod in our own repo. Confirmed locked-in.
- Provides all custom GUI screens (Quest Log, Bounty Board, Tier upgrade, Shop browser)
- Provides the FTB Chunks map mixins (spawn plot cost overlay, hover tooltip, purchase popup)
- Provides custom quest-progress HUD render layer
- Provides the `bnstoolkit:plots` data storage + ownership permissions
- Provides network packets for client↔server state sync
- Provides the `/bnstoolkit reload` admin command for hot-reloading tier config
- Built on FTB Library UI framework for visual consistency
- KubeJS handles all gameplay logic (bounty rotation, state machine, villager trades, Numismatics integration) — the mod is purely the UI + integration layer
Estimated scope: ~2-3k LOC, single-developer week of focused work. Bounded.
### Explicitly NOT adding
- CustomNPCs (Easy NPC covers it)
- Citizens (Bukkit-only)
- PMMO / skill mods (out of scope)
- Generic "quest giver" mods (FTB Quests + our KubeJS bounty engine cover it)
---
## 9. Phasing
Each phase is independently shippable. Earlier phases unlock value without depending on later ones.
| Phase | Deliverable | Spawn build required? |
|---|---|---|
| **0a** | **Mod additions PR:** FTB Quests + FTB XMod Compat + FTB Ranks (+ minor Easy NPC bump). New pack version. | No |
| **0b** | Spawn skeleton — 7 guild building blockouts (rough). **User does in-game when time permits.** Non-blocking. | Yes (user) |
| **0c** | **`bnstoolkit` companion mod — scaffolding pass.** Mod project set up, FTB Library UI dependency wired, network packet plumbing, build/release scripts. No screens yet. | No |
| **1** | **Sell shop:** Numismatics shop blocks for diamonds (10 spurs) + netherite ingots (100 spurs). Lifetime-sale tracker for diminishing returns. KubeJS only, no mod work needed. | No |
| **2** | **Tier upgrade flow:** FTB Ranks integrated + KubeJS `/tier upgrade` command. **`bnstoolkit` Tier upgrade screen** wired to Civic Office NPC. Tier perks driven by `tiers.json`. | No |
| **3** | **Spawn plot system:** plot region registry in `bnstoolkit`, ownership tracking, FTB Chunks map mixin (cost overlay + purchase popup). | No |
| **4** | **Bounty engine:** state machine, KubeJS-rotated dailies, `bnstoolkit` Bounty Board screen + Quest Log screen + Quest progress HUD. NPC dialog hooks via Easy NPC. 3-slot cap. | No (NPC layer activates once spawn is built) |
| **5** | **Villager rebalance:** strip vanilla, ship spur-priced trade table via `ServerEvents.villagerTrades`. | No |
| **6** | **Progression quest line:** FTB Quests anchor + first chapter. KubeJS rewards dispense spurs via Numismatics API. | No (anchor NPC at Library once spawn exists) |
| **7** | **Dynamic exchange rates:** global supply-pool pricing for raw mats. | No |
| **8+** | Lootr dungeons, Foundry crafting commissions, deeper FTB Quests chapters, player-vs-player bounties (if wanted). | TBD |
---
## 10. Risk register
| Risk | Likelihood | Mitigation |
|---|---|---|
| Bounty engine bugs out, players lose progress | Medium | Atomic state writes; logs of every state transition |
| Villager farms still profitable after rebalance | Medium | Track player sell volumes; tune prices in patches |
| KubeJS-EasyNPC dialog branching has limits | Low-Med | Verify hooks in a test world before Phase 3; fall back to command-driven NPCs if needed |
| FTB Chunks `/claim` command override gotchas | Low | Test in dev world; FTB Chunks API is stable |
| Plot cost feels punishing | Med | First 9 chunks free is the safety valve; tune from playtest |
| Players bypass the system via creative / `/give` | Op-only | Document op responsibility; consider audit logs for op spur grants |
---
## 11. Decisions made
Resolved before implementation:
| Question | Decision |
|---|---|
| Quest UI for bounties | **Custom mod with FTB Library UI widgets** — proper GUI screens, no chat commands |
| Quest UI for progression | FTB Quests |
| Plot purchase UI | Custom mod mixin into FTB Chunks map — hover preview, click-to-buy popup |
| Tier upgrade UI | Custom mod screen at Civic Office NPC |
| State storage | KubeJS-managed per-player JSON for quest state; mod-managed for plot ownership |
| Numismatics access | Direct Java via `Java.loadClass` from KubeJS; via API directly from the mod |
| Wilderness chunk allowance | Tier-driven via FTB Ranks permission nodes — no per-chunk pricing |
| Spawn plots | Predefined regions, slot-limited by tier, individually purchased with spurs |
| Tier ladder | Civic: Peasant → Citizen → Patron → Notable → Baron → Noble → Lord → Sovereign (8 tiers) |
| Tier perks | JSON-configured (`config/bnstoolkit/tiers.json`), hot-reloadable |
| Custom mod | Confirmed. Built on FTB Library UI framework. Working name `bnstoolkit`. |
| Sethomes / warps | Tier-allocated count (not paid per use) |
| Daily quest count | Tier-driven (3 at Peasant, up to 6 at Sovereign), refresh per-player 24h after last accept |
| Emeralds | Retired as currency, retain as a trade material for villager-redirect trades |
| Fork FTB | Not needed — depend on FTB Library as a UI lib, FTB Chunks/Quests stay unmodified, integration via mixins + KubeJS hooks |
### Still to decide (non-blocking — pick during implementation)
- **PvP bounties** — out of scope for V1, revisit after V1 ships
- **Lootr** — add only when structured dungeons exist (Phase 8+)
- **Default-rank starting permissions** — finalised when FTB Ranks config is written
- **Spawn plot pricing** — first-pass numbers (2,000 standard / 5,000 premium), tune in playtest
---
## 12. Implementation notes
### KubeJS scripts (gameplay logic)
Organised under `pack/overrides/kubejs/server_scripts/economy/`:
- `01_numismatics_api.js` — Java.loadClass wrapper helpers (balance / deposit / deduct)
- `02_quest_state.js` — load/save `world/data/bns_economy/quests/<uuid>.json`
- `03_commands.js` — admin commands (`/tier upgrade`, `/bnstoolkit reload`, debug)
- `04_bounty_engine.js` — daily rotation, state machine, KubeJS↔mod packet handlers
- `05_sell_shop.js` — Numismatics shop tracking + diminishing returns
- `06_villager_trades.js` — Phase 5 `ServerEvents.villagerTrades` rebalance
- `07_tier_perks.js` — FTB Ranks promote/demote, perk application
- `99_dynamic_exchange.js` — Phase 7 supply-priced market
### Custom mod codebase
Repo: separate (or sub-tree of main repo, TBD).
Modid: `bnstoolkit` (working name).
Package layout:
```
bnstoolkit/
├── client/
│ ├── screen/ QuestLog, BountyBoard, Shop, Tier, PlotConfirm (FTB Library subclasses)
│ ├── mixin/ ChunkScreenPanel (cost overlay + plot button), ChunkButton (hover tooltip)
│ ├── hud/ QuestProgressHud (custom render)
│ └── ClientEvents keybind reg, screen reg, mixin loader
├── server/
│ ├── packet/ OpenScreen, UpgradeRank, BuyPlot, ClaimBounty, etc.
│ ├── command/ /bnstoolkit reload (config refresh)
│ └── data/ PlotRegistry, PlotOwnership (saved with world data)
├── common/
│ ├── data/ TierConfig (JSON-loaded), BountyDefinition, QuestState mirror
│ └── BnsToolkit.java mod entry
└── config-defaults/
├── tiers.json copied to config/bnstoolkit/tiers.json on first run
└── plots.json spawn plot region definitions
```
Architecture doc (`docs/bnstoolkit-architecture.md`) covers package layout, screen UX sketches, network packet contract, mixin targets, KubeJS↔mod integration surface — to be written before mod work begins.
### State data
- Quest state: `world/data/bns_economy/quests/<uuid>.json`. Readable JSON, easy to debug.
- Plot ownership: persisted with world via the mod's `SavedData` (vanilla NeoForge persistence). Authoritative source of truth.
- Tier config: `config/bnstoolkit/tiers.json` shipped from `pack/overrides/defaultconfigs/bnstoolkit/tiers.json`. Hot-reloadable.
- Plot definitions: `config/bnstoolkit/plots.json` shipped similarly. Defines plot region bounds, type (standard/premium), prices.
### NPC dialog
Authored in Easy NPC's in-game editor, exported as preset JSONs into `pack/overrides/world/datapacks/bns-fuel/data/easy_npc/`. Dialog `Command` actions call `/bnstoolkit <verb> ...` which routes to either the mod (for screen-opening) or KubeJS (for state changes).
### Villager rebalance
Single source file `06_villager_trades.js`. Each profession × tier has its own block. One file = one diff per balance pass.
---
## See also
- `MEMORY.md` entries:
- `project-mc-player-economy.md` — earlier higher-level notes on Numismatics + plot system
- `feedback-kubejs-rhino-gotchas.md` — KubeJS scripting constraints
- `feedback-bns-pack-version-sync.md` — pack version + sync workflow
- Existing tasks #20-#26 — to be reshuffled to mirror the phase plan above