Files
tekton/TODO.md
T

11 KiB

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.gltfcandy_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)

  • CI Pipeline Fixes
    • Downgraded Godot runner version to 4.6.3 to match local engine build.
    • Updated Gitea API and Git clone URLs to use https:// instead of http:// to prevent silent redirect failures during release.
  • Runtime & Compilation Crash Fixes
    • Fixed bot_controller.gd: Replaced dead _execute_move() with proper enhanced_gridmap.find_path() logic.
    • Fixed bot_controller.gd & player_movement_manager.gd: Changed .is_active to .active for CandySurvivalManager checks.
    • Fixed candy_survival_manager.gd: Merged duplicate start_game_mode() implementations.
    • Fixed special_tiles_manager.gd indentation errors.
    • Fixed main.gd duplicate variable declarations.
  • Editor & Test Environment Fixes
    • Resolved "Cyclic Reference" errors in leaderboard_panel.gd by accessing Nakama session via get().
    • Fixed BackendService.gd Autoload dependencies failing in isolated tests by using get_node_or_null().
  • Gacha System Fixes
    • Corrected BackendService.gd payload to send "banner_id" instead of "gacha_id", fixing HTTP 500 errors on pull.
    • Configured Unique Names (%) for left-side BalanceRow labels in gacha_panel.tscn so currency updates instantly upon rolling.
  • 3D Arena & GridMap Elevation Fixes
    • 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).
    • Removed hardcoded terrain shifts and 0.08 mesh elevations from main.gd.
    • Added EditorTileReference to arena scenes as a perfect 1:1 footprint guide.
    • Baked terrain height shifts directly into .tscn files to match the reference tile perfectly.
    • Scaled red non-walkable blocks (Tile 4) to 0 so they act as invisible collision walls in 3D arenas.
    • Fixed Stop N Go safe zone clipping by adjusting render priorities (1 for safe zone, -1 for baked terrain shadows).