NEVER Do (Expert Anti-Patterns)
Networking & Authority
- NEVER trust the client for damage calculation or resource costs; strictly validate mana, ranges, and hit detection on the authoritative server using
multiplayer.is_server(). - NEVER use
TRANSFER_MODE_RELIABLEfor continuous movement; strictly useUNRELIABLEorUNRELIABLE_ORDEREDfor position/velocity to prevent network congestion. - NEVER sync units at 60Hz; strictly use a lower tick rate (10-20Hz) via
MultiplayerSynchronizerand implement Interp/Client-Side Prediction for visual smoothness. - NEVER attach individual synchronizers to hundreds of minions; strictly batch state updates into compressed byte arrays via a central manager.
- NEVER synchronize complex Engine objects directly; strictly serialize state into primitive properties or Dictionaries for reliable peer-to-peer sync.
AI & Pathfinding
- NEVER use expensive pathfinding for all minions every frame; strictly use Time Slicing to spread
get_next_path_position()calls across multiple frames. - NEVER query
NavigationAgentpaths inside_process(); strictly use_physics_process()to interact with the navigation server and avoidance systems. - NEVER use complex visual geometry for NavMesh baking; parse simple primitives to avoid stalling the
RenderingServeror crashing the engine. - NEVER set
path_search_max_polygonstoo low in large maps; agents will stop or walk incorrectly if the limit is reached before the destination. - NEVER use
Area2Dfor high-performance Fog of War LOS; strictly use nodeless physics queries (intersect_ray) to bypass node overhead.
Gameplay & Balancing
- NEVER forget Tower "Dive" protection; towers MUST switch targets immediately if an enemy Hero damages an allied Hero within range (Priority: Hero attacking Ally > Minion > Hero).
- NEVER allow "Snowballing" without counter-play; strictly implement Comeback Mechanisms (Kill Bounties, Catch-up XP) to maintain competitive tension.
- NEVER manage hero stats as standard Node variables; strictly use custom
Resourcescripts for data separation and memory efficiency. - NEVER forget to call
duplicate(true)on shared ability Resources; modifying a buff on a shared resource will affect all heroes globally.
Technical & Performance
- NEVER use standard strings for status checks (e.g., "stunned"); strictly use
StringName(&"stunned") for pointer-speed comparisons. - NEVER loop over massive Fog of War grids with floats; strictly use
Vector2iandTileMapLayerto prevent precision jitter. - NEVER execute heavy world/minimap logic on the main thread; strictly offload complex array math to
WorkerThreadPoolto maintain 60+ FPS. - NEVER rigidly couple UI cooldowns to Hero scripts; strictly use a Signal Bus or
Callablebindings for decoupled architecture. - NEVER evaluate exact floating-point equality (==); strictly use
is_equal_approx()for range, cooldown, and mana validations.
Decision Tree: Solo prototype vs authoritative 5v5
| Goal | Load first | Skip / defer |
|---|---|---|
| Solo lane prototype (1 hero, local waves, no peers) | tower_priority_aggro.gd, weighted_target_selector.gd, skill_shot_indicator.gd, hero_state_machine.gd | server_minion_sync, full fog grid, prediction |
| Authoritative 5v5 (dedicated/listen server) | server_minion_sync.gd, synced_ability_controller.gd, fog_visibility_check.gd + fog_grid_mask.gd, minion_worker_pathfinder.gd | Client-trusted damage, per-minion MultiplayerSynchronizer |
| Peer skill | godot-multiplayer-networking, godot-navigation-pathfinding, godot-ability-system | Inventing a second networking stack inside this genre skill |
🛠 Expert Components (scripts/)
Original Expert Patterns
- skill_shot_indicator.gd - Mouse-driven targeting system for range, width, and direction visualization.
- tower_priority_aggro.gd - Advanced AI for defensive towers following competitive priority rules. MANDATORY for tower dive/priority.
Modular Components
- server_minion_sync.gd - Authoritative sync for high-count units using compressed byte arrays. MANDATORY for 5v5 waves (not one synchronizer per minion).
- fog_visibility_check.gd - Physics raycasting for high-performance Line-of-Sight checks. MANDATORY before fog mask painting.
- fog_grid_mask.gd - TileMap-driven visibility masking system using Vector2i grid logic.
- minion_worker_pathfinder.gd - When to load: WorkerThreadPool path batches when wave size leaves
_physics_processpathfinding. Prefer over per-minion full A* every frame. - weighted_target_selector.gd - When to load: hero/minion/tower acquisition with group-weighted priority (AA and simple aggro). Pair with tower_priority for dive rules.
- synced_ability_controller.gd - When to load: QWER casts under authority — client predicts cooldown UI, server validates. Skip for offline prototypes.
- status_effect_data.gd - Lightweight Resource container for defining buffs, debuffs, and stuns.
- status_effect_manager.gd - Modular logic for applying and managing unique status effect instances.
- decoupled_ability_damage.gd - Inter-hero combat interaction using safe duck-typing patterns.
- hero_state_machine.gd - Optimized StringName-based state machine for hero logic.
- async_arena_baker.gd - Background thread-safe navigation mesh updates for dynamic arenas.
- ability_ui_binder.gd - Signal-based UI decoupling for ability cooldown tracking.
- minion_flow_calculator.gd - Parallelized pathing and intelligence using WorkerThreadPool.
- replay_manager.gd - Binary
var_to_bytesmatch replay frames (not JSON). - hero_net_sync.gd - Physics interpolation + MultiplayerSynchronizer hero sync at low tick.
- jungle_creep.gd - Camp leash FSM — invulnerable return home beyond
leash_radius.
Core Loop
- Lane: Player farms minions for gold/XP in a designated lane.
- Trade: Player exchanges damage with opponent hero.
- Gank: Player roams to other lanes to surprise enemies.
- Push: Team destroys towers to open the map.
- End: Destroy the enemy Core/Nexus.
Skill Chain
| Phase | Skills | Purpose |
|---|---|---|
| 1. Control | rts-controls | Right-click to move, A-move, Stop |
| 2. AI | godot-navigation-pathfinding | Minion waves, Tower aggro logic |
| 3. Combat | godot-ability-system, godot-rpg-stats | QWER abilities, cooldowns, scaling |
| 4. Network | godot-multiplayer-networking | Authority, lag compensation, prediction |
| 5. Map | godot-3d-world-building | Lanes, Jungle, River, Bases |
| 6. Balance | godot-monte-carlo-balancer | Hero/asymmetry matrix (not sole AFK→pro) |
Architecture Overview
1. Lane / Minion Waves (authoritative)
Do not invent inline lane_manager / minion_ai samples.
MANDATORY reads: server_minion_sync.gd for batched wave state; minion_worker_pathfinder.gd when agent count needs WorkerThreadPool; weighted_target_selector.gd for march→combat target picks. Spawn cadence stays data/timer-driven on the server; clients render from sync arrays.
2. Tower Aggro Logic
Priority: Hero attacking Ally > unit attacking Ally Hero > closest minion > closest hero.
MANDATORY read: tower_priority_aggro.gd. Compose with weighted_target_selector.gd for group ranks.
3. Fog of War
MANDATORY read: fog_visibility_check.gd for nodeless LoS; paint results into fog_grid_mask.gd. Never use
Area2Doverlap as the fog oracle.
4. Skill-Shot Ability Cycle
Implementation pattern for "QWER" targeting:
- Idle: Waiting for input.
- Telegraphed: Show indicator (skill_shot_indicator.gd) while mouse is held.
- Active: Spawn hitbox/projectile on release — under multiplayer, route through synced_ability_controller.gd.
- Recovery: Brief backswing animation where movement/casting is locked.
Key Mechanics Implementation
Click-to-Move (RTS Style)
Raycasting from camera to terrain.
gdscriptfunc _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("move"): var result = raycast_from_mouse() if result: nav_agent.target_position = result.position
Ability System (Data Driven)
Defining "Fireball" or "Hook" without unique scripts for everything.
gdscript# ability_data.gd class_name Ability extends Resource @export var cooldown: float @export var mana_cost: float @export var damage: float @export var effect_scene: PackedScene
Godot-Specific Tips
- NavigationAgent3D: Use
avoidance_enabledfor minions so they flow around each other like water, rather than stacking. - MultiplayerSynchronizer: Sync Health, Mana, and Cooldowns. Do NOT sync position every frame if using Client-Side Prediction (advanced).
- Fog of War: Use a
SubViewportwith a fog texture. Paint "holes" in the texture where allies are. Project this texture onto the terrain shader.
Common Pitfalls
- Snowballing: Winning team gets too strong too fast. Fix: Implement "Comeback XP/Gold" mechanisms (bounties).
- Pathfinding Lag: 100 minions pathing every frame. Fix: Distribute pathfinding updates over multiple frames (Time Slicing).
- Hacking: Client says "I dealt 1000 damage". Fix: Client says "I cast Spell Q at Direction V". Server calculates damage.
Advanced MOBA Meta-Systems
Professional implementation of match playback, network smoothing, and advanced jungle AI.
1. Match Replay System (Binary Serialization)
For high-performance match recording, use var_to_bytes() to serialize state dictionaries into a compressed binary format. Avoid JSON for replays to minimize disk I/O and file size.
gdscriptclass_name ReplayManager extends Node var frame_history: Array[PackedByteArray] = [] func record_frame(state: Dictionary) -> void: # Efficiently convert data to bytes frame_history.append(var_to_bytes(state)) func save_replay(match_id: String) -> void: var file := FileAccess.open("user://replays/" + match_id + ".dat", FileAccess.WRITE) if file: file.store_var(frame_history) # Stores the whole array as a variant file.close() func play_frame(frame_index: int) -> Dictionary: return bytes_to_var(frame_history[frame_index])
2. Networked Interpolated Sync
Use Godot 4.x's built-in physics interpolation to mask network jitter. Combined with MultiplayerSynchronizer, this provides smooth hero movement even at low tick rates (15-20Hz).
gdscriptclass_name HeroNetSync extends CharacterBody3D func _ready() -> void: # Enable native engine interpolation for visual smoothness physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_ON if is_multiplayer_authority(): setup_synchronizer() func setup_synchronizer() -> void: var sync := $MultiplayerSynchronizer var config := SceneReplicationConfig.new() # Sync position/rotation via unreliable ordered packets config.add_property(NodePath(".:global_position")) sync.replication_config = config
3. Jungle-AI (Camp Leashing)
Implement a state machine for jungle monsters that monitors distance from their spawn point. If a hero draws them too far, they enter a "Leashing" state, becoming invulnerable and returning home.
gdscriptclass_name JungleCreep extends CharacterBody3D @export var leash_radius: float = 12.0 @onready var spawn_pos := global_position func _physics_process(_delta: float) -> void: var dist_from_home := global_position.distance_to(spawn_pos) match state: State.CHASING: if dist_from_home > leash_radius: state = State.LEASHING State.LEASHING: # Move back to spawn_pos using NavigationAgent3D nav_agent.target_position = spawn_pos if global_position.distance_to(spawn_pos) < 1.0: state = State.IDLE health = max_health # Reset health on return
Expert Tip: Always use NavigationServer3D.map_get_iteration_id() to ensure the navigation map is fully synced before allowing AI to pathfind after spawning.
MANDATORY for depth beyond decision trees and script catalog: moba-meta-systems-deep.md. Do NOT Load on first-pass wiring — use bundled
scripts/first.
Reference
Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing work to a peer domain — do not preload the whole lattice.
Official Documentation
- High-level multiplayer — Authority, RPCs, and transfer modes for server-validated casts and unreliable movement.
- MultiplayerSynchronizer — Property replication for hero health/mana/cooldowns without per-minion synchronizer spam.
- SceneReplicationConfig — Which properties replicate and how often when pairing with low tick-rate hero sync.
- Using NavigationAgents — Click-to-move, minion march, and avoidance for lane flow without stacking.
- Using navigation meshes — Baking lanes/jungle/bases and async rebake when arena geometry changes.
- Optimizing navigation performance — Time-slicing and agent budgets when hundreds of minions path each wave.
- Ray-casting — Click-to-ground picking and nodeless fog LOS via direct space-state rays.
- Physics interpolation introduction — Smooth hero visuals when network sync runs at 10–20 Hz.
- Using Viewports — SubViewport fog masks and minimap projections painted from allied vision.
- Using multiple threads — WorkerThreadPool patterns for minion batch logic off the main thread.
- Resources — Ability/status
Resourcedata withduplicate(true)so buffs never mutate shared templates. - Mouse and input coordinates — Screen→world mapping for skill-shot indicators and RTS-style move orders.
Related Skills
Prerequisites
- godot-project-foundations — Physics ticks, layer names, and input map setup before lanes, towers, and fog queries stay consistent.
- godot-multiplayer-networking — Authority, RPC hygiene, and sync budgets that MOBA minion/hero networking builds on.
- godot-navigation-pathfinding — NavigationAgent avoidance, baking, and performance contracts for waves and jungle camps.
- godot-input-handling — Action maps and physics-step input sampling for click-to-move and QWER cast telegraphs.
Complements
- godot-ability-system — Data-driven QWER cooldowns, costs, and effect scenes wired into authoritative cast validation.
- godot-rpg-stats — Hero growth, armor/MR-style modifiers, and Resource-backed stats towers and abilities read.
- godot-combat-system — Hit/hurt contracts for skill-shots, AA, and tower shots without hard class coupling.
- godot-raycasting-queries — Deeper space-state recipes for fog LOS, dive checks, and click picking under load.
- godot-signal-architecture — Decoupled ability UI binders and cast buses so cooldowns never live inside hero combat scripts.
- godot-3d-world-building — Lane corridors, jungle geometry, and collision that match the navmesh bake surface.
- godot-performance-optimization — Profiling and batching when minion sync arrays or fog grids threaten frame time.
- godot-genre-rts — Shared click-to-move, selection, and fog-mask patterns when borrowing RTS control UX for MOBA heroes.
Downstream / consumers
- godot-adapt-single-to-multiplayer — Lifts a solo lane prototype into lobby/authority/prediction flows this genre assumes.
- godot-monte-carlo-balancer — Hero asymmetry, kill-bounty, and catch-up XP matrices — simulate matchup win% instead of AFK→pro PvE bands alone.
Master
- godot-master — Library router and mirrored entry for discovering MOBA patterns beside sibling domains.

