# Game Modes [Back to Home](./Home) ## Table of Contents - [Overview](#overview) - [Architecture](#architecture) - [GameMode Enum & ModeConfig](#gamemode-enum--modeconfig) - [Session Flow (all modes)](#session-flow-all-modes) - [Core Managers (shared)](#core-managers-shared) - [Freemode](#freemode) - [Stop n Go](#stop-n-go) - [Tekton Doors (Portal)](#tekton-doors-portal) - [Candy Pump Survival (Gauntlet)](#candy-pump-survival-gauntlet) - [Scoring & Leaderboard](#scoring--leaderboard) - [Glossary](#glossary) - [File Index](#file-index) [Back to top](#top) ## Overview Four game modes, each implementing the same core loop — players navigate a grid, collect tiles (Heart / Diamond / Star / Coin), match them to goals on a virtual 5x5 playerboard, and compete for score before the match timer expires. | Mode | Enum Value | Display Name | Play Area | Gimmick | |------|-----------|-------------|-----------|---------| | Freemode | `FREEMODE = 0` | "Freemode" | Variable | No restrictions, just goals + timer | | Stop n Go | `STOP_N_GO = 1` | "Stop n Go" | 23x12 | GO/STOP phases, safe zones, scatter penalty | | Tekton Doors | `TEKTON_DOORS = 2` | "Tekton Doors" | 14x14 | 4 rooms, portal doors swap connections every 15s | | Candy Pump Survival | `GAUNTLET = 3` | "Candy Pump Survival" | 20x20 | Ground growth — candy slowly fills the arena | [Back to top](#top) ## Architecture ``` GameMode (enum/RefCounted) ├── .from_string() / .mode_to_string() / .is_restricted() / .get_all_modes() │ ├── ModeConfig (RefCounted) │ └── SCHEMA with defaults, type-checking, min/max for each mode │ ├── GoalsCycleManager (Node, autoload?) │ ├── 30s cycle timer │ ├── Match timer (configurable 60-600s) │ ├── Score tracking (player_scores, player_goal_counts) │ ├── Goal completion: _process_goal_completion() │ └── RPC sync: sync_player_score, sync_goal_count, sync_timer │ ├── GoalManager (Node) │ ├── initialize_random_goals() — generates 9-slot goal patterns │ ├── Speed tracking (completion_times, boost_multiplier) │ └── generate_preset_goals() / get_goals_for_player() │ ├── PlayerRaceManager (per-player) │ ├── goals: Array[int] (9 slots) │ ├── playerboard: Array[int] (25 slots, 5x5) │ ├── check_pattern_match() — core matching logic │ └── DEPRECATED lap/finish-line stubs │ ├── PlayerboardManager (per-player) │ ├── grab_item() / auto_put_item() / arrange operations │ ├── _execute_grab() — server-authoritative grab validation │ ├── HIDDEN_SLOTS (12 of 25 cells blocked) │ ├── bot_try_grab_item() — AI grab logic │ └── _check_and_refill_grid_if_needed() — scarcity refill │ ├── TurnManager (shared) │ ├── next_turn() / end_current_turn() │ └── turn_based_mode toggle │ └── Mode-specific managers ├── StopNGoManager — phase transitions, safe zones, mission HUD ├── PortalModeManager — room partitions, portal doors, swap timer └── GauntletManager — ground growth, phases, bubbles, smack ``` All mode managers live under `/root/Main` and connect to `GoalsCycleManager` signals for score / goal tracking. [Back to top](#top) ## GameMode Enum & ModeConfig **File:** `scripts/game_mode.gd` (41 lines) ``` enum Mode { FREEMODE = 0, STOP_N_GO = 1, TEKTON_DOORS = 2, GAUNTLET = 3 } ``` | Static Method | Returns | Description | |--------------|---------|-------------| | `from_string(mode: String)` | `Mode` | Converts "Freemode"/"Stop n Go"/"Tekton Doors"/"Candy Pump Survival" to enum | | `mode_to_string(mode: Mode)` | `String` | Reverse of from_string | | `is_restricted(mode: Mode)` | `bool` | true for STOP_N_GO, TEKTON_DOORS, GAUNTLET | | `get_all_modes()` | `Array[String]` | Returns display names | **File:** `scripts/mode_config.gd` (109 lines) SCHEMA defines per-mode settings with type, default, min, max, allowed values: | Mode | Settings | |------|---------| | Freemode | match_duration (180s default), randomize_spawn (bool), enable_cycle_timer (bool), scarcity_mode (Normal/Aggressive/Chaos) | | Stop n Go | match_duration, sng_go_duration (20s), sng_stop_duration (4s), sng_required_goals (8) | | Tekton Doors | match_duration, doors_swap_time (15s), doors_refresh_time (25s), doors_required_goals (8) | | Gauntlet | match_duration, gauntlet_growth_interval (3.0s), gauntlet_cells_per_tick (phase dict) | | Method | Args | Returns | |--------|------|---------| | `get_defaults(mode)` | String | Dictionary of defaults for that mode | | `validate_setting(mode, key, value)` | String, String, Variant | `{"valid": bool, "error": String}` | | `validate_config(mode, config)` | String, Dictionary | `{"valid": bool, "errors": Array}` | | `get_mode_settings(mode)` | String | Array of setting keys | | `get_setting_schema(mode, key)` | String, String | Dictionary with type/default/min/max/allowed | [Back to top](#top) ## Session Flow (all modes) 1. **Lobby** — players join, select mode + settings 2. **Game start** — `main.gd` calls `_setup_host_game()` which: - Creates arena (gridmap resize + clear) - Spawns mission tiles on Layer 1 - Calls mode manager's `start_game_mode()` 3. **Countdown** — brief timer then match begins 4. **Match active** — `GoalsCycleManager.start_match()` runs match timer + cycle timer 5. **Per-cycle** (30s): - Players grab tiles from grid → place on 5x5 playerboard - Match 3x3 pattern against 9-slot goals - Complete goals → B1000 score + new goals + tiles randomize around player - Cycle ends → board cleared, unmatched tiles scored at 10/tile match 6. **Match ends** — final leaderboard sync [Back to top](#top) ## Core Managers (shared) ### GoalManager (`scripts/managers/goal_manager.gd`, 108 lines) Generates 9-slot goal arrays using tile IDs 7-10 (Heart=7, Diamond=8, Star=9, Coin=10) with -1 for no-goal slots (~3 nulls per set). | Function | Returns | Description | |----------|---------|-------------| | `initialize_random_goals(size, min_value, max_value, null_count)` | `Array` | Random goals with controlled null distribution | | `generate_preset_goals(count)` | `Array` | Pre-generates N goal sets for all players | | `get_goals_for_player(player_index)` | `Array` | Returns goals for a specific player slot | | `mark_goal_start(player_id)` | void | Records timestamp for speed tracking | | `mark_goal_complete(player_id)` | void | Records completion duration | | `get_player_average_time(player_id)` | `float` | Average completion speed | | `get_global_average_time()` | `float` | Average across all players | | `get_boost_multiplier(player_id)` | `float` | 0.8-1.5x fill rate based on speed vs average | | `reset()` | void | Clears all state | ### GoalsCycleManager (`scripts/managers/goals_cycle_manager.gd`, 520 lines) Central scoring and timer system. Emits signals consumed by mode managers, UI, and leaderboard. | Signal | Payload | |--------|---------| | `cycle_started()` | — | | `cycle_ended()` | — | | `timer_updated(time_remaining)` | float | | `score_updated(peer_id, new_score)` | int, int | | `goal_count_updated(peer_id, count)` | int, int | | `leaderboard_updated(sorted_scores)` | Array | | `match_started()` | — | | `match_ended()` | — | | `global_timer_updated(time_remaining)` | float | | Function | Description | |----------|-------------| | `start_match(duration_seconds, start_cycles)` | Begins match timer, optionally starts first 30s cycle | | `_on_match_end()` | Processes final scores, syncs to clients | | `start_cycle()` | Begin 30s cycle, emit `cycle_started` | | `on_goal_completed(player, time_remaining)` | Entry point — routes to server or optimistic local path | | `_process_goal_completion(player, time_remaining)` | Server: award B1000 + time bonus, regen goals, randomize tiles | | `regenerate_goals_for_player(player)` | Generate new 9-slot goal set, sync via RPC | | `_randomize_tiles_around_player(player)` | Randomize 3x3 area around player on the grid | | `_process_cycle_end_for_all_players()` | Clear all boards, convert matches to B10/tile | | `add_score(peer_id, amount)` | Server: add arbitrary score points | | `_update_leaderboard()` | Sort by score descending (or with SNG winner override) | ### PlayerRaceManager (`scripts/managers/player_race_manager.gd`, 133 lines) State holder per player. Core logic is `check_pattern_match()`. | Function | Description | |----------|-------------| | `check_pattern_match()` | Returns true if any 3x3 sub-grid of 5x5 board matches 3x3 goals | | `check_3x3_section(board, goals, start_row, start_col)` | Checks single 3x3 section | | `_normalize_tile(tile)` | Converts holo tiles 11-14 → 7-10 for match comparison | | Remaining functions | DEPRECATED lap/finish line stubs | **Playerboard Layout:** 5x5 (indices 0-24). 13 cells are HIDDEN_SLOTS (cannot hold tiles). Only 12 usable slots arranged in an L-shape matching the HUD. ### PlayerboardManager (`scripts/managers/playerboard_manager.gd`, 793 lines) Handles grab, put, arrange operations with optimistic local updates + server-authoritative validation. | Function | Description | |----------|-------------| | `grab_item(grid_position)` | Grab tile from grid → place on board (auto-arrange) or consume as power-up | | `_execute_grab(grid_pos, cell, item_id, expected_slot)` | Server-side validation + state update + sync | | `_force_sync_to_client(cell, server_item)` | Revert client when server rejects grab | | `auto_put_item()` | AI/bot: find best tile to remove from board | | `find_best_goal_slot_for_item(item)` | Auto-arrange into best matching slot | | `bot_try_grab_item()` | AI grab logic | | `_check_and_refill_grid_if_needed(gridmap)` | Refill floor 1 via ScarcityController when empty | ### TurnManager (`scripts/managers/turn_manager.gd`, 27 lines) | Function | Description | |----------|-------------| | `next_turn(players)` | Advance turn index, emit `turn_changed` | | `end_current_turn()` | Emit `turn_ended` | | `reset_turn()` / `reset()` | Clear state | [Back to top](#top) ## Freemode **No dedicated manager.** Freemode relies entirely on the shared core managers (GoalsCycleManager, PlayerboardManager, etc.) with no mode-specific restrictions or gimmicks. Arena size is configurable via LobbyManager settings. **Settings effects:** - `enable_cycle_timer` false → cycle never expires (board never auto-clears) - `scarcity_mode` → controls tile refill aggression - `randomize_spawn` → players start at random positions [Back to top](#top) ## Stop n Go **Manager:** `StopNGoManager` (`scripts/managers/stop_n_go_manager.gd`, 1107 lines) A 23x12 arena with two alternating phases: ### Phase System | Phase | Duration (default) | Behaviour | |-------|-------------------|-----------| | GO | 20s | Players move freely, collect tiles, complete goals | | STOP | 4s | Players frozen if outside safe zone → tiles scattered | When STOP begins: 1. 3 dynamic safe zones spawn randomly (green tiles) 2. All players outside safe zone get `_scatter_player_tiles()` — board tiles scattered on grid 3. Power-up tiles (Speed=11, Ghost=14) spawn at 5 permanent locations 4. Mission requirement: complete 8 goals before reaching finish (x=22) When GO begins: 1. Dynamic safe zones cleared 2. All STOP freeze effects removed via `sync_stop_freeze(false)` ### Tile IDs | ID | Meaning | |----|---------| | 0 | Walkable floor | | 2 | Safe zone (green) | | 3 | Start/Finish line | | 4 | Wall/obstacle | | 15 | Lightning stone (decorative ancient rock) | | 16 | Safe zone wall | ### Arena 22x10 walkable area with two interior rooms with entrances: - Room 1: (7,6) to (11,9) — 5x4 area with 4 door entrances - Room 2: (15,1) to (19,5) — 5x5 area with 4 door entrances ### HUD - Center-bottom mission label: "GOALS (X/8)" or "ALL GOALS COMPLETE! REACH THE FINISH!" - Traffic light stop timer (3 segments): all empty during GO, fills red during STOP phase - Last 3 seconds of GO phase: segments light up one-by-one (countdown) - VFX: `vfx_manager.play_go_animation()` / `play_stop_phase()` ### RPCs | RPC | Direction | Description | |-----|-----------|-------------| | `sync_phase(phase_name, duration)` | Authority → all | Broadcast GO/STOP phase change | | `sync_arena_setup()` | Authority → remote | Sync 23x12 grid dimensions + obstacles | | `sync_all_safe_zones_vfx()` | Authority → all | Trigger safe zone visual effects | ### Key Functions (server-only unless noted) | Function | Description | |----------|-------------| | `start_game_mode()` | Server: setup arena, assign missions, start GO phase | | `_start_phase(phase)` | Transition GO↔STOP, penalize players outside safe zone | | `_setup_arena()` | Build 23x12 with obstacles + rooms | | `_spawn_mission_tiles()` | Heart(7)/Diamond(8)/Star(9)/Coin(10) at 60% density | | `_spawn_powerup_tiles()` | Speed(11)+Ghost(14) at 5 permanent locations | | `_assign_missions()` | NO-OP (mission = achievement: collect 8 goals) | | `activate_client_side()` | Client: show HUD, connect to GoalsCycleManager signals | | `rotate_players_to_start()` | Force all players to face East (PI/2) | | `can_rpc()` | Check multiplayer peer is connected | [Back to top](#top) ## Tekton Doors (Portal) **Manager:** `PortalModeManager` (`scripts/managers/portal_mode_manager.gd`, 585 lines) **Actor:** `PortalDoor` (`scripts/portal_door.gd`, 136 lines) A 14x14 grid divided into 4 rooms (7x7 each) by cross-shaped wall partitions. Players move between rooms via portal doors that swap connections every 15 seconds. ### Room Layout ``` Room 0 (NW) | Room 1 (NE) x: 0-6 | x: 7-13 z: 0-6 | z: 0-6 --------------+-------------- Room 2 (SW) | Room 3 (SE) x: 0-6 | x: 7-13 z: 7-13 | z: 7-13 ``` Central divider: columns 6,7 and rows 6,7 are walls (tile ID 4). ### Portal System - 10 doors total (2 base per room + 2 randomly placed extras) - Every 15s (`doors_swap_time`): `_randomize_connections()` shuffles pairings - Each pair gets a color from `PORTAL_COLORS` (Cyan/Magenta/Red/Green/Orange) - Validation ensures no pair connects doors in the same room - 200ms anti-jitter cooldown per player in `handle_portal_interaction()` ### PortalDoor (actor) | Property/Method | Description | |----------------|-------------| | `room_id` | Which room this door belongs to | | `door_id` | Unique door index | | `target_door_id` | Connected door (set by PortalModeManager) | | `portal_color` | Color (set triggers `set_portal_color`) | | `detection_area` | Area3D — body_entered triggers portal | | `_on_body_entered(body)` | 200ms cooldown, emit `player_entered_portal` | | `spawn_offset` | Vector2i meta — nudge spawn position into room | | `_adjust_indicator_position()` | Move GroundIndicator toward room interior | ### Finish Room - At 30s remaining on match timer, reveal `_spawn_finish_room()` - Random 3x3 area converted to finish tiles (ID 3) in one room - Player must be standing on finish tile AND have `doors_required_goals` complete ### Tile Refill - Every 25s (`tile_refresh_time`): `_refresh_tiles()` refills Floor 1 at 60% density - Uses `ScarcityModel.get_tile_weights()` for weighted random selection - Avoids spawning under portal doors ### HUD - Center-bottom: "GOALS (X/8)" or "ALL GOALS COMPLETE! FIND THE FINISH ROOM!" - Message broadcasts: "PORTALS SWITCHED!", "TILES REPLENISHED!" - Warning: "A 3x3 Finish Zone has appeared in Room N!" ### RPCs | RPC | Direction | Description | |-----|-----------|-------------| | `sync_portal_data(data)` | Authority → local | Sync connections + colors to all clients | | `sync_portal_configs(door_configs)` | Via main | Broadcast door positions/rotations | ### Key Functions | Function | Description | |----------|-------------| | `initialize(p_main, p_gridmap)` | Create swap timer + tile refresh timer, connect signals | | `start_game_mode()` | Setup arena, randomize connections, start timers | | `setup_arena_locally()` | Resize to 14x14, build room walls, spawn portal doors | | `_randomize_connections()` | Shuffle door pairings, assign colors, validate same-room rule | | `handle_portal_interaction(player, door)` | Teleport player to connected door + offset | | `_spawn_finish_room()` | Convert random 3x3 area to finish tiles | | `check_win_condition(player_id, pos)` | Check finish tile + mission complete | | `_refresh_tiles()` | Refill floor 1 items with scarcity weights | | `sync_to_client(peer_id)` | Sync portal connections to late-joining client | | `get_spawn_points()` | Returns 4 spawn positions (one per room quadrant) | [Back to top](#top) ## Candy Pump Survival (Gauntlet) **Manager:** `GauntletManager` (`scripts/managers/gauntlet_manager.gd`, 1825 lines) A 20x20 arena where sticky candy (pink) slowly grows from the edges inward over 3 phases. Players must navigate shrinking safe zones, avoid sticky tiles, and use the "Smack" ability to temporarily clear candy. ### Phase System | Phase | Start | Duration | Cell Growth (per tick) | Description | |-------|-------|----------|----------------------|-------------| | OPEN_ARENA (0) | 0s | 60s | 4-6 | "Outer Pressure" — candy pushes from perimeter | | ROUTE_PRESSURE (1) | 60s | 60s | 6-8 | "Middle Pressure" — corridors tighten | | SURVIVAL_ENDGAME (2) | 120s | 60s | 8-10 | "Inner Survival" — center fills in | Each phase transition shrinks the arena bounds by removing outer layers (via `_shrink_arena()`). ### Growth Algorithm Each tick (every `growth_interval` = 3s): 1. **Detect movement buffers** — identify critical corridor cells (#083) 2. **Generate candidates** — all SAFE cells scored by formula: ``` CandidateScore = LayerPriority + StickyNeighbor + InwardPressure + PlayerPressure + ClusterGrowth + CampingPressure + RandomNoise(-20..+20) + MovementBuffer + PathSafety + Repetition ``` 3. **Weighted selection** — pick `_cells_this_tick()` cells via roulette wheel 4. **Path safety check** — `_apply_path_safety()` ensures no player gets fully trapped 5. **Telegraph** — amber warning overlay appears for 1s (cells still passable) 6. **Apply** — cells convert to permanent STICKY (pink overlay on Layer 2) ### Scoring Components | Score Component | Range | Description | |----------------|-------|-------------| | `_score_layer_priority` | -40..+60 | Phase weight by ring (outer/middle/inner) | | `_score_sticky_neighbor` | 0..+64 | +8 per adjacent sticky cell (cap +64) | | `_score_inward_pressure` | 0..+30 | Push inward, scales with phase | | `_score_player_pressure` | -50..+20 | 2-4 cells away +20; under player -50 (+10 in final 30s) | | `_score_cluster_growth` | 0..+25 | +15 expansion, +25 bridge between clusters | | `_score_camping_pressure` | 0..+60 | Per-region: >5s +20, >8s +40, >10s +60 | | `_score_movement_buffer` | -40..0 | Hidden corridor buffers + player proximity floor | | `_score_path_safety` | -100..0 | Soft penalty if selection would strand a player | | `_score_repetition` | -30..0 | Penalty for cells near last tick's selection | ### Cell States | State | Meaning | Passable? | |-------|---------|-----------| | SAFE | Normal floor | Yes | | TELEGRAPHED | Amber warning (1s) | Yes | | STICKY | Permanent candy overlay | No (slows) | | BUBBLE_GROWING | Candy bubble expanding | No | | BLOCKED | NPC zone / permanent obstacle | No | ### Candy Bubble System (#082) Anti-camping hazard: grows 1x1 → 3x3 sticky area. | Phase | Max Bubbles | |-------|-------------| | OPEN_ARENA | 0 (disabled) | | ROUTE_PRESSURE | 2 | | SURVIVAL_ENDGAME | 3 | | Property | Value | |----------|-------| | Grow duration | 2.75s | | Explosion radius | 1 (3x3) | | Recent memory | 4 positions | | Anti-stack radius | 3 (no bubbles within 3 of recent) | ### Camping Detection (#073) Players tracked in 4x4 regions. Time accumulates while player stays in same region, resets on region change. Drives camping pressure in candidate scoring. ### Movement Buffers (#083) Hidden per-cell penalties on critical corridor cells (chokepoints where removing the cell would isolate part of the arena). Decay over time and phase transitions so arena can still close in. ### Smack Mechanic | Property | Value | |----------|-------| | Cooldown | 8s | | Charge window | 3s | | Effect | Clears nearby sticky? (consumes charge) | Per-player cooldown/charge tracked in `smack_cooldowns` / `smack_charged` Dictionaries. Pink modulate during charge window, white on cooldown. ### Arena NPC Candy Pump NPC at center (9,9) in a 3x3 blocked zone. Visual-only in v2 (projectile logic removed). Scattered projectiles still spawned for visual effect during telegraph phase. ### Slow-Mo - Triggered conditionally, duration 4s - `Engine.time_scale = 0.25` (1/4 speed) - Restored to 1.0 in `_exit_tree()` ### Spawn Points | Player Count | Positions | |-------------|-----------| | 4 | 4 corners: (1,1), (18,1), (1,18), (18,18) | | 5-6 | 4 corners + top-mid (10,1) + bottom-mid (10,18) | | 7-8 | 4 corners + all 4 mid-edges | ### RPCs | RPC | Direction | Description | |-----|-----------|-------------| | `sync_phase(phase_index, phase_name)` | Authority → local | Phase change broadcast | | `sync_arena_setup()` | Authority → remote | Arena dimensions + layout | | `sync_growth_telegraph(cells)` | Authority → local | Show amber warning on selected cells | | `sync_growth_apply(cells)` | Authority → local | Convert telegraphed to sticky | | `consume_smack(pid)` | Any peer → local | Smack consumption + animation | | `sync_stop_freeze` | (inherited from player.gd) | Freeze/unfreeze player | ### Key Functions | Function | Description | |----------|-------------| | `initialize(main, grid)` | Connect to GoalsCycleManager | | `start_game_mode()` | Activate client side, start OPEN_ARENA phase | | `_setup_arena()` | Build 20x20, spawn Candy Pump NPC | | `_process_growth_tick()` | One growth cycle: score → select → telegraph → apply | | `_generate_candidates()` | Score all SAFE cells | | `_calculate_candidate_score(pos, player_cells)` | Full formula with 10 components | | `_select_cells_weighted(candidates, count)` | Roulette-wheel selection | | `_apply_path_safety(selected)` | Filter: ensure no player stranded | | `_try_spawn_bubble()` | Anti-camping bubble spawn attempt | | `_update_camp_tracking(delta)` | Per-player region residency timer | | `_detect_movement_buffers()` | Identify critical corridor chokepoints | | `_shrink_arena()` | Remove outer arena layers on phase change | | `_spawn_mission_tiles()` | Heart/Diamond/Star/Coin at 60% density | | `get_spawn_points(player_count)` | Return spawn positions by player count | | `has_smack_charged(pid)` / `consume_smack(pid)` | Smack mechanic | | `_spawn_telegraph_highlight(pos)` | Amber glow visual (2-stage: build-up + flash) | | `_spawn_impact_particles(targets)` | Candy splash particles on sticky impact | | `_check_all_players_trapped()` | Re-evaluate sticky traps after growth apply | [Back to top](#top) ## Scoring & Leaderboard | Action | Points | |--------|--------| | Complete goal pattern (match 3x3) | B1000 + time bonus | | Tile match at cycle end (per tile) | B10 | | Time bonus formula | `int(time_remaining * TIME_BONUS_MULTIPLIER)` — currently 0 (flat 1000) | Leaderboard sorted descending. Stop n Go special case: winner (first to reach finish) placed at top regardless of score. Leaderboard signal payload: ``` [{"peer_id": int, "score": int}, ...] ``` [Back to top](#top) ## Glossary | Term | Definition | |------|------------| | Goal | 3x3 pattern (9 slots, some -1 for null) player must match on their playerboard | | Playerboard | 5x5 virtual grid (12 usable slots, 13 hidden) per player | | Tile | Grid item on Floor 1: Heart(7), Diamond(8), Star(9), Coin(10) | | Holo Tile | Power-up tiles: Speed(11), Ghost(14) — consumed on pickup, not placed on board | | Cycle | 30-second scoring round; ends with board clear + point conversion | | Sticky | Permanent pink overlay on Gauntlet floor cells — blocks/slows movement | | Telegraph | Amber 1-second warning before a cell becomes sticky | | Safe Zone | Green tiles in Stop n Go STOP phase — only safe tile type | | Portal | Colored door connecting rooms in Tekton Doors | | Scarcity | Tile refill model controlling spawn weights based on mode config | | Smack | Gauntlet ability: clear nearby sticky (8s cooldown, 3s charge window) | | Camping | Player staying in same 4x4 region >5s, attracts growth pressure | | Movement Buffer | Hidden chokepoint corridor that growth algorithm avoids sealing early | | Chebyshev Distance | `max(|x1-x2|, |y1-y2|)` — used for all proximity calculations | [Back to top](#top) ## File Index | File | Lines | Role | |------|-------|------| | `scripts/game_mode.gd` | 41 | Mode enum + helper functions | | `scripts/mode_config.gd` | 109 | Schema-driven per-mode settings | | `scripts/managers/goal_manager.gd` | 108 | Goal generation + speed tracking | | `scripts/managers/goals_cycle_manager.gd` | 520 | Timer, scoring, cycle control | | `scripts/managers/player_race_manager.gd` | 133 | Per-player state: goals, board, pattern matching | | `scripts/managers/playerboard_manager.gd` | 793 | Grab/put/arrange operations | | `scripts/managers/turn_manager.gd` | 27 | Turn-based flow | | `scripts/managers/stop_n_go_manager.gd` | 1107 | Stop n Go phase system, safe zones, HUD | | `scripts/managers/portal_mode_manager.gd` | 585 | Tekton Doors room layout, portals, tiles | | `scripts/managers/gauntlet_manager.gd` | 1825 | Candy Pump Survival growth, phases, smack | | `scripts/portal_door.gd` | 136 | PortalDoor actor — detection, teleport, visuals | | `scripts/managers/goals_cycle_manager.gd` | (shared) | Also referenced by gauntlet signal connections | | `scripts/managers/camera_context_manager.gd` | ... | Camera mode changes per game mode? | | `scripts/managers/player_movement_manager.gd` | ... | Movement restrictions per mode | [Back to top](#top)