added more documentation

This commit is contained in:
DeSqBlocki
2026-09-13 22:10:34 +02:00
parent dd4d6e4817
commit 6e3e1620d1
7 changed files with 1020 additions and 669 deletions
+185
View File
@@ -0,0 +1,185 @@
# ShaiBot Architecture
This manual describes ShaiBot's implementation structure at a level
useful to maintainers. For exact behavior, the current code remains
authoritative.
## Runtime
`index.js` initializes the Discord client and MongoDB connection,
creates the interaction collections, initializes shared systems/indexes,
loads handlers, and logs the bot in.
Interaction modules are discovered into collections such as:
``` js
client.commands
client.legacyCommands
client.aliases
client.buttons
client.selectMenus
client.modals
```
Before manually wiring a new component into the central router, check
whether the filesystem loader already supports it.
## Preferred Layering
ShaiBot favors:
``` text
Discord command / button / select menu
↓
shared utility
↓
Mongo / economy / profile
```
Discord wrappers should remain thin. Shared rules belong in `utils/`.
A feature reachable from multiple interfaces should normally have one
authoritative implementation.
## Important Shared Utilities
Examples include:
-----------------------------------------------------------------------
Utility Responsibility
----------------------------------- -----------------------------------
`cookieEconomy.js` Cookie balances, transfers,
cooldowns, economy primitives
`crumbCollect.js` Shared Cookie collection
`crumbSlots.js` Slots
`crumbBlackjack.js` Blackjack
`crumbRoulette.js` Roulette
`cookieHeist.js` Vault Heist
`bankruptcy.js` Bankruptcy/recovery
`profileSystem.js` Profiles, achievements, badges,
activity
`profileMaintenance.js` Profile audit/reconciliation
`interactionSession.js` Shared single-owner interaction
sessions
`permissions.js` Administrator/bot-author checks
`pokerEngine.js` Pure Hold'em engine
`crumbPoker.js` Persistent Poker service
`pokerDiscord.js` Poker Discord rendering/components
`pokerProfile.js` Poker progression bridge
`crumbleStrike.js` Cooperative encounter state/combat
-----------------------------------------------------------------------
## MongoDB
Important collections include:
``` text
items_cookies
cooldown_cookies
items_games
items_special_games
stats_profiles
items_achievements
guild_badges
config_achievements
```
Indexes are part of correctness, not only performance.
ShaiBot intentionally avoids requiring multi-document MongoDB
transactions. Depending on the subsystem it instead uses:
- Atomic filtered updates
- Unique indexes
- Optimistic version checks
- Idempotency markers
- Persistent resolution state
- Compensating writes
## Concurrency
Assume users can double-click, spam controls, act simultaneously, race a
timeout, or restart the bot during a transition.
Stateful systems should answer:
``` text
What is authoritative?
Can two interactions both succeed?
Can money move twice?
What happens if the process stops after the first write?
Can the operation safely be retried?
```
Do not rely on process-local flags for correctness that must survive a
restart.
## Discord Interactions
Button visibility is never authorization.
For potentially slow stateful interactions, acknowledge Discord early
using the response style appropriate to that flow.
Do not globally defer every interaction from the central router because
different modules legitimately use `reply`, `update`, `deferReply`, or
`deferUpdate`.
Critical state should not exist only in an embed/footer.
## Permissions
Administrative access is centralized through the shared permission
utility.
Administrative access may include:
``` text
Discord Administrator
OR
BOT_AUTHOR_ID
```
Do not hard-code administrative Discord IDs.
## Deployment
Typical production workflow:
``` bash
node --check path/to/changed-file.js
pm2 restart ShaiBot
pm2 logs ShaiBot --lines 100
```
Syntax checking is useful, but economy and persistent-state changes
still require behavioral testing.
## Maintainer Checklist
Before shipping a stateful change:
- Identify the authoritative state.
- Check duplicate-click behavior.
- Check simultaneous-user behavior.
- Check insufficient-balance behavior.
- Check restart/recovery behavior.
- Check private/public information boundaries.
- Check whether profile tracking can safely fail without corrupting
settlement.
- Inspect Mongo after a controlled live test.
+168
View File
@@ -0,0 +1,168 @@
# ShaiBot Cookie Economy
This manual describes the shared Cookie economy and the rules
maintainers should preserve.
## Source of Truth
`utils/cookieEconomy.js` is the shared economy utility.
Game and command modules should not perform independent ad-hoc balance
mutations when the shared economy already provides the required
operation.
## Balances
Cookie balances live in:
``` text
items_cookies
```
Conceptually:
``` js
{
userId: "...",
cookies: 2500
}
```
Negative changes use an atomic balance filter so a player cannot spend
more Cookies than are available.
Expected insufficient-balance failures use:
``` text
INSUFFICIENT_COOKIES
```
Some subsystems carry expected error identifiers in `error.message`,
while others may also use `error.code`. User-facing formatters should
account for the convention used by that subsystem.
## Transfers
Player-to-player transfers do not require MongoDB transactions.
The safe conceptual sequence is:
``` text
atomic debit source
→ credit destination
→ compensate source if destination credit fails
```
A critical compensation failure must remain visible in logs.
## Cooldowns
Cooldowns live in:
``` text
cooldown_cookies
```
Use the shared cooldown helpers, especially atomic cooldown claiming
when double-clicks or simultaneous requests must not both succeed.
## House Vault
ShaiBot acts as the general house Cookie vault for supported games.
Gambling losses and penalties may feed the vault, while wins, heists,
and rewards may pay out from it.
House-funded features should respect their existing liquidity rules.
## Cookie Collection
`/cookies collect` and the Crumb Saucer Bakery share
`utils/crumbCollect.js`.
They must share:
- the same cooldown
- the same reward generation
- the same balance mutation
- the same profile tracking
Do not create separate collection behavior for the two interfaces.
## PvP Stealing
Normal player-to-player stealing is separate from Vault Heist.
Detailed robbery balancing lives in:
``` text
COOKIE_LOGIC.md
```
The current model includes wealth scaling, victim heat, percentage-based
loot, a hard per-hit cap, and an hourly victim exposure budget.
## Persistent Game Settlement
For simple house games, settlement should still be protected against
repeated resolution.
For lifecycle-heavy multiplayer games such as Poker, Cookie movement is
separated from internal chip movement.
Poker only crosses the Cookie economy boundary for:
``` text
buy-in
cash-out / refund
```
Ordinary Poker betting modifies the table's internal stack state, not
`items_cookies`.
## Idempotent Operations
Recovery-sensitive economy flows can use operation IDs.
Poker temporarily stores markers such as:
``` js
appliedCookieOperations: [
"poker_buyin:...",
"poker_cashout:..."
]
```
The purpose is to prevent a retry after a crash from moving money twice.
Safe lifecycle:
``` text
apply Cookie operation once
→ persist authoritative game state
→ confirm operation is durably represented
→ remove temporary marker
```
Never remove a recovery marker before the surrounding state is safe.
When the final marker is removed, unset the empty field instead of
leaving:
``` js
appliedCookieOperations: []
```
## Economy Invariants
Every economy change should preserve:
``` text
No Cookie duplication.
No unexplained Cookie loss.
No duplicate debit.
No duplicate payout.
No spending below zero.
```
Correctness and recoverability take priority over cosmetic cleanup.
+262
View File
@@ -0,0 +1,262 @@
# ShaiBot Game Manual
This document gives maintainers a compact overview of the main game
systems. Exact rules remain in the owning utilities.
# Crumb Saucer
The Crumb Saucer is ShaiBot's Cookie-powered game hub.
Shared principle:
``` text
Discord controls
→ game utility
→ Cookie economy / profile system
```
## Slots
Core utility:
``` text
utils/crumbSlots.js
```
Features include multiple wagers, symbol payouts, jackpots, All-In
tracking, Run It Back, profile statistics, achievements, and guild-first
triplet badges.
Historical replay facts must come from wager-time metadata rather than
the player's current Cookie balance.
## Blackjack
Core utility:
``` text
utils/crumbBlackjack.js
```
Supports:
- Hit
- Stand
- Double
- Dealer stands on 17
- Natural Blackjack pays 3:2
- Push
- All-In
- Run It Back
Repeated interactions must never resolve/pay the same hand twice.
## Roulette
Core utility:
``` text
utils/crumbRoulette.js
```
European Roulette uses `0–36`.
Simple bets include Red, Black, Odd, Even, and Zero. Zero loses for
Red/Black/Odd/Even.
Animation uses edits of the same message rather than high-frequency
message spam.
## Vault Heist
Core utility:
``` text
utils/cookieHeist.js
```
Vault Heist targets ShaiBot's house vault and is separate from PvP
stealing.
Approaches include Sneak, Hack, and Smash and share the same Heist
cooldown.
## Bankruptcy
Core utility:
``` text
utils/bankruptcy.js
```
Bankruptcy provides a recovery path and tracks post-Bankruptcy
rebuilding in profiles.
Recovery progress should reflect actual balance after Bankruptcy, not
merely lifetime Cookie gains.
## Run It Back
Supported games can track consecutive replay through the explicit Run It
Back action.
A normal/new wager breaks the chain.
Win/loss/push does not inherently break it because the streak represents
the player's decision to immediately replay.
Historical All-In and wager state must be preserved at the time the
wager occurs.
# Poker
Poker is a persistent 2--6 player Texas Hold'em game inside the Crumb
Saucer.
Important files:
``` text
utils/pokerEngine.js
utils/crumbPoker.js
utils/pokerDiscord.js
utils/pokerInteractions.js
utils/pokerProfile.js
handlers/poker.js
buttons/poker/*
selectMenus/poker/*
```
Current defaults:
``` text
Buy-in: 1,000 Cookies
Blinds: 10 / 20
Turn timer: 90 seconds
Pot model: single pot
```
Supported actions:
``` text
Fold
Check
Call
Bet
Raise
All-In
```
## Single-Pot Rule
Poker intentionally has no side pots.
At hand start, the maximum amount each participant can commit is limited
by the smallest participating starting stack.
Chips above that cap remain protected for a later hand.
## Persistence
MongoDB is authoritative for live/recoverable tables.
Poker uses temporary state in:
``` text
items_special_games
```
and optimistic versioning for authoritative updates.
Fully settled games are cleaned up rather than kept permanently as raw
history.
## Economy
Cookies move only at buy-in and cash-out/refund boundaries.
Betting moves internal table chips.
Recovery-sensitive economy operations are idempotent.
## Privacy
Hole cards are private.
The private Cards view may show the requesting player's cards, community
cards, turn status, and remaining turn time.
It must never expose opponent cards.
A player-facing equity/win-percentage calculator is intentionally
excluded from V1 for fairness.
## Turn / Lobby Behavior
Active turns have a 90-second deadline.
Timeout folding uses the same authoritative Fold transition as a normal
player action.
Lobby expiry is disabled while a hand is active and refreshed when a
hand ends.
The internal between-hand state may be called `NEXT_HAND`, but the
user-facing UI presents **HAND COMPLETE**.
## Cancellation / Cleanup
Host cancellation is allowed outside an active hand.
Cancellation safely settles players before deleting the table state.
Confirmation controls should disappear after Confirm or Keep so stale
buttons cannot remain usable.
# Crumble Strike
Core utility:
``` text
utils/crumbleStrike.js
```
Crumble Strike is a persistent cooperative boss battle.
Typical flow:
1. Spawn encounter.
2. Recruit players.
3. Start once requirements are met.
4. Fight within the encounter lifetime.
5. Settle success/failure and committed Cookies.
Combat includes:
``` text
Strike
Defend
Heal
Revive
Limit Break
```
Roles include:
``` text
DPS
Tank
Healer
```
Crumble Strike has more lifecycle complexity than ordinary Saucer games.
Do not copy its persistence model into simpler games unless the new
feature genuinely requires it.
# Raid Planner
Raid planning uses Discord embeds and reactions.
Participation can count unique users across reactions without forcibly
removing reactions.
Be mindful of Discord partials when changing reaction behavior.
+200
View File
@@ -0,0 +1,200 @@
# ShaiBot Profiles, Achievements & Badges
ShaiBot's profile system is the permanent progression layer behind the
economy and games.
## Central Profile System
`utils/profileSystem.js` owns the main profile/progression behavior.
Important collections:
``` text
stats_profiles
items_achievements
guild_badges
config_achievements
```
Game modules should integrate with this system instead of creating
separate progression databases.
## Profiles
Profiles can track:
- Overall game totals
- Per-game statistics
- Cookie gains and losses
- Giving and stealing
- Daily activity
- Win/loss streaks
- Weekday/time-of-day activity
- Social relationships
- Run It Back progression
- Poker history
- Achievement progress
- Badge ownership
Profiles are intended to preserve meaningful long-term history.
## Profile Events
Prefer extending established event metadata rather than inventing
parallel event systems.
Common concepts include:
``` text
game_start
game_result
cookie_gain
cookies_given
steal_success
stolen_from_me
```
New wager metadata should prefer:
``` text
wager
```
Compatibility reads for older `bet`/`previousBet` fields may remain
intentionally.
## Activity
Profile activity uses a configured timezone.
Default:
``` text
Europe/Berlin
```
Activity supports daily streaks, weekly participation, weekday counts,
and broad time buckets.
Avoid making ordinary progression depend on excessively narrow
late-night windows.
## Social Progression
Profiles can store unique relationship sets for gifting and stealing.
Use set-style updates for unique users rather than appending duplicates.
Current social progression is intentionally scaled for a relatively
small community.
## Achievements
Achievements are personal: multiple players can earn the same
achievement.
Supported models include:
### Stat-backed
Best for durable lifetime milestones and reconciliation.
### Composite
Combines multiple durable conditions.
### Event-only
Used when the accomplishment depends on exact event context that cannot
reliably be reconstructed later.
### Hidden
Used for secret/special challenges.
Event-only achievements should not be treated as historically
backfillable when the necessary event was never stored.
## Achievement Notifications
Unlock notification is centralized.
Individual games should not create competing achievement announcement
systems.
## Global Badges
Global badges are guild-unique distinctions.
The common pattern is an atomic claim against an unowned badge:
``` text
guildId
badgeId
ownerId: null
```
then setting the winner.
This prevents simultaneous candidates from both owning the same
guild-first badge.
Achievements and badges are intentionally different:
``` text
Achievement → personal; many owners
Global badge → guild-unique; one owner
```
## ID Stability
Once achievement or badge IDs may exist in MongoDB, treat them as
persistent database identifiers.
Prefer retiring an old definition over renaming/deleting an ID that
players may already own.
## Reconciliation & Audit
Administrative tooling includes:
``` text
/profileadmin audit
/profileadmin reconcile dry-run:true
```
Reconciliation can backfill durable/stat-backed accomplishments.
Event-only achievements may be skipped because historical event context
cannot be invented safely.
When changing progression schemas:
- use idempotent migrations
- preserve existing values
- preserve historical IDs
- dry-run reconciliation first
- do not fabricate data that was never tracked
## Poker History
Poker stores permanent statistics in the profile system rather than
retaining completed raw table documents.
Examples include:
- hands played/won/lost
- Cookies won/lost
- largest pot
- All-Ins
- showdowns
- action counts
- streaks
- hand-rank counters
- pocket Aces wins
- 7-2 wins
- fold wins
- full-table wins
Poker profile tracking occurs after authoritative game state succeeds. A
profile failure must never corrupt a valid pot/economy settlement.