Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
0ad43ed
Add temporary source snapshot workflow
remdui Aug 6, 2026
76fcd31
Add economy patch chunk 00
remdui Aug 6, 2026
0c174be
Add economy patch chunk 01
remdui Aug 6, 2026
30e841d
Add economy patch chunk 02
remdui Aug 6, 2026
e619feb
Add economy patch chunk 03
remdui Aug 6, 2026
22354be
Add economy patch chunk 04
remdui Aug 6, 2026
a442be9
Add economy patch chunk 05
remdui Aug 6, 2026
2576de1
Add economy patch chunk 06
remdui Aug 6, 2026
5ffe675
Add economy patch chunk 07
remdui Aug 6, 2026
5e7b048
Add economy patch chunk 08
remdui Aug 6, 2026
316336f
Add economy patch chunk 09
remdui Aug 6, 2026
41b38b0
Add final economy patch chunk
remdui Aug 6, 2026
fb06621
Apply advanced economy implementation
remdui Aug 6, 2026
a688144
Run economy implementation apply job
remdui Aug 6, 2026
49c609d
Diagnose economy payload integrity
remdui Aug 6, 2026
fb2812c
Add corrected economy patch segment 08a
remdui Aug 6, 2026
8e86366
Add corrected economy patch segment 08b
remdui Aug 6, 2026
8e2b6b2
Remove corrupted economy patch segment
remdui Aug 6, 2026
51e418c
Implement advanced multi-currency economy
github-actions[bot] Aug 6, 2026
bf579e8
Apply advanced economy implementation
remdui Aug 6, 2026
2a05ed7
Remove temporary economy apply workflow
remdui Aug 6, 2026
6eb2af2
Apply economy CI fixes
remdui Aug 6, 2026
e349d4f
Fix economy compilation and lint
github-actions[bot] Aug 6, 2026
e99443c
Document economy failure behavior
remdui Aug 6, 2026
9c177c1
Apply economy review hardening
remdui Aug 6, 2026
2ec82d6
Run verified economy review fixes
remdui Aug 6, 2026
6ffd81f
Harden economy transaction semantics
github-actions[bot] Aug 6, 2026
4db1e8f
Extend economy transaction semantics tests
remdui Aug 6, 2026
dd96d95
Stage Vault isolation fix payload
remdui Aug 6, 2026
cd0b1a6
Apply verified Vault isolation fix
remdui Aug 6, 2026
7f74827
Keep Vault integration truly optional
github-actions[bot] Aug 6, 2026
14d91a1
Verify Vault remains optional at class load
remdui Aug 6, 2026
1ba6244
Stage final Economy hardening payload
remdui Aug 6, 2026
ace7a8f
Apply final Economy hardening
remdui Aug 6, 2026
2b6ae44
Harden economy command and identifier validation
github-actions[bot] Aug 6, 2026
cc5f16a
Test Economy identifier boundaries
remdui Aug 6, 2026
cbb928a
Temporarily export PR source for economy review
remdui Aug 6, 2026
0a5822e
Stage economy hardening payload 1/6
remdui Aug 6, 2026
471ee55
Stage economy hardening payload 2/6
remdui Aug 6, 2026
f66f496
Stage economy hardening payload 3/6
remdui Aug 6, 2026
36ddbaa
Stage economy hardening payload 4/6
remdui Aug 6, 2026
c8f91b6
Stage economy hardening payload 5/6
remdui Aug 6, 2026
b6b0aff
Stage economy hardening payload 6/6
remdui Aug 6, 2026
885245e
Apply checksum-verified economy hardening
remdui Aug 6, 2026
fe693d0
Harden economy network integrity
github-actions[bot] Aug 6, 2026
ed88dfe
Document economy network deployment validation
remdui Aug 6, 2026
d45d9f9
Stage Economy compiler warning fix
remdui Aug 6, 2026
447d4a9
Apply Economy compiler fix
remdui Aug 6, 2026
fa2cd39
Fix Economy Java 25 warning
github-actions[bot] Aug 6, 2026
fe96434
Require uniform Economy build across the network
remdui Aug 6, 2026
0a9e505
Test Economy cross-server message contracts
remdui Aug 6, 2026
2b47902
Test Economy integrity model invariants
remdui Aug 6, 2026
3836883
Stage Economy configuration test fix
remdui Aug 6, 2026
7b2c862
Apply Economy configuration test fix
remdui Aug 6, 2026
6c799b8
Fix Economy configuration test setup
github-actions[bot] Aug 6, 2026
8fd34e5
Clarify logical gamemode scope configuration
remdui Aug 6, 2026
6c2c446
Stage Economy code-quality fixes
remdui Aug 6, 2026
5ff0d42
Apply Economy code-quality review fixes
remdui Aug 6, 2026
1f224f9
Address Economy code-quality review
github-actions[bot] Aug 6, 2026
e442d36
Document final Economy quality invariants
remdui Aug 6, 2026
d15e0ad
Simplify immutable Economy history accessor
remdui Aug 6, 2026
fa5e1ec
Add HauntedMC Economy topology example
remdui Aug 6, 2026
ad5db54
Make Economy history page explicitly immutable
remdui Aug 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/features/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ This directory documents all **64** feature modules currently present in ServerF
- [VillagerOptimizer](villageroptimizer.md) — Reduces villager processing cost by applying configurable optimization rules without changing intended gameplay more than necessary.
- [WorldEditVisualizer](worldeditvisualizer.md) — Visualizes WorldEdit selections for authorized builders with temporary particles or display markers.
- [Graveyard](graveyard.md) — Stores death contents durably and renders claimable packet-only graves with active-server-time expiry and crash recovery.
- [Economy](economy.md)
- [Lottery](lottery.md) — Runs scheduled ticket-based draws with donations, offline payouts, history, leaderboards, and a small staff command set.

## Moderation and administration
Expand Down
49 changes: 49 additions & 0 deletions docs/features/economy-deployment-checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Economy network deployment checklist

Use this checklist before enabling Economy on a production HauntedMC network.

## Required shared infrastructure

- Every Paper instance must use the same authoritative MySQL database for shared/global currencies.
- Redis messaging should use the same configured connection and channel on all participating instances. Redis is an invalidation and notification transport only; MySQL remains authoritative.
- DataRegistry must resolve the same immutable player ID and UUID pair on every instance.
- Every participating instance must run the same ServerFeatures build. Do not operate mixed Economy schema or messaging versions during rollout.

## Stable scope keys

- Give every logical gamemode one permanent local key, such as `survival`, `skyblock`, or `kitpvp`.
- Set the top-level `server_key`, `gamemode_key`, or `local_key` to that logical gamemode key. A per-currency `scope.local_key` may override it when replicas need an explicitly shared local scope.
- Physical replicas of one gamemode must use the same logical local key when they should share gamemode-local balances.
- Do not rename a logical key after accounts exist. A different key intentionally selects a different account scope.
- Configure Crowns and Credits as `GLOBAL` on every participating gamemode.
- Configure Essence, Relics, Soulstones, and Money as gamemode-local `SERVER` currencies.
- Expose only gamemode-local Money as the Vault primary currency on each Paper server.

## Configuration consistency

- Keep precision, starting balance, bounds, negative-balance policy, rounding, payment limits, cooldown, and payment-default settings identical for every server sharing a currency account scope.
- Keep each currency ID in one scope family across the network. For example, `crowns` must not be global on one gamemode and local on another.
- Startup must remain blocked when the persisted currency-family or scope definition conflicts with configuration. Do not bypass these guards.

## Rollout

1. Back up the economy database.
2. Deploy the same plugin build to every participating Paper instance.
3. Enable and validate one non-production gamemode first.
4. Run `/economy status`, `/economy currencies`, and `/economy verify`.
5. Test one local Money transfer between physical replicas of the same gamemode.
6. Test one local currency transaction while the recipient is online on another gamemode; only the originating gamemode account should change.
7. Test one global Crowns or Credits payment while the recipient is online on another gamemode; both servers should converge on the same committed MySQL balance.
8. Repeat the global test with Redis temporarily unavailable. The transaction must still commit safely and the remote display must heal through authoritative refresh after messaging returns or the refresh interval elapses.
9. Retry one native mutation with the same source and idempotency key. It must replay the original operation without changing the balance twice.
10. Retry the same key with a different amount or recipient. It must return an idempotency conflict and apply nothing.
11. Confirm Vault reports the correct gamemode-local Money balance and cannot expose Crowns, Credits, or other named currencies.
12. Enable the remaining gamemodes only after all checks pass.

## Operational rules

- Never repair balances by editing cache or Redis data.
- Never change balances outside `EconomyApi`, the Economy administration commands, or the registered Vault provider.
- Preserve operation IDs, sources, and idempotency keys in logs for every high-value integration.
- Keep financial data models immutable at API boundaries and retain null-safe failure handling in every compensation path.
- Treat `/economy verify` findings, identity conflicts, currency-definition conflicts, or repeated temporary database failures as release-blocking incidents.
237 changes: 237 additions & 0 deletions docs/features/economy-hauntedmc-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# Example Economy feature configuration for one HauntedMC gamemode.
# Change server_key per logical gamemode (survival, skyblock, kitpvp, ...).
# Physical replicas of the same gamemode must use the same server_key.

enabled: true
network_key: hauntedmc
server_key: survival

database:
connection: system_data_rw

messaging:
enabled: true
connection: hauntedmc
channel: serverfeatures.economy.balance

vault:
enabled: true
primary_currency: money
conflict_policy: FAIL

currencies:
crowns:
enabled: true
scope:
type: GLOBAL
display:
singular: Crown
plural: Crowns
symbol: "♛"
format: "{amount} {plural}"
fractional_digits: 0
grouping: true
balances:
starting: "0"
minimum: "0"
maximum: "999999999999999999999999999999"
allow_negative: false
rounding: UNNECESSARY
commands:
root: crowns
aliases: [crown]
balance: true
balance_others: true
pay: true
paytoggle: true
history: true
top: true
payments:
default_enabled: true
allow_offline_recipient: true
minimum: "1"
maximum: "1000000"
confirmation_threshold: "10000"
daily_send_limit: "0"
daily_receive_limit: "0"
cooldown: 1s

credits:
enabled: true
scope:
type: GLOBAL
display:
singular: Credit
plural: Credits
symbol: "✦"
format: "{amount} {plural}"
fractional_digits: 0
grouping: true
balances:
starting: "0"
minimum: "0"
maximum: "999999999999999999999999999999"
allow_negative: false
rounding: UNNECESSARY
commands:
root: credits
aliases: [credit]
balance: true
balance_others: true
pay: true
paytoggle: true
history: true
top: true
payments:
default_enabled: true
allow_offline_recipient: true
minimum: "1"
maximum: "1000000"
confirmation_threshold: "10000"
daily_send_limit: "0"
daily_receive_limit: "0"
cooldown: 1s

essence:
enabled: true
scope:
type: SERVER
display:
singular: Essence
plural: Essence
symbol: "✧"
format: "{amount} {plural}"
fractional_digits: 0
grouping: true
balances:
starting: "0"
minimum: "0"
maximum: "999999999999999999999999999999"
allow_negative: false
rounding: UNNECESSARY
commands:
root: essence
aliases: []
balance: true
balance_others: true
pay: true
paytoggle: true
history: true
top: true
payments:
default_enabled: true
allow_offline_recipient: true
minimum: "1"
maximum: "0"
confirmation_threshold: "0"
daily_send_limit: "0"
daily_receive_limit: "0"
cooldown: 1s

relics:
enabled: true
scope:
type: SERVER
display:
singular: Relic
plural: Relics
symbol: "◆"
format: "{amount} {plural}"
fractional_digits: 0
grouping: true
balances:
starting: "0"
minimum: "0"
maximum: "999999999999999999999999999999"
allow_negative: false
rounding: UNNECESSARY
commands:
root: relics
aliases: [relic]
balance: true
balance_others: true
pay: true
paytoggle: true
history: true
top: true
payments:
default_enabled: true
allow_offline_recipient: true
minimum: "1"
maximum: "0"
confirmation_threshold: "0"
daily_send_limit: "0"
daily_receive_limit: "0"
cooldown: 1s

soulstones:
enabled: true
scope:
type: SERVER
display:
singular: Soulstone
plural: Soulstones
symbol: "◈"
format: "{amount} {plural}"
fractional_digits: 0
grouping: true
balances:
starting: "0"
minimum: "0"
maximum: "999999999999999999999999999999"
allow_negative: false
rounding: UNNECESSARY
commands:
root: soulstones
aliases: [soulstone]
balance: true
balance_others: true
pay: true
paytoggle: true
history: true
top: true
payments:
default_enabled: true
allow_offline_recipient: true
minimum: "1"
maximum: "0"
confirmation_threshold: "0"
daily_send_limit: "0"
daily_receive_limit: "0"
cooldown: 1s

money:
enabled: true
scope:
type: SERVER
display:
singular: Coin
plural: Coins
symbol: "$"
format: "{symbol}{amount}"
fractional_digits: 2
grouping: true
balances:
starting: "0.00"
minimum: "0.00"
maximum: "999999999999999999999999999999.99999999"
allow_negative: false
rounding: HALF_UP
commands:
root: money
aliases: [balance, bal]
balance: true
balance_others: true
pay: true
paytoggle: true
history: true
top: true
payments:
default_enabled: true
allow_offline_recipient: true
minimum: "0.01"
maximum: "0.00"
confirmation_threshold: "100000.00"
daily_send_limit: "0.00"
daily_receive_limit: "0.00"
cooldown: 1s
Loading
Loading