# Candy Survival: Complete Implementation & Architecture Log This document serves as an exhaustive, technical record of all modifications, refactors, and features implemented during the transition from the legacy "Gauntlet" mode to the new "Candy Survival" mode. --- ## 1. Project-Wide Renaming & Metadata Scrubbing - **Global Find & Replace**: Executed across `scripts/`, `scenes/`, `tests/`, and `addons/`. - Replaced `GAUNTLET`, `GauntletManager`, `gauntlet_manager`, and `is_gauntlet_mode()`. - Replaced UI and enum display strings `"Gauntlet Arena"` → `"Candy Survival Arena"`. - **File System Refactoring**: - `git mv scripts/managers/gauntlet_manager.gd scripts/managers/candy_survival_manager.gd` - `git mv scripts/controllers/candy_cannon_controller.gd scripts/controllers/candy_survival_npc_controller.gd` - `git mv scenes/candy_cannon.tscn scenes/candy_survival_npc.tscn` - `git mv scenes/gauntlet_hud.tscn scenes/candy_survival_hud.tscn` - `git mv scenes/arena/gauntlet.tscn scenes/arena/candy_survival.tscn` - **Asset Scrubbing (`assets/models/arena/candy_survival/`)**: - Renamed the directory and all interior files (e.g., `Gauntlet terrain.gltf` → `candy_survival_terrain.gltf`). - Purged buried metadata: Modified `.import` and `.gltf` text structures to remove cached `"res://assets/models/arena/gauntlet/..."` paths to prevent headless Godot build corruption. - Updated legacy entries in `version.json` for historical consistency. --- ## 2. Arena Layout & Sticky Collision Overhaul - **Grid Properties**: Enforced strict `18x18` playable bounds via `_setup_arena()`. - **Sticky Mechanics Rewritten**: - *Legacy*: Sticky cells grew dynamically, gave telegraph warnings, and trapped players requiring a "cleanser". - *New*: `TILE_STICKY` now acts exclusively as static, pure-collision boundary walls. Placed solely on the arena perimeter and the center 3x3 NPC zone to block entry. - Movement check in `player_movement_manager.gd` strictly evaluates `if gm.is_sticky_cell(grid_position)` and rejects the move outright unless the player possesses the `is_invisible` (Ghost) buff. - **Spawn Point Correction**: Shifted `get_spawn_points()` coordinates from `row 1` to `row 2` and `row 15` to `row 16` (`(2,2), (16,2), (2,16), (16,16)`) to prevent players from spawning inside stairs/geometry. --- ## 3. Mekton NPC (Center Boss Entity) - **Mesh Replacement**: Scrapped the primitive Cylinder/Sphere tank meshes in `candy_survival_npc.tscn`. Instanced `static_tekton_mesh.tscn` as the visual representation. - **Face Color Cycling**: - Engineered `set_face_color_rpc(color_index: int)` inside `candy_survival_npc_controller.gd`. - Dynamically extracts the surface material from the `ted_body` skeleton node. - Duplicates the material at runtime and applies emission glow and albedo tints corresponding to the `CandyColor` enum (0: Heart/Red, 1: Diamond/Blue, 2: Star/Yellow, 3: Coin/Orange). - **Manager Authority**: `candy_survival_manager.gd` tracks `face_timer`. Every 5.0 seconds (`COLOR_CYCLE_TIME`), it increments `current_face = CandyColor.values()[(current_face + 1) % CandyColor.size()]` and fires the RPC to visually sync the Mekton across all clients. --- ## 4. Gameplay Loop: Blueprints & Stacks - **Auto-Pickup Integration**: - Hooked into `player_movement_manager.gd` -> `_on_movement_finished()`. - If `LobbyManager.game_mode == "Candy Survival"`, automatically calls `player.grab_item(player.current_position)` when stepping on a tile, assuming the `playerboard_manager` has an empty slot. Completely removes the need for manual button presses during high-speed building. - **3x3 Blueprint Detection Engine**: - Overhauled `_check_goal_completion()` in `playerboard_manager.gd`. - Scans the 5x5 player board for *any* contiguous, fully-populated 3x3 block. - Calculates the majority color (`primary_color`) within that block. - **Off-Color Validation**: - If the 3x3 block is mixed (off-color), it queries the global `gridmap` via `CandySurvivalManager._grid_has_color_tiles(primary_tile_id)`. - If the primary color is mathematically extinct on the physical arena floor, the blueprint is accepted for 50% points. Otherwise, it is rejected. - **Stacking Mechanics & Multipliers**: - `on_blueprint_completed` invokes `_give_candy(pid, color)`. - Tracks `player_candies` (height) and `player_candy_color`. - Multiplier scales dynamically: `1.0 + (Stack Count * MULTI_STEP [0.1])`. Generates continuous passive points per second evaluated in `_process`. --- ## 5. Gameplay Loop: Delivery & Sugar Rush - **Proximity Delivery Trigger**: - Built into `player_movement_manager.gd`. During movement, it evaluates Manhattan distance to the center NPC (`abs(x - 8) + abs(y - 8)`). - If distance is `<= 2`, the client fires `gm.try_deliver(pid)` via RPC to the server. - **Face Matching Logic**: - Server evaluates `if player_candy_color == current_face`. - Rejects if the player has 0 candies or colors mismatch. - **Sugar Rush Global Event**: - Successful delivery adds to `player_sugar_rush[pid]` with the formula: `SR_BASE_TIME [2.0s] + (candies * SR_PER_CANDY [0.4s])`. - While *any* player's rush timer is `> 0`, the manager forces `Engine.time_scale = SR_SPEED [2.0]`. When all timers reach 0, it restores to `1.0`. --- ## 6. Sabotage: Knock & Ghost Dynamics - **Knock (Steal/Backfire)**: - Input bound natively to `action_knock_tekton` inside `player_input_manager.gd`. - Fires `try_knock(attacker, target)` when adjacent to an opponent. - Consumes 1 of 5 starting charges (`player_knocks`). - *Steal*: If target has candies, attacker adopts target's full stack and color; target is zeroed. - *Backfire*: If target has 0 candies, attacker loses a charge and both suffer the knock animation state (handled by caller). - **Ghost (Phase-Through)**: - Input bound natively to `action_grab_tekton` inside `player_input_manager.gd` (bypasses default grab behavior in this mode). - Consumes 1 of 5 starting charges (`player_ghosts`). - `try_activate_ghost` sets the core `player.is_invisible = true` and `sync_modulate(Color(1, 1, 1, 0.4))` for 4.0 seconds. - The `is_invisible` state natively bypasses the sticky collision checks, allowing phase-through of boundaries/boss zones, and renders the player immune to incoming Knocks. --- ## 7. Visuals, UI & 3D Stacking - **HUD De-Scripting**: - Legacy `gauntlet_manager` instantiated UI elements via GDScript. This was purged. - Created `candy_survival_hud.tscn` using pure Godot Control nodes (VBoxContainer, HBoxContainer, ProgressBar, Label). Exposes all UI to artists for layout/theme modifications without code risk. - Manager simply grabs node references (`hud_rush_bar`, `hud_stack_badge`, etc.) on `_ready()`. - **Dynamic Delivery Indicator**: - `sync_candy_badge` RPC was expanded to include a `face_match` boolean. - When the Mekton's face color changes (every 5s), the server force-updates all clients. - The HUD dynamically shifts `DeliveryIndicator.text` to a Green `"READY TO DELIVER!"` or Red `"Waiting for match..."` based on their currently held candy stack. - **Physical 3D Candy Stacking**: - Implemented `sync_candy_stack(count, color_id)` directly on `player.gd`. - Creates a generic `Node3D` on the player's `Visuals` node. - Instantiates raw `MeshInstance3D` tiles (`tile_heart.tres`, `tile_diamond.tres`, etc.). - Visually stacks them vertically (`y = i * 0.4`) and scales them down (`0.5x`) corresponding exactly to the player's internal candy count. Clears them instantly upon delivery or being knocked. --- ## 8. AI & Bot Behaviors - **Delivery Pathfinding (Priority 0.7)**: - Injected specialized logic into `bot_controller.gd`. - Bots actively check their held `player_candy_color` against the manager's `current_face`. - When colors match, the Bot halts blueprint construction and immediately uses `find_path` targeting `Vector2i(8,8)` to execute a delivery and trigger Sugar Rush. - **Ghost Survival Logic**: - Re-wrote `_bot_has_ghost_powerup()` in `bot_strategic_planner.gd` to evaluate the new native `player_ghosts` charge counter instead of the legacy `SpecialTilesManager` inventory. - Bots correctly evaluate proximity to sticky walls and automatically fire `try_activate_ghost` when cornered to phase out of traps. --- ## 9. Code Health & QA - **Orphan Code Purge**: Deleted 8 specific `test_gauntlet_*.gd` files that referenced non-existent legacy mechanics (growth algorithms, bubbles, floor highlights, old cleansers). - **Compile Integrity**: Fixed a trailing `_on_doors_update()` call in `lobby_room.gd` leftover from a different branch. Verified flawless compilation via `godot --headless --build-solutions`. - **Gitea Documentation**: Automated the closure and deep-technical documentation of Issues #54, 55, 56, 57, 65, 66, 67, 68, 69, and 70 directly to the tracking server. - **Wiki Accuracy**: Overhauled `Game-Modes.-.md` to perfectly mirror the new Sabotage input maps, Blueprint rules, RPC structures, and Mekton behavior. ### Completed (July 6, 2026) - [x] **CI Pipeline Fixes** - [x] Downgraded Godot runner version to 4.6.3 to match local engine build. - [x] Updated Gitea API and Git clone URLs to use `https://` instead of `http://` to prevent silent redirect failures during release. - [x] **Runtime & Compilation Crash Fixes** - [x] Fixed `bot_controller.gd`: Replaced dead `_execute_move()` with proper `enhanced_gridmap.find_path()` logic. - [x] Fixed `bot_controller.gd` & `player_movement_manager.gd`: Changed `.is_active` to `.active` for CandySurvivalManager checks. - [x] Fixed `candy_survival_manager.gd`: Merged duplicate `start_game_mode()` implementations. - [x] Fixed `special_tiles_manager.gd` indentation errors. - [x] Fixed `main.gd` duplicate variable declarations. - [x] **Editor & Test Environment Fixes** - [x] Resolved "Cyclic Reference" errors in `leaderboard_panel.gd` by accessing Nakama session via `get()`. - [x] Fixed `BackendService.gd` Autoload dependencies failing in isolated tests by using `get_node_or_null()`. - [x] **Gacha System Fixes** - [x] Corrected `BackendService.gd` payload to send `"banner_id"` instead of `"gacha_id"`, fixing HTTP 500 errors on pull. - [x] Configured Unique Names (`%`) for left-side BalanceRow labels in `gacha_panel.tscn` so currency updates instantly upon rolling. - [x] **3D Arena & GridMap Elevation Fixes** - [x] Normalized root node transforms of all arenas (`freemode.tscn`, `stop_n_go.scn`, `candy_survival.tscn`) to `(0,0,0)` and scale `(1,1,1)`. - [x] Removed hardcoded terrain shifts and `0.08` mesh elevations from `main.gd`. - [x] Added `EditorTileReference` to arena scenes as a perfect 1:1 footprint guide. - [x] Baked terrain height shifts directly into `.tscn` files to match the reference tile perfectly. - [x] Scaled red `non-walkable` blocks (Tile 4) to 0 so they act as invisible collision walls in 3D arenas. - [x] Fixed Stop N Go safe zone clipping by adjusting render priorities (`1` for safe zone, `-1` for baked terrain shadows).