A satirical choose-your-adventure resort simulator with a unified chip economy

Author
Affiliation

University of Wisconsin–Madison

Published

July 27, 2026

Abstract

The Mandalay Bay (degen-llms) is a full-stack digital resort simulator spanning a Python CLI, a browser terminal on GitHub Pages, and a Phaser 3 pixel RPG overworld. Players share one chip wallet across blackjack, Texas Hold’em, roulette, craps, fourteen slot machines, lottery tickets, a sports book with prediction markets, a trading floor for futures and options, thoroughbred racing, and equestrian events — then leave the floor for hotel check-in, an eleven-acre pool complex, and MGM Rewards tier progression. This Quarto site documents the product surfaces, economy, save system, architecture, and expansion roadmap using the live repository packages.

Keywords

Mandalay Bay, casino simulation, chip economy, blackjack, slots, sports book, Phaser RPG, Quarto, Posit Connect Cloud

1 Introduction

The Mandalay Bay is a satirical Las Vegas resort simulator. It is not a thin demo of a single table game — it is a property with floors, a hotel tower, a pool deck, VIP venues, and a rewards phone that persists across visits. The project ships three playable surfaces that share save slots and the same chip wallet:

Surface How to open Role
Python CLI python3 -m mandalay_bay Authoritative game logic
Web terminal exios66.github.io/degen-llms Browser parity of the CLI hub
Pixel RPG …/rpg Phaser 3 overworld with activity encounters

This Posit Connect Cloud site is the documentation manuscript for the repository: player guides, developer architecture, live package introspection, and deploy notes. The interactive game itself remains on GitHub Pages; see Play.

New content instance

This deployment is a new JackJBurleson Posit Connect Cloud content item for degen-llms. It does not replace the PSYCH 755 communication-apprehension manuscript at content id 019f9a10-ebb9-d1d5-839f-97e794bfd0ca.

2 Product map

2.0.1 What you can do on property

Zone Highlights
Casino floor Blackjack, Hold’em, roulette, craps, 14 slots, lottery, sports book, trading floor, arcade alley, racing, dressage & jumping
Cashier & bank Buy/cash chips, ledger, off-strip bank account
Hotel Clerk Carmen, hallway mini-game, in-room amenities, guest directory
Resort dining Aureole, Border Grill, Stripsteak — capacity minigame + drink-scaled encounters
Pool complex Wave pool, cabanas, Shark Reef collection, beach club
MGM Rewards Sapphire → Chairman tiers, comps, phone (press P on web)
Pixel RPG 28 walkable rooms, 61 NPCs, quests, and a dex — see Pixel RPG
Code
rows = []
for activity in ALL_ACTIVITIES:
    info = activity.info
    rows.append(
        {
            "ID": info.id,
            "Name": info.name,
            "Floor": info.floor,
            "Min bet": info.min_bet,
            "Description": info.description,
        }
    )
catalog = pd.DataFrame(rows)
catalog = catalog.sort_values(
    by="Floor",
    key=lambda s: s.map({name: i for i, name in enumerate(FLOOR_ORDER)}).fillna(99),
)
catalog
Table 1. Live activity catalog from mandalay_bay.activities.registry
ID Name Floor Min bet Description
0 blackjack Blackjack Table Games 10 Classic 21 with solo or full-table play. 3:2 b...
1 holdem Texas Hold'em Table Games 10 No-limit Hold'em vs 4 AI opponents — full stre...
2 roulette Mandalay Roulette Table Games 5 European single-zero wheel — straights, colors...
3 craps Mandalay Craps Table Games 5 Dice table — Pass / Don't Pass, Field, props, ...
4 slots Mandalay Bay Slots Slot Machines 1 Nearly 1,000 reel games from penny slots to hi...
5 lottery Mandalay Lottery Lottery Counter 2 Pick 3/4, Mega/Powerball jackpot draws, and in...
6 sportsbook Mandalay Sports Book Sports Book 10 125+ stored sports scenarios and prediction ma...
7 trading_desk Mandalay Markets Trading Floor 25 Futures and call/put options on NYSE, commodit...
8 arcade Mandalay Arcade Arcade Alley 5 Vegas-styled CRT cabinets — play the full over...
9 horse_racing Mandalay Racing Racing Pavilion 5 Simulated thoroughbred racing — win, place, an...
10 dressage Dressage Arena Equestrian Arena 5 Score-based dressage competition — bet on the ...
11 jumper Show Jumping Equestrian Arena 5 Fault-and-time show jumping — wager on clear r...
Code
counts = catalog.groupby("Floor").size().reindex(FLOOR_ORDER).fillna(0).astype(int)
fig, ax = plt.subplots(figsize=(7.2, 3.8))
bars = ax.bar(counts.index, counts.values, color="#C5050C", edgecolor="#7a0307")
ax.set_ylabel("Activities")
ax.set_xlabel("Floor")
ax.set_ylim(0, max(counts.values.max(), 1) + 1)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
for bar, value in zip(bars, counts.values):
    ax.text(bar.get_x() + bar.get_width() / 2, value + 0.05, str(int(value)), ha="center", va="bottom", fontsize=9)
fig.tight_layout()
plt.show()
Figure 1. Registered activities per casino floor

3 Chip economy and stakes

Every activity debits and credits a single ChipWallet. Buy-ins and cash-outs happen at the Cashier; gambling outcomes write to a transaction ledger. Stake tiers span penny slots through high-roller / no-limit brackets (including satirical “401K Contribution” limits). Progressive jackpots persist in the active save.

Code
from mandalay_bay.stakes import TIER_ORDER

stake_df = pd.DataFrame(
    [
        {
            "ID": STAKE_TIERS[tid].id,
            "Name": STAKE_TIERS[tid].name,
            "Min bet": STAKE_TIERS[tid].min_bet,
            "Max bet": STAKE_TIERS[tid].max_bet if STAKE_TIERS[tid].max_bet is not None else "No cap",
            "Description": STAKE_TIERS[tid].description,
        }
        for tid in TIER_ORDER
    ]
)
stake_df
Table 2. Stake tiers exposed by mandalay_bay.stakes
ID Name Min bet Max bet Description
0 penny Penny & Low Limit 1 25 Micro stakes — $1 min. Tables: no max (bankrol...
1 standard Standard 5 100 Main floor — $5 min. Tables: no max (bankroll)...
2 high_limit High Limit 25 500 High-limit room — $25 min. Tables: no max (ban...
3 401k_contribution 401K Contribution 542 6500 Average employee deferral — $542 min. Tables: ...
4 no_limit High Roller / No Limit 2500 No cap Salon stakes — minimum table bet, no maximum (...

Full player-facing detail: Chip Economy.

4 Resort systems beyond the pits

4.1 Hotel experience

Exit the casino floor to the Mandalay Bay Hotel Experience: reservation locate with Clerk Carmen, hallway navigation, room upgrades (Deluxe King → Panorama Suite → Chairman Penthouse), folio settlement, and in-room amenities (TV channels, minibar, foreign calls, balcony decisions, unlockable Vegas vignettes). A real-time day/night cycle drives daily charges and rotating check-in requirements.

Resort dining opens Aureole, Border Grill, and Stripsteak as a capacity overlay — pace courses, stack drinks, and risk satirical encounters that escalate with every pour. See Resort Dining.

4.2 Pool complex

The eleven-acre expansion includes wave-pool timing, hot tubs, private cabanas, Shark Reef species collection, topless beach club, and beach rave — with vignettes that chain into hotel room events.

4.3 MGM Rewards

Code
from mandalay_bay.rewards import COMP_CATALOG

rewards_df = pd.DataFrame(
    [
        {
            "Tier": tier.label,
            "ID": tier.id,
            "Lifetime wagered": tier.min_wagered,
            "Comp unlock": (
                COMP_CATALOG.get(tier.comp, {}).get("title", tier.comp)
                if tier.comp
                else "—"
            ),
        }
        for tier in REWARD_TIERS
    ]
)
rewards_df
Table 3. MGM Rewards ladder from mandalay_bay.rewards
Tier ID Lifetime wagered Comp unlock
0 Sapphire sapphire 0
1 Pearl pearl 10000 $10 Slot Free-Play
2 Gold gold 50000 Buffet Comp
3 Platinum platinum 200000 Standard Room Night
4 Noir noir 500000 Suite Upgrade
5 Chairman chairman 1000000 Penthouse Fantasy Comp

Lifetime wagered chips advance Sapphire → Pearl → Gold → Platinum → Noir → Chairman. Tier comps gate TV channels, phone contacts, VIP venues, and narrative perks. On the web terminal, press P for the rewards phone.

5 Save system

Up to five save slots with most-recent-first library ordering. CLI stores under ~/.mandalay_bay/saves/; the browser uses localStorage. Auto-save runs on leave, after activities, and on Ctrl+C. RPG position, quests, hotel state, pool progress, and progressive jackpots travel with the slot.

See Save Slots and Getting Started.

6 Architecture

Python is the source of truth. The web terminal mirrors logic in vanilla ES modules under docs/js/. Screens are written once as buildXRenderers(ctx) factories in docs/js/ui/: the terminal spreads them into its renderer table and the RPG mounts the same functions inside an encounter panel, so neither surface reimplements the other.

Code
def count_files(path: Path, suffixes: set[str]) -> int:
    if not path.exists():
        return 0
    return sum(1 for p in path.rglob("*") if p.is_file() and p.suffix in suffixes)

inventory = pd.DataFrame(
    [
        {"Package / tree": "mandalay_bay/", "Python modules": count_files(ROOT / "mandalay_bay", {".py"}), "Data files": count_files(ROOT / "mandalay_bay" / "data", {".json", ".csv"})},
        {"Package / tree": "blackjack/", "Python modules": count_files(ROOT / "blackjack", {".py"}), "Data files": 0},
        {"Package / tree": "poker/", "Python modules": count_files(ROOT / "poker", {".py"}), "Data files": 0},
        {"Package / tree": "docs/js/", "Python modules": count_files(ROOT / "docs" / "js", {".js"}), "Data files": count_files(ROOT / "docs" / "data", {".json", ".csv"})},
        {"Package / tree": "docs/rpg/", "Python modules": count_files(ROOT / "docs" / "rpg", {".js"}), "Data files": count_files(ROOT / "docs" / "rpg", {".json", ".css", ".html", ".md"})},
        {"Package / tree": "tests/", "Python modules": count_files(ROOT / "tests", {".py"}), "Data files": 0},
    ]
)
inventory
Table 4. Repository package inventory (file counts at render time)
Package / tree Python modules Data files
0 mandalay_bay/ 54 8
1 blackjack/ 15 0
2 poker/ 3 0
3 docs/js/ 92 8
4 docs/rpg/ 31 43
5 tests/ 44 0

Developer deep-dives:

7 Player documentation index

Guide Audience
Getting Started Install, launch, CLI flags
Player Guide Every menu, dialog, and shortcut
Chip Economy Wallet, ledger, buy-ins, cash-outs
About Vision, design pillars, history
Casino Offerings Full floor catalog
Save Slots Library, migration, RPG fields
Blackjack Table rules and modes
Table Games Hold’em, roulette, craps
Slot Machines Machines, paytables, progressives
Lottery Pick 3/4, Mega, scratchers
Sports Book Scenario board, parlays, prediction markets
Trading Floor Futures & options
Arcade Alley CRT cabinet minigames
Racing Thoroughbred + equestrian
Hotel / Dining / Pool / Rewards Resort off the floor
RNG CSPRNG guarantees
Pixel RPG Overworld overview

8 RNG and legitimacy

All random outcomes use OS-backed CSPRNG (secrets.SystemRandom() in Python, crypto.getRandomValues() in the browser). Tests inject seeded RNGs for determinism; production play never does. See RNG and Fairness.

9 License and deploy

MIT licensed — see LICENSE in the repository. GitHub Pages hosts the interactive web terminal and RPG from the gh-pages branch /docs folder (mirrored from main/docs/ via the gh-pages-deploy-loop skill; automatic push/schedule is disabled). This Quarto website is published separately to Posit Connect Cloud under the JackJBurleson account as its own content instance (deploy notes).