Technical Documentation

Candy Cannon Survival

Gauntlet Mode โ€” Implementation blueprint mapping GDD mechanics to existing Tekton Dash systems

70%
Code Reuse
4
New Files
7
Modified Files
12
New Terms
10
Reused Terms

๐Ÿ“– Glossary

All terms used in Gauntlet mode โ€” categorized by whether they're new, adapted, or already implemented in Tekton Dash.

New โ€” unique to Gauntlet
Adapted โ€” modified from existing mechanic
Existing โ€” already in game, reused as-is
๐Ÿฌ

Sticky Cell New

A grid cell hit by the Candy Cannon that becomes impassable. Players stepping onto or pushed into a sticky cell are trapped. Remains until cleansed or round ends. Rendered as Layer 2 overlay (pink translucent mesh, ID 17).

TILE_STICKY = 17 โ†’ GridMap Layer 2
โšก

Telegraph New

1-second warning before cannon impact. Target cell glows pink/candy color with a shadow preview and charge-up sound. Uses temporary overlay tile (ID 18) on Layer 2, animated alpha 0โ†’1 over 0.8s, then replaced by Sticky Cell on impact.

TILE_TELEGRAPH = 18 โ†’ rpc("sync_telegraph")
๐Ÿ’ฅ

Candy Cannon New

Central NPC occupying a permanent 3ร—3 zone at arena center. Fires volleys of 5 candy shots every 5 seconds, creating sticky cells. Static body โ€” cannot be grabbed, thrown, or interacted with. Not a Tekton โ€” it's a dedicated hazard entity.

CandyCannonController โ†’ candy_cannon.tscn
๐ŸŽฏ

Volley New

A batch of 5 simultaneous cannon shots fired at different target cells. One volley fires every 5 seconds (36 total over 3 minutes = 180 impacts). Each shot in a volley has an independent impact size roll (1ร—1, 1ร—2, or 2ร—2).

_fire_volley() โ†’ cannon_interval = 5.0
๐Ÿ“

Impact Size New

The footprint of each cannon shot. Three sizes: 1ร—1 (single cell), 1ร—2 (two adjacent), 2ร—2 (four cells square). Distribution changes per phase โ€” early favors 1ร—1, endgame favors 2ร—2.

phase_weights[phase_idx]["2x2"]
๐Ÿชค

Trapped New

Player state when standing on a sticky cell. Cannot move normally. Escape only via Cleanser power-up. Players can be trapped by stepping onto sticky, being pushed into sticky, or direct cannon hit. Trapped players keep their score but are out of active play.

trapped_players: Dict โ†’ rpc("sync_trapped")
โœจ

Cleanser New

Power-up earned by completing 2 missions. Allows 5 cells of movement through sticky candy, cleansing traversed cells back to walkable. Inventory limit: 1. Cannot activate while stunned. 0.3s activation delay.

player_cleansers[peer_id] โ†’ GoalsCycleManager signal
๐Ÿ’ซ

Clash New

When two players activate Smack simultaneously (within 0.5s) and are in range of each other. Both get stunned for 1.0s, no push occurs, both smack bars are consumed. Server-authoritative timestamp comparison.

clash detection โ†’ 0.5s window, server authority
๐Ÿ”‹

Charged State New

3-second window after Smack activation where the player model turns pink. If a target enters range during this window, the smack triggers. If no target is hit within 3s, energy is consumed with no effect.

smack_charged[player_id] โ†’ 3.0s window
โš–๏ธ

Anti-Unfairness New

Targeting rules preventing the cannon from feeling random/cheap. No same-player twice in a row, 2ร—2 never directly on player, path validation ensures escape routes exist (except final 30s). Uses AStar pathfinding.

last_targeted_player_id โ†’ EnhancedGridMap.initialize_astar()
๐Ÿšง

Route Blocking New

Cannon targeting strategy (25% chance) that places sticky cells on pathfinding bottlenecks โ€” narrow corridors between sticky regions. Forces players to reroute. Calculated using EnhancedGridMap neighbor analysis.

_get_route_blocking_target() โ†’ 25% weight
๐ŸŸ๏ธ

Gauntlet Arena New

20ร—20 cell arena with 391 playable cells (400 minus 3ร—3 NPC zone). Players spawn at outer edges/corners. Target: 80% sticky coverage by round end (313 cells), leaving ~78 safe cells.

ARENA_SIZE = 20 โ†’ gauntlet.tscn
๐Ÿ‘Š

Smack Adapted

Gauntlet-specific melee push. Adapts existing try_push() from Attack Mode but replaces boost-meter gating with 8s auto-refill cooldown, adds 3s charged window, sticky landing trap, and clash detection. Push distance: 3 cells.

PlayerMovementManager.try_push() โ†’ smack_cooldowns
โฑ๏ธ

Phase Adapted

Three escalation phases in Gauntlet: Open Arena (0โ€“60s), Route Pressure (60โ€“120s), Survival Endgame (120โ€“180s). Adapts StopNGoManager's Go/Stop phase pattern but uses time-elapsed triggers instead of cycle signals.

enum Phase { OPEN_ARENA, ROUTE_PRESSURE, SURVIVAL_ENDGAME }
๐Ÿค–

Bot AI โ€” Cannon Avoidance Adapted

Extends BotStrategicPlanner with Gauntlet-specific logic: telegraph awareness, sticky path planning, safe-zone pathfinding. Adapts existing bot movement heuristics to factor in shrinking arena.

BotStrategicPlanner โ†’ new evaluate_gauntlet()
โš”๏ธ

Attack Mode Existing

Existing player state toggled via PowerUpManager when boost bar is full. In Gauntlet, not used directly โ€” replaced by Smack mechanic. The push physics from try_push() are reused but the activation logic differs.

PowerUpManager.is_attack_mode โ†’ NOT used in Gauntlet
๐Ÿ˜ต

Stagger Existing

Existing 1.5s movement disable after being push-attacked. Gauntlet's Smack uses a shorter 1.0s stun, but the underlying apply_stagger() function is reused with a duration parameter.

PlayerMovementManager.apply_stagger(duration)
๐ŸŽฏ

Mission / Goals Existing

3ร—3 pattern-matching tile collection system. Reused as-is from GoalManager + GoalsCycleManager. In Gauntlet, completing every 2 missions also triggers Cleanser unlock (new hook on existing signal).

GoalManager โ†’ GoalsCycleManager.goal_count_updated
๐Ÿ—‚๏ธ

Layer 2 Overlay Existing

GridMap's Y=2 layer used for visual overlays (safe zones in Stop N Go, freeze in Freemode, highlights). Gauntlet uses it for Sticky Cell and Telegraph meshes. No conflict โ€” modes are mutually exclusive.

GridMap.set_cell_item(Vector3i(x, 2, z), id)
๐Ÿซธ

try_push() Existing

Player push mechanic in PlayerMovementManager. Pushes target 3 cells backward. Gauntlet's Smack wraps this with direction-based push, sticky landing detection, and clash rules.

PlayerMovementManager.try_push(target, direction)
๐Ÿ“ณ

Screen Shake Existing

Camera shake effect triggered via RPC. Used on cannon impact with "medium" intensity. Already implemented system-wide.

player.rpc("trigger_screen_shake", "medium")
๐ŸŽช

Tekton Projectile Existing

Arc-tween projectile from Tekton NPC. Candy Cannon reuses this exact visual pattern (spawn_projectile_rpc) โ€” creating a mesh, arc-tweening position, then freeing on arrival.

tekton.gd โ†’ spawn_projectile_rpc(target, duration)
๐Ÿ“ก

RPC Sync Pattern Existing

Server-authoritative state sync via @rpc("authority", "call_local", "reliable"). All Gauntlet state changes (sticky, phase, trap, cleanser) use this identical pattern.

@rpc("authority", "call_local", "reliable")
โฐ

Timed Match Existing

Global match timer from GoalsCycleManager. Gauntlet passes 180s duration. System handles countdown, HUD timer, and match-end trigger.

goals_cycle_manager.start_match(180.0)
๐Ÿ’Ž

SpecialTilesManager Existing

Handles power-up tiles, inventory, and effects. Gauntlet restricts certain powerups (like Stop N Go restrictions) and adds Cleanser as a new inventory slot via the existing signal/slot system.

SpecialTilesManager.inventory โ†’ mode-based restrictions

๐Ÿ—๏ธ Architecture

How GauntletManager slots into the existing manager tree, following the StopNGoManager pattern exactly.

main.gd
โ”œโ”€โ”€ _init_managers() โ† instantiate GauntletManager
โ”œโ”€โ”€ _setup_host_game() โ† arena setup branch
โ”œโ”€โ”€ _start_game() โ† start_game_mode() call
โ”‚
GauntletManager NEW
โ”œโ”€โ”€ _setup_arena() โ† 20ร—20 grid, center 3ร—3 NPC zone
โ”œโ”€โ”€ _setup_hud() โ† mission label, cleanser indicator
โ”œโ”€โ”€ start_game_mode() โ† start cannon timer, spawn tiles
โ”œโ”€โ”€ _process() โ† cannon volley timer, phase escalation
โ”œโ”€โ”€ CandyCannonController NEW โ† targeting, volley fire
โ”œโ”€โ”€ StickyCell system NEW โ† Layer 2 overlay, trap logic
โ”œโ”€โ”€ Cleanser system NEW โ† powerup via missions
โ”œโ”€โ”€ Smack system NEW โ† modified push with charge/cooldown
โ””โ”€โ”€ Win condition โ† highest score at timer end

โ™ป๏ธ Reuse Map

How each GDD feature maps to existing systems โ€” showing what's reused vs what's new.

GDD FeatureExisting SystemReuseNew Work
Game Mode RegistrationGameMode.gd + LobbyManagerDirectAdd enum + strings
20ร—20 ArenaStopNGoManager._setup_arena()HeavyCustom layout, same API
Tile Collection / ScoringGoalsCycleManagerDirectReuse as-is
Mission SystemGoalManager + goals_cycle_managerDirectSame 3ร—3 pattern matching
Timed MatchGoalsCycleManager.start_match()DirectPass 180s duration
Player MovementPlayerMovementManagerDirectNo changes
Powerup SystemSpecialTilesManagerPartialCleanser = new type
Smack MechanicPlayerMovementManager.try_push()AdaptModified push rules
Candy Cannon NPCtekton.gd + TektonControllerPatternNew NPC, reuses projectile
Sticky CellsStopNGoManager safe zone overlayPatternNew tile type, same layer
Telegraph VFXVFXManager / animation.gdPatternNew animations, same system
HUDStopNGoManager._setup_hud()DirectMode-specific labels
Network SyncRPC patternsDirectSame patterns
Lobby SettingsLobbyManager signal/syncDirectGauntlet settings
Bot AIBotController + BotStrategicPlannerAdaptCannon avoidance strategy

๐ŸŒŠ Phase Timeline

Three escalation phases that control cannon intensity and impact size distribution.

0:00 โ€” 1:00

Open Arena

  • Collect tiles, learn the mission
  • Slow candy pressure
  • 1ร—1 shots: 60%
  • 1ร—2 shots: 40%
  • 2ร—2 shots: 0%
  • ~60 impacts total
1:00 โ€” 2:00

Route Pressure

  • Candy shapes arena topology
  • Smack becomes dangerous
  • 1ร—1 shots: 30%
  • 1ร—2 shots: 55%
  • 2ร—2 shots: 15%
  • Cleanser used strategically
2:00 โ€” 3:00

Survival Endgame

  • ~80% arena is sticky
  • Safe zones limited, high tension
  • 1ร—1 shots: 15%
  • 1ร—2 shots: 55%
  • 2ร—2 shots: 30%
  • Aggressive route-blocking allowed

โš™๏ธ Core Systems

Deep-dive into the four new systems and how they integrate.

๐Ÿฌ Sticky Cell System

FeatureImplementation
VisualLayer 2 overlay โ€” transparent candy-pink mesh (ID 17)
Movement BlockPlayerMovementManager.simple_move_to() โ€” add sticky check alongside wall check
Trap on StepGauntletManager._check_player_on_sticky() in _process()
Trap on PushPlayerMovementManager.try_push() โ€” check landing cell
Cleanser BypassTemporary flag (like is_invisible wall bypass)
Network Syncmain.rpc("sync_grid_item", x, 2, z, 17)

๐Ÿ‘Š Smack vs Attack Mode

PropertyCurrent Attack ModeGauntlet Smack
Charge SourceBoost bar fills to 1008s auto-refill cooldown
ActivationToggle is_attack_mode3s charged window (pink model)
Push Distance3 cells backward3 cells in push direction
Stagger Duration1.5s apply_stagger()1.0s stun
Sticky LandingN/ATrapped on first sticky cell
Clash RuleN/ABoth stunned, no push, bars consumed

โœจ Cleanser Power-Up

PropertyValue
Unlock TriggerGoalsCycleManager.goal_count_updated โ†’ count % 2 == 0
StorageGauntletManager.player_cleansers[peer_id] = 1
Effect5 cells movement through sticky โ€” crossed cells become passable
Syncrpc("sync_cleanser_state", peer_id, count)
Clear Stickymain.rpc("sync_grid_item", x, 2, z, -1)
Inventory Limit1 per player

๐ŸŽฏ Cannon Targeting Intelligence

Roll %Target StrategyPurpose
60%Near a player (not same as last)Direct pressure
25%Route-blocking bottleneckCut escape paths
10%Random non-sticky areaSpread coverage
5%Previously sticky / chaosUnpredictability

๐Ÿ“ File Changes

New Files

๐Ÿ“œ

gauntlet_manager.gd

Core mode logic, phases, sticky cells, cleanser, smack

๐Ÿ“œ

candy_cannon_controller.gd

Cannon targeting, volley fire, telegraph

๐ŸŽฌ

gauntlet.tscn

3D arena environment scene

๐ŸŽฌ

candy_cannon.tscn

Candy Cannon NPC (3ร—3, static)

Modified Files

โœ๏ธ

game_mode.gd

Add GAUNTLET = 3 enum, string mappings

โœ๏ธ

lobby_manager.gd

Mode list, gauntlet settings, area mapping

โœ๏ธ

main.gd

Manager init, arena setup branch, start branch

โœ๏ธ

player_movement_manager.gd

Sticky check in move + push

โœ๏ธ

goals_cycle_manager.gd

Cleanser grant on 2nd goal

โœ๏ธ

special_tiles_manager.gd

Gauntlet powerup restrictions

โœ๏ธ

MeshLibrary .tres

Add TILE_STICKY (17) and TILE_TELEGRAPH (18)

๐Ÿ“ก Network Sync

All sync follows existing RPC patterns โ€” no new networking paradigms needed.

DataSync MethodExisting Pattern
Sticky Cellsmain.rpc("sync_grid_item", x, 2, z, 17)Safe zone / freeze overlay
Telegraphrpc("sync_telegraph", targets_array)StopNGoManager.sync_phase()
Phase Changesrpc("sync_gauntlet_phase", idx, elapsed)StopNGoManager.sync_phase()
Trap Stateplayer.rpc("sync_trapped", true)player.rpc("sync_stop_freeze")
Cleanser Grantrpc("sync_cleanser", peer_id, count)goals_cycle_manager.sync_goal_count()
Smack Stateplayer.rpc("sync_smack_state", charged)player.rpc("sync_modulate")
Cannon NPCStatic scene โ€” no movement sync needed

๐Ÿ“‹ Implementation Priority

1

Game Mode Registration

game_mode.gd, lobby_manager.gd, main.gd

2

Arena Setup

gauntlet_manager._setup_arena(), 20ร—20 grid

3

Tile Spawning

StopNGoManager._spawn_mission_tiles() pattern

4

Cannon Timer + Volley

5s interval, 5 shots, 1ร—1 only

5

Sticky Cell System

Layer 2 overlay, movement block, trap detection

6

Telegraph VFX

Warning glow โ†’ impact transition

7

Impact Sizes

1ร—2 and 2ร—2 shapes, phase weights

8

Smack Mechanic

Modified push with cooldown/charge

9

Cleanser

Unlock tracking, sticky bypass

10

Targeting Intelligence

Player proximity, route blocking, anti-unfairness

11

Bot AI

Cannon avoidance, sticky path planning

12

Polish

VFX, SFX, HUD animations, 3D scene

โš ๏ธ Risk Assessment

๐Ÿ—‚๏ธ

Layer 2 Conflict

GridMap Layer 2 used by freeze/safe overlays. Mitigated: Gauntlet mode is exclusive โ€” no freeze/safe tiles exist.

๐Ÿ“Š

20ร—20 Grid Performance

400 cells + overlays. Mitigated: Existing 23ร—12 and 14ร—14 arenas work fine; 20ร—20 comparable.

๐Ÿšซ

Impossible Arenas

Cannon could seal all paths. Mitigated: AStar pathfinding check before each volley.

๐Ÿ”ข

MeshLibrary ID Collision

IDs 17โ€“18 might exist. Mitigated: Verify max ID in .tres before adding.

โฑ๏ธ

Smack Clash Timing

Network latency affects clash detection. Mitigated: Server-authoritative timestamp, 0.5s window.