A fully playable casino map and plugin for ATLYSS with multiplayer slots, blackjack, roulette, background jukebox music, private room chat, and casino teleports.
Reworked casino jukebox volume so it behaves more like background music by default.
Changed the casino jukebox and personal jukebox volume controls to a 0-10 range, defaulting to 5.
Capped effective jukebox output so 5 is quiet background playback and 10 is louder but still limited.
Added a one-time migration for older saved 0-1 volume values so existing configs are converted to the new 0-10 range.
Improved shared jukebox networking so the lobby host owns the world jukebox state, clients can request song advances, and late joiners can receive the current jukebox state.
Made jukebox state application more stable so it does not repeatedly restart or spam repeated "Playing" logs when the same track/state is already active.
Kept casino jukebox playback tied to the casino scene so it stops when the casino is no longer active for the local client.
Private RoomZone chat
Added generic private room-zone chat support using Unity-authored RoomZone BoxCollider triggers.
Room zones can be named with the RoomZone_<RoomName> pattern, such as RoomZone_VIP, RoomZone_BackRoom, or RoomZone_PrivateTable.
Zone chat sent by a player inside a private room is routed only to players in the same named private room.
Separate private rooms are isolated from each other, so players in different room zones do not receive each other's outgoing room messages.
Players inside private rooms can still receive normal Zone chat sent from outside private rooms.
// chat messages are treated as chat text for private room routing, while normal single-slash casino commands remain commands.
Private room messages try to display through ATLYSS' vanilla chat receive path so the normal player talk sound behavior is preserved, including race and voice pitch handling.
Added a client-side private room chat toggle in Easy Settings and the /roomzonechat [on|off|status] command.
Added CodeTalker preference, presence, and room-chat request packets so hosts and clients can keep room membership and private delivery in sync.
Added room-zone diagnostics for registration, membership transitions, sender/recipient scope, and vanilla-vs-fallback display.
Manual portals and portal signs
Added manual portal support for one-way portal pairs using ManualPortal_<Name> and ManualPortalTarget_<Name>.
Added two-way manual portal support using ManualPortalTwoWay_<Name>_A and ManualPortalTwoWay_<Name>_B.
Manual portals now use the shared casino interact input, including the configured controller interact button.
Runtime portal setup now forces usable portal colliders to triggers where possible so invisible portal volumes do not physically block the player.
Added authored portal/elevator sign support for CasinoTeleportSign_Elevator, CasinoTeleportSign_Office, CasinoTeleportSign_Basement, CasinoTeleportSign_Floor1, and CasinoTeleportSign_Floor2.
Portal signs now use regular TextMesh text with a depth-tested material so normal opaque walls can hide the text instead of drawing through walls.
Portal sign handling is separate from blackjack/roulette table info signs, so client performance options for table signs do not hide portal signs.
Scene and build support
Added runtime visibility support for authored owner portrait objects named SelfPortrait or Self Portait.
Reorganized casino source files into feature folders and added a project compile guard so stale flat files under Casino Code do not create duplicate class definitions if they reappear.
Added additional runtime logs around room zones, manual portals, jukebox state, and portal signs to make future BepInEx log debugging easier.
1.8.0
Added casino jukebox music, which auto-plays in the casino and can be advanced with the normal casino interact input.
Added bundled casino music tracks to the casino asset bundle.
Added Client Audio settings for casino music.
1.7.0
Added controller support for casino interactions that previously only used the F key.
The default controller interact button is X / Square, matching vanilla ATLYSS.
Added a client controls section for controller interact settings.
Added optional controller command macros in a collapsed EasySettings section. They are disabled by default and only run recognized casino commands while inside the casino.
Confirmed client performance settings remain local convenience settings and are not host-synced gameplay rules.
1.6.1
Cleaned up casino command handling so slash commands are caught a little earlier and parsed more safely.
// messages are left alone instead of being treated like casino commands.
Updated the plugin/source version metadata to match the package version.
Added a short README note about my coding experience, the project, and how AI assistance has been used.
No casino gameplay or balance changes in this update.
1.6.0 (formerly 1.0.9)
Version number note
I had been numbering releases as 1.0.x while learning how version numbers should work.
This update was first prepared as 1.0.9, but the correct SemVer-style number is 1.6.0 because it added compatible new performance options.
Older changelog entries now keep their old 1.0.x labels in parentheses so people can still match them to the original Thunderstore releases.
Already-uploaded Thunderstore versions are not changed; this just fixes the numbering from here on.
Client performance options
Added a Client Performance settings section for local-only visual optimization.
Added Hide Decor Props, which can unload optional casino decorations such as bottles, bar shelves, plants, neon signs, neon lighting, and spotlights while keeping gameplay objects intact.
The bar structure, casino tables, slot machines, triggers, portal, and point lights are preserved when decor unloading is enabled.
Added Idle Slot Screens Off, which disables idle slot-machine screen visuals on casino entry and re-enables them while a local or remote spin is playing.
Performance options are client-local preferences and do not change casino rules or host-owned gameplay settings.
Cleanup
Tightened decor filtering so remaining plant hooks and potted plant decorations are included in the optional hide pass.
Verified casino setup, exit cleanup, and deferred cleanup continue to complete without leaked casino objects.
1.5.0 (formerly 1.0.8)
Easy Settings integration
Added Easy Settings API as a required dependency.
Added an Atlyss Casino settings tab for main-menu casino configuration.
Settings are backed by the normal BepInEx config file, so dedicated/headless servers can configure the casino without opening a client UI.
The settings UI locks once a player/session is loaded, preventing casino rules from being changed mid-lobby.
Gameplay settings are host/server-owned. Clients cannot override the lobby host's casino rules from their own settings menu.
Host-owned gameplay values are synced to clients when the casino loads, so client-side trigger paths use the lobby host's configured rules.
Configurable casino rules
Entry fee is now configurable. The default remains 100 Crowns.
Walk-away penalty is now configurable. The default remains 10 Crowns.
Blackjack turn timeout is now configurable. The default remains 60 seconds.
Roulette AFK timeout is now configurable. The default remains 60 seconds.
Floating blackjack/roulette table info text can now be toggled on or off.
Routine headless/dedicated-server casino logging can now be suppressed through config.
Documentation
Updated README dependency notes for Easy Settings API.
Added README configuration guidance for lobby hosts and dedicated servers.
Added Easy Settings API credit to Special Thanks.
1.4.0 (formerly 1.0.7)
Entry fee reliability
Improved entry-fee consistency by verifying that the 100 Crown deduction actually applies before marking a player as paid.
If the entry-fee deduction does not apply correctly, the mod retries once, restores the player's original balance if needed, and does not grant paid-entry status.
Re-entering during the same loaded casino session still recognizes already-paid players, while a fresh casino unload/reload requires paying again.
Blackjack and table interaction fixes
Added host-authoritative blackjack turn sync with a TurnChanged packet. All clients now receive current-turn changes for table prompts and green active-seat stool indicators.
Turn changes short-circuit when the seat did not actually change, preventing duplicate broadcasts and redundant AFK timer resets.
Blackjack seat, ready, and turn prompts are now gated to the local player being seated at the same table, preventing unrelated table HUD leakage.
Blackjack table setup now deep-scans the whole table hierarchy for SeatTrigger, SeatAnchor, DealerAnchor, and Stool objects. This supports Unity prefab layouts where SeatTrigger is nested under a stool instead of being a direct table child.
SeatTrigger index detection can now infer the seat from a parent Stool object, so both Stool (1)/SeatTrigger (1) and Stool (1)/SeatTrigger layouts work.
Floating table info
Added runtime floating table info displays for blackjack and roulette using the Unity-authored Casino_TableInfoAnchor/Casino_TableInfoText hierarchy.
Blackjack displays show table host, round state, compact dealer value, current turn or ready count, and player count.
Roulette displays show table host, round state, landed number/color after a spin, ready count, and player count.
Player names are cleaned up from ATLYSS object names such as [connID: 0]_player(name/Azrael) into readable names such as Azrael.
Empty/inactive tables now hide their floating text entirely to reduce visual clutter.
Floating text material handling now attempts to depth-test text so it does not draw through walls, tables, and other objects.
Position, rotation, and scale are now respected from Unity. The runtime no longer billboards or overrides the authored transform, so table text can be tuned per prefab.
Added an optional Unity editor-only preview script for checking table-info placement and blackjack card footprints in Scene view without launching the game.
Slot machine locking
Added network-aware per-machine slot locks. When any player pulls a machine, that machine locks locally and on remote clients for the spin duration.
SlotBetConfirm rejects extra pulls on an in-use machine with a countdown HUD prompt.
The spinner locks locally before broadcasting the spin result, closing the timing window where the same player could trigger multiple machines during one spin.
F-key interaction gating
Reworked Plugin.IsTypingInUI() so casino F-key interactions are blocked only while the player is actually typing.
The check now prioritizes ATLYSS chat focus state and only falls back to Unity/TMP input fields when those fields are actually focused.
Fixed F-key interactions appearing dead until left-clicking the world after chat had closed.
Applied the typing gate across casino F-key paths so pressing F in chat does not fire casino interactions.
HUD, headless logging, and cleanup
Plugin.ShowHUDOnce() suppresses casino HUD prompts when the local player is not actually in the casino, preventing host-side Sanctum HUD leakage while the casino scene remains loaded.
Added a CasinoLog wrapper around BepInEx logging. Routine Info, Debug, and Message output is suppressed on headless/dedicated server while warnings, errors, and fatal logs remain visible.
Headless detection now uses the shared HostCasinoVisibilityWatcher path, including batch mode, -nographics, and -server launch arguments.
Preserved the 1.0.6 ghost-casino visibility work so casino visuals/colliders hide when the local player is outside the casino while host-authoritative MonoBehaviour updates keep running.
Preserved the player visual skip stack and tracking-aware hide/restore sets so remote player bodies and blackjack card faces are not corrupted by casino hide/restore cycles.
Removed _entity_recallPortal from leak cleanup so Map Loader's legitimate Sanctum recall portal is no longer destroyed after casino exit.
Cleanup logs now name each destroyed leaked object and source scene.
Debug and build hygiene
Disabled BlackjackDebugCommands.cs by default behind the ATLYSS_CASINO_DEBUG_COMMANDS compile symbol. The old debug card/deck/table tools are preserved for later testing but are not part of regular builds.
Current 1.0.7 work keeps the normal casino build path focused on runtime features rather than old testing commands.
Command shortcuts
Added extra blackjack shortcuts while keeping every existing command and alias: /br for ready, /bd for deal/start, /bh for hit, /bst for stand, and /bl for leave.
Added extra roulette shortcuts while keeping every existing command and alias: /rb for placing bets, /rr for ready/standby, and /rc for clearing bets.
Added compact roulette outside-bet shorthand: /rb d1, /rb d2, /rb d3 for dozens and /rb c1, /rb c2, /rb c3 for columns.
Left the existing /rs alias mapped to roulette ready/standby for backwards compatibility.
1.3.0 (formerly 1.0.6)
Ghost-casino visibility and player visuals
Added HostCasinoVisibilityWatcher to handle ATLYSS's additive scene behavior where the casino scene can remain loaded after the local player has returned to Sanctum.
Casino visuals and colliders are hidden per component instead of disabling root objects, so host-authoritative table logic, ghost-seat polling, and AFK checks continue running while visuals are hidden.
Plugin.IsLocalPlayerInCasino() became the shared gate for casino input and HUD behavior, preventing triggers from firing while the local player is outside the casino.
Visibility detection was moved away from active-scene and bounds checks and onto reflected Player.Network_playerMapInstance comparison against the casino MapInstance, which works with ATLYSS additive loading and overlapping world origins.
Fixed remote-player body corruption caused by the hide pass disabling renderers on Mirror-reparented remote Player objects. The final skip stack protects MapInstance hierarchy objects, scene-root cameras/lights, Player ancestors, and all SkinnedMeshRenderer body meshes.
Hide/restore now tracks exactly which renderers, lights, cameras, and colliders it disabled. This prevents blackjack card fronts and backs from both being re-enabled after a hide cycle.
Multiplayer and currency stability
Codified the host-authoritative blackjack pattern: hosts execute state changes locally and broadcast; non-hosts send request packets to the lobby host.
Fixed remote-player currency writes by using PlayerInventory.Network_heldCurrency directly from the host for blackjack bets, payouts, and other host-authoritative currency changes.
Added blackjack ghost-seat detection on the lobby host. Destroyed-but-still-referenced Player objects are now released and broadcast to all clients so seats do not stay blocked after disconnects.
Preserved slot-machine per-player behavior where each spinner rolls locally and broadcasts the final result while echo guards prevent duplicate local replay.
Exit, HUD, and scene cleanup
Moved casino exit F-key handling into the persistent visibility watcher so clients can reliably leave the casino even when the portal GameObject hook order differs from the host.
Added a shared HUD gate so casino prompts do not leak to the host while they are in Sanctum and the casino is still loaded in the background.
Removed _entity_recallPortal from leak cleanup. That object is a legitimate Map Loader recall portal, and destroying it was the real cause behind the earlier 1.0.3 "harmless" MapInstance.Handle_VisualSettings NullRefs.
Scene cleanup now logs each destroyed leaked object and its source scene, making future cleanup mistakes much easier to diagnose.
Dedicated server and log cleanup
Added headless/server-mode detection through HostCasinoVisibilityWatcher.
Skips visual hide/show management on dedicated servers where there is no local camera view to manage.
Demoted noisy setup retry, trigger-bounds, and per-seat/per-machine diagnostics from Info to Debug.
Consolidated missing-BoxCollider warnings so they log once globally instead of once per object.
Build notes
Cleaned up nullable warnings in HCVW.cs.
Known harmless gap: casino audio is not silenced during hide/restore because adding full AudioSource handling would require an additional Unity audio module reference.
1.2.1 (formerly 1.0.5)
Lighting
Fixed casino lights so they properly render and stay on.
Resolved lighting issues where some lights appeared enabled but flickered based on camera/player position, while other lights failed to work or stayed off entirely.
1.2.0 (formerly 1.0.4)
Slots and balance
Rebalanced slot payouts. The 3x Diamond jackpot became 500x the bet, with other payout rows increased to match the new table.
Reduced jackpot frequency by adding a 50% demotion chance when a natural 3x Diamond result occurs. The jackpot moved from roughly 1 in 216 spins to roughly 1 in 432, while other payout odds remain unchanged.
The jackpot demotion happens before reel animation, so players only see the final actual result.
Signs and readability
Regenerated the slots sign with the new payout table.
Increased blackjack and roulette sign size/resolution so text is readable from normal standing distance.
Corrected roulette sign commands, including /tbet, /rstandby, and /rleave.
Command shortcuts and docs
Added short aliases for the main casino commands while keeping the original full command names.
Updated /casinohelp, README, and changelog content to better reflect the current command set and previous release changes.
1.1.0 (formerly 1.0.3)
Multiplayer & sync
Fixed Sanctum-leak bug where blackjack cards spawned on the host would appear floating in Sanctum if the host was physically there while clients were playing in the casino. Added Plugin.ScopeToCasinoScene helper that explicitly binds runtime-instantiated GameObjects to the casino scene at spawn time, so they're properly destroyed when the casino unloads instead of orphaning into whatever scene was active on the host's machine
Roulette ghost-detection now properly broadcasts RPlayerLeft to all clients when an abruptly-disconnected player is evicted by the host's 1Hz polling. Previously the host would clear the ghost locally but never tell other clients, leaving phantom seats lingering on every other machine until they re-entered the casino
Aggressive multi-pass scene cleanup in BlackjackSceneWatcher — runs immediately on casino scene unload, +1 frame later, and +1 second later. Catches casino objects (cards, slot machines, tables) that survive the unload event due to Mirror lifecycle quirks. Includes scanning the DontDestroyOnLoad scene where Mirror sometimes deposits orphaned NetworkIdentity'd objects
Roulette release on scene unload now properly cleans up local table state (refunds bets, clears ready, broadcasts to other clients) — was missing entirely before this release
AFK system
Per-turn AFK timer for blackjack — when it's a player's turn to /hit or /stand, they have 60 seconds before the host auto-stands them. HUD warnings appear at 10s and 3s remaining
Per-player AFK timer for roulette — joining a table without placing bets and going /rstandby for 60 seconds gets you auto-kicked. Activity (placing a bet, clearing bets, toggling ready) resets the timer. Doesn't count down while the wheel is spinning
Both AFK systems are host-authoritative — only the lobby host runs the timer, broadcasts the auto-action via existing packet flows
Walk-away enforcement (strict zone)
Physical walk-away from a seat trigger zone now releases the seat immediately, no grace period, no countdown — same model for blackjack and roulette
Walk-away from a roulette table forfeits all placed bets without refund (in contrast to /rleave which refunds normally)
Walk-away charges a 10-Crown penalty with red HUD warning teaching the player to use /leave or /rleave next time. If the player has fewer than 10 Crowns, drains to zero (never goes negative). Penalty applies even if no bet was at stake — strict by design
New RouletteTable.LeaveNoRefund(player) method and Forfeit flag on RLeaveTableRequest packet so the no-refund behavior works correctly for both lobby host and client walk-away paths
The walk-away path bypasses the "wheel is spinning" rejection so players can never get stuck at a table
Visual / layout improvements
Casino interior fully remodeled and redesigned. The whole layout has been reworked — game zones are more distinct, sightlines between the slots / blackjack / roulette areas are cleaner, and the floor plan generally flows better than the original boxy arrangement
Cards now stack tightly with only the corner of each previous card visible (poker fan style) instead of spreading widely. Prevents card overflow into adjacent seats when multiple players are at the same table
Each subsequent card lifts forward along the seat anchor's up axis to prevent z-fighting and visual clipping with cards behind it (bumped from 0.005 → 0.015 per card)
Card sizes now scale with the parent table's world scale via a non-linear curve. Small tables get appropriately smaller cards, large tables get appropriately larger cards — but extremes are pulled toward the middle so neither feels comically out of proportion. Tunable via PLAYER_CARD_SCALE, DEALER_CARD_SCALE, and TABLE_SCALE_EXPONENT constants in BlackjackTable.cs
New STACK_OFFSET_FRACTION constant (0.20) controls how much each subsequent card peeks out from the previous one — easy to tweak from 0.10 (tight) to 1.00 (full spread, old behavior)
Trigger zones
Slot machine triggers (SlotBet_Confirm) and blackjack seat triggers (SeatTrigger) now use a BoxCollider for detection if one is present on the GameObject, falling back to the previous fixed-radius behavior otherwise. Trigger zones automatically scale with their parent table — a 0.33x slot machine has a tiny detection zone, a 3x has a huge one, no code changes needed
Matches the existing pattern from RouletteTrigger, EntryFee, and Exit for consistency
Tone / colors
HUD message colors split into two semantic categories: peach (#FFDC96) for informational messages and prompts, vivid red (#FF3119) for errors, rejections, and "you can't do that" feedback. Replaces the previous uniform red-by-default tone
New Plugin.ShowHUDInfo() and Plugin.ShowHUDError() helpers wrap messages in TextMeshPro rich-text color tags. All ~60 call sites across the casino code routed through these helpers
Removed
The Plugin.ShowHUD() lingering coroutine that re-fired prompts every 2.8 seconds for 8 seconds total. Manifested as visible text spam rather than the intended "longer-lasting prompt" effect. ShowHUD() and ShowHUDErrorLong() are kept as compatibility shims that now just delegate to single-shot ShowHUDInfo / ShowHUDError
Known harmless warnings
Four MapInstance.Handle_VisualSettings NullReferenceExceptions appear in the BepInEx log on entering the casino. These come from ATLYSS's own MapInstance script reading visual references that occasionally don't resolve in time. They don't affect gameplay. Will investigate further if they ever start firing more frequently than 4 per session
The usual wall of "missing script" warnings for Beer Bottle / Cocktail Glass / Stairs / Ladder / Bottle / Stand / Pillar are from third-party asset packs (Fries and Seagull Bar) and are cosmetic only
Known Issues
Lights/Lighting still flickers and some still dont work, unkown reasons why and how to fix
Cards at the Blackjack table are not scaled correctly according to the table scale
1.0.2
Fixed multiplayer host detection — BJNetcode.AmHost() now uses SteamMatchmaking.GetLobbyOwner directly (matching CodeTalker's own SenderIsLobbyOwner check) instead of relying solely on Player.Network_isHostPlayer reflection
Removed dangerous fallback that returned true when host detection failed, which could cause clients to incorrectly behave as host and broadcast unauthoritative packets that get silently rejected
Fallback now defaults to false (treat as client and send request packets to host) — safer behavior that prevents desync when reflection fails
Added detailed reflection diagnostics on startup so the BepInEx log shows exactly which Steam matchmaking paths resolved on each player's machine
Affects all multiplayer features: blackjack seat claiming, ready states, hit/stand, roulette joining, betting, spinning — slots were unaffected as they don't gate on host authority
Fixed cursor staying visible after sending casino chat commands (/slotbet, /blackjackbet, /rbet, etc.) — players no longer have to press Escape to dismiss the chat input
The Harmony patch on ChatBehaviour.Send_ChatMessage was blocking the original method (which normally closes chat and re-locks the cursor), so SetChatFocusFalse() now tries ATLYSS's own close methods via reflection, with a fallback that manually clears _focusedInChat and forces Cursor.lockState = Locked + Cursor.visible = false
Fixed clients seeing the casino map but unable to interact with anything — CasinoPatch setup logic that hooks slot machines, blackjack tables, and roulette tables previously ran exactly once, two frames after scene load. That worked for the host (whose scene is populated immediately) but failed for clients, whose scene contents arrive over the network slightly later, leaving the client with zero hooked objects despite the map appearing visually
Setup logic now retries up to 15 times, once per second, stopping as soon as it successfully finds the casino objects — hosts continue to succeed on attempt 1; clients typically succeed on attempt 2
Each retry attempt logs what was found vs. what was expected, making future timing or scene replication issues much easier to diagnose from BepInEx logs
Fixed _entity_portal, _MapInstance, and _npc_Skrit GameObjects being saved as inactive prefabs with broken sceneId state, which prevented Mirror from properly replicating networked scene contents to clients — these are now active scene instances with valid sceneIds
Added an editor tool (Tools → Casino → Inspect Scene NetworkIdentities) to detect and report missing or duplicate sceneIds before building the asset bundle, including options to force-assign missing IDs or wipe and reassign all of them as a last resort
1.0.1
Fixed casino scene hierarchy — all geometry now correctly placed under _Environment
Replaced RecallPortal with a proper Portal component for return to Sanctum