1 Architecture
1.1 Package overview
degen-llms/
├── mandalay_bay/ # Resort hub & economy
│ ├── main.py # CLI entry, session bootstrap
│ ├── hub.py # Lobby navigation
│ ├── chips.py # ChipWallet & ledger
│ ├── session.py # PlayerSession & stats
│ ├── hotel.py # Hotel state, hallway, checkout lifecycle
│ ├── hotel_experience.py
│ ├── room_amenities.py # In-room TV, minibar, phone, events
│ ├── pool_complex.py # 11-acre pool zones & events
│ ├── resort_bridge.py # Cross-system event requirements
│ ├── resort_completion.py
│ ├── casino_amenities.py
│ ├── rewards.py / rewards_perks.py
│ ├── craps.py / lottery.py / prediction_markets.py / trading_desk.py
│ └── activities/
│ ├── base.py # Activity ABC
│ ├── registry.py # Activity catalog
│ ├── blackjack.py / holdem.py / roulette.py / craps.py
│ ├── slots.py / lottery.py / sportsbook.py / trading_desk.py
│ └── horse_racing.py / equestrian.py
├── blackjack/ # Blackjack engine
│ ├── table.py # Round orchestration
│ ├── cards.py # Shoe & dealing
│ ├── rules.py # Action legality
│ ├── runner.py # Casino wallet integration
│ └── ...
├── docs/ # Documentation & web terminal (GitHub Pages)
│ ├── js/
│ │ ├── core.js # PlayerSession, ChipWallet, save versioning
│ │ ├── hotel.js / hotel-ui.js
│ │ ├── room-amenities.js
│ │ ├── pool-complex.js
│ │ ├── resort-bridge.js / resort-completion.js
│ │ ├── casino-amenities.js
│ │ ├── world-cycle.js # The single resort clock
│ │ └── ui/ # buildXRenderers(ctx) screen factories
│ │ ├── shell.js # el, banner, chipLine, statusBanner, view stack
│ │ ├── slots-renderers.js / table-renderers.js
│ │ ├── sportsbook-renderers.js / racing-renderers.js
│ │ ├── cashier-renderers.js / meta-renderers.js
│ │ └── stakes-ui.js
│ └── rpg/ # Phaser overworld — 28 JSON-authored maps
│ ├── js/data/ # maps, npcs, dialogues, quests, easter_eggs, triggers
│ └── js/systems/ # MapLoader, TerminalHostOverlay, MenuOverlay, ...
└── tests/ # pytest suite
1.2 Three surfaces, one engine
| Surface | Entry | Role |
|---|---|---|
| Python CLI | python3 -m mandalay_bay |
Authoritative rules |
| Web terminal | docs/index.html |
Browser parity, ES modules under docs/js/ |
| Pixel RPG | docs/rpg/index.html |
Phaser overworld over the same modules |
1.2.1 The delegation rule
The RPG never reimplements a game screen. Casino, hotel, pool, shopping, sportsbook, racing, cashier, and every meta screen is written once in docs/js/ui/ as a buildXRenderers(ctx) factory that returns a view-name → render-function map. The terminal spreads those maps into its RENDERERS table; the RPG’s TerminalHostOverlay builds the same ctx and mounts them inside an encounter panel. A feature added to the terminal therefore appears in the RPG with no RPG-side work.
flowchart LR
LOGIC["docs/js/ — rules"] --> UI["docs/js/ui/ — buildXRenderers(ctx)"]
UI --> APP["app.js (terminal)"]
UI --> HOST["TerminalHostOverlay (RPG)"]
The exceptions are the four bespoke “battle screens” the RPG draws itself because they read better in-world: blackjack, hold’em, roulette, and the House of Blues rhythm minigame. They still route bet entry through the shared stake picker. See the Pixel RPG GDD for the overworld side.
Anything genuinely new belongs in docs/js/ first, with the RPG consuming it — never the reverse.
1.3 Data flow
flowchart TD
main[main.py] --> session[PlayerSession]
session --> wallet[ChipWallet]
main --> hub[hub.py]
hub --> activity[Activity.run]
activity --> wallet
activity --> stats[ActivityStats]
blackjackAct[BlackjackActivity] --> runner[blackjack/runner.py]
runner --> table[blackjack/table.py]
runner --> wallet
1.4 Key abstractions
1.4.1 ChipWallet (mandalay_bay/chips.py)
Single source of truth for chip balance. Methods:
debit()/credit()— immediate wager/payoutapply_delta()— net change with ledger entryreconcile()— align with external balance (blackjack rail)buy_in()/cash_out()— Cashier operations
1.4.2 PlayerSession (mandalay_bay/session.py)
Per-visit state: player name, wallet, display prefs, activity statistics.
1.4.3 Activity (mandalay_bay/activities/base.py)
class Activity(ABC):
info: ActivityInfo # id, name, floor, description, min_bet
def run(self, session: PlayerSession, ui: TerminalUI) -> None: ...
def can_enter(self, session: PlayerSession) -> bool: ...Activities are registered in activities/registry.py and discovered by floor.
1.4.4 TerminalUI (mandalay_bay/display.py)
Shared terminal rendering: banners, menus, prompts, chip formatting, color control.
1.5 Activity registry
ALL_ACTIVITIES = [
BlackjackActivity(),
SlotsActivity(),
SportsbookActivity(),
]Floors are defined by ActivityInfo.floor:
- Table Games
- Slot Machines
- Sports Book
1.6 RNG layer
All games import from blackjack/rng.py:
SECURE_RANDOM—secrets.SystemRandom()singletonfisher_yates_shuffle()— in-place shuffle for shoes
Slots and sports book use SECURE_RANDOM directly for outcome generation.
1.7 Blackjack integration
The blackjack engine is decoupled from the casino:
| Mode | Entry | Wallet |
|---|---|---|
| Standalone | blackjack/main.py |
Internal player bankroll |
| Casino | blackjack/runner.py |
Synced via ChipWallet |
run_casino_blackjack() sets the human player’s rail to wallet balance, applies apply_delta() after each hand, and reconcile() on exit.
1.8 Extension points
See Adding Activities for plugging in new games.
1.9 Testing
- Unit tests per module in
tests/ - Integration tests for navigation in
tests/test_casino_navigation.py - Injectable deterministic RNG for blackjack tests only