Godot Master: Lead Architect Knowledge Hub
Every section earns its tokens by focusing on Knowledge Delta — the gap between what the base model already knows and what a senior Godot engineer knows from shipping real products.
Library target — Godot 4.7+
All Domain Skill mirrors target Godot 4.7+ (stable). For any engine version upgrade (1.x/2.x legacy → 3→4 → hop-by-hop 4.x), use godot-version-migration — do not treat this hub as a migration changelog.
Cross-cutting 4.7 reminders while routing: AreaLight3D / HDR → 3D Lighting; Asset Store vs Asset Library → export/platform modules; RichTextLabel ImageUnit, input device ID constants, Jolt behavior → migration hub module notes.
🧠 Part 1: Expert Thinking Frameworks
"Who Owns What?" — The Architecture Sanity Check
Before writing any system, answer these three questions for EVERY piece of state:
- Who owns the data? (The
StatsComponent owns health, NOT the CombatSystem)
- Who is allowed to change it? (Only the owner via a public method like
apply_damage())
- Who needs to know it changed? (Anyone listening to the
health_changed signal)
If you can't answer all three for every state variable, your architecture has a coupling problem. This is not OOP encapsulation — this is Godot-specific because the signal system IS the enforcement mechanism, not access modifiers.
The Godot "Layer Cake"
Organize every feature into four layers. Signals travel UP, never down:
┌──────────────────────────────┐
│ PRESENTATION (UI / VFX) │ ← Listens to signals, never owns data
├──────────────────────────────┤
│ LOGIC (State Machines) │ ← Orchestrates transitions, queries data
├──────────────────────────────┤
│ DATA (Resources / .tres) │ ← Single source of truth, serializable
├──────────────────────────────┤
│ INFRASTRUCTURE (Autoloads) │ ← Signal Bus, SaveManager, AudioBus
└──────────────────────────────┘
Critical rule: Presentation MUST NOT modify Data directly. Infrastructure speaks exclusively through signals. If a Label node is calling player.health -= 1, the architecture is broken.
The Signal Bus Tiered Architecture
- Global Bus (Autoload): ONLY for lifecycle events (
match_started, player_died, settings_changed). Debugging sprawl is the cost — limit events to < 15.
- Scoped Feature Bus: Each feature folder has its own bus (e.g.,
CombatBus only for combat nodes). This is the compromise that scales.
- Direct Signals: Parent-child communication WITHIN a single scene. Never across scene boundaries.
🔗 The "Smart Interconnect" Mandate
Expert systems are defined not by their isolation, but by their Payload Synthesis.
- Physics → Performance:
PhysicsServer2D and RenderingServer bypass SceneTree node overhead. Use for 1,000+ bullets or particles to achieve O(1) processing.
- Animation → Physics:
AnimationTree.get_root_motion_position() converts animation displacement into physics velocity, preventing "foot sliding" in complex movement.
- Data → Reactivity: Serialized
Resource objects (like Stats) emit signals when modified, allowing UI to update automatically without tight coupling.
- Asset → Spawning: An O(1) Dictionary-based cache (preloaded during
ResourceLoader async phases) prevents I/O hitches when spawning items or enemies.
- Eyes → Verification: After UI, lighting, or scene-building work, agents must see the current representation — route to Agent Vision (capture → budgeted WebP → scored taste), not verbal guesswork.
- Score → Certify: Before calling architecture “production-ready,” route to Analyst (Anara) — rubric sectors + helper scripts, not vibes.
- Slop → Decree: Before merge/ship, route to Auditor (Aurelius) — never-list encyclopedia + deterministic scanners.
- Mobile → Visuals: Prevent runtime frame-hitches by instantiating hidden effects during loading screens to force GPU shader pipeline compilation.
- Networking → Bandwidth: Use bit-packing into
PackedByteArray for synchronization instead of JSON/Strings to keep packets under 100 bytes.
- Genre Synthesis:
Shooter: strictly use intersect_ray() (direct space state) over RayCast3D nodes for 100x performance.
RPG: Damage follows base * pow(scaling, level) to sustain end-game progression.
RTS: Moves groups based on their Center of Mass with Relative Offset to preserve formation integrity.
Metroidvania: Uses ResourceLoader.load_threaded_request() for seamless room swaps.
Platformer: Mandatory Jump Buffering (~0.15s) and Coyote Time for professional feel.
Simulation: Tick Manager batch processing; avoid per-entity _process to sustain thousands of units.
Romance: Multi-Axial Affection (Attraction, Trust, Comfort) to map complex narrative branching.
Architecture: Signal Architecture strictly follows Signal Up, Call Down to eliminate circular scene coupling.
🧭 Part 2: Architectural Decision Frameworks
The Master Decision Matrix
| Scenario |
Strategy |
MANDATORY Skill Chain |
Trade-off |
| Rapid Prototype |
Event-Driven Mono |
READ: Foundations → Autoloads. Do NOT load genre or platform refs. |
Fast start, spaghetti risk |
| Complex RPG |
Component-Driven |
READ: Composition → States → RPG Stats. Do NOT load multiplayer or platform refs. |
Heavy setup, infinite scaling |
| Massive Open World |
Resource-Streaming |
READ: Open World → Save/Load. Also load Performance. |
Complex I/O, float precision jitter past 10K units |
| Server-Auth Multi |
Deterministic |
READ: Server Arch → Multiplayer. Do NOT load single-player genre refs. |
High latency, anti-cheat secure |
| Mobile/Web Port |
Adaptive-Responsive |
READ: UI Containers → Adapt Desk→Mobile → Platform Mobile. |
UI complexity, broad reach |
| Application / Tool |
App-Composition |
READ: App Composition → Theming. Do NOT load game-specific refs. |
Different paradigm than games |
| Romance / Dating Sim |
Affection Economy |
READ: Romance → Dialogue → UI Rich Text. |
High UI/Narrative density |
| Secrets / Easter Eggs |
Intentional Obfuscation |
READ: Secrets → Persistence. |
Community engagement, debug risk |
| Collection Quest |
Scavenger Logic |
READ: Collections → Marker3D Placement. |
Player retention, exploration drive |
| Seasonal Event |
Runtime Injection |
READ: Easter Theming → Material Swapping. |
Fast branding, no asset pollution |
| Souls-like Mortality |
Risk-Reward Revival |
READ: Revival/Corpse Run → Physics 3D. |
High tension, player frustration risk |
| Wave-based Action |
Combat Pacing Loop |
READ: Waves → Combat. |
Escalating tension, encounter design |
| Balance / Difficulty / Economy Pacing |
Monte Carlo Balance Lab |
READ: Resources → Economy → Combat / RPG Stats / Waves (as needed) → Monte Carlo Balancer → Testing → Builder. |
Statistical rigor; abstract sim must calibrate vs headless Godot |
| Survival Economy |
Harvesting Loop |
READ: Harvesting → Inventory. |
Resource scarcity, loop persistence |
| Racing / Speedrun |
Validation Loop |
READ: Time Trials → Input Buffer → Genre Racing. |
High precision, ghost record drive |
| Horror / Stealth |
Tension Management |
READ: Genre Horror → Genre Stealth → Audio. |
Atmosphere, player vulnerability |
| Card / Board Game |
Rule Enforcement |
READ: Genre Card Game → Turn System. |
Deterministic state, UI heavy |
| Simulation / RTS |
Batch Processing |
READ: Genre Simulation → Genre RTS → Performance. |
High unit counts, O(1) logic |
| HDR / Cinematic Visuals |
Display Pipeline |
READ: 3D Lighting → Platform Desktop → Shaders. Enable viewport HDR in Project Settings. |
Platform-specific tonemapping tuning |
| Rectangular Area Lights |
AreaLight3D |
READ: 3D Lighting → 3D Materials. Prefer AreaLight3D over emissive+GI hacks. |
Forward+ renderer required for full quality |
| Mobile Touch Controls |
Native Joystick |
READ: Platform Mobile → Adapt Desk→Mobile. Use built-in virtual joystick (4.7+). |
Less plugin dependency |
| Addon / Asset Discovery |
Asset Store |
READ: Project Foundations → Export Builds. Asset Store replaces Asset Library. |
Beta store UI — verify licensing per addon |
| CLI Scene / Headless Build |
Builder Pipeline |
READ: Builder. Programmatic .tscn / glTF→collision / CI export via prefixed builder_*.py. Do NOT load genre refs. |
Structure only — pair with Agent Vision for pixels |
| Architecture Score / Certificate |
Analyst (Anara) |
READ: Analyst → marking rubrics atlas → active sector category only. |
Certifies scale/cohesion — not “it runs” |
| Never-List / Slop Audit |
Auditor (Aurelius) |
READ: Auditor → never-list encyclopedia → active sector + scanners on disk. |
Surgical load — do not ingest entire encyclopedia |
| Agent Eyes / Visual QA |
Capture → WebP → Rubric |
READ: Agent Vision. Screenshot assets, window/region/screen, or TEMP editor bridge — then structured review. Do NOT load genre refs. |
Host-side only; never Autoload / never leave staged addon |
The "When NOT to Use a Node" Decision
One of the most impactful expert-only decisions. The Godot docs explicitly say "avoid using nodes for everything":
| Type |
When to Use |
Cost |
Expert Use Case |
Object |
Custom data structures, manual memory management |
Lightest. Must call .free() manually. |
Custom spatial hash maps, ECS-like data stores |
RefCounted |
Transient data packets, logic objects that auto-delete |
Auto-deleted when no refs remain. |
DamageRequest, PathQuery, AbilityEffect — logic packets that don't need the scene tree |
Resource |
Serializable data with Inspector support |
Slightly heavier than RefCounted. Handles .tres I/O. |
ItemData, EnemyStats, DialogueLine — any data a designer should edit in Inspector |
Node |
Needs _process/_physics_process, needs to live in the scene tree |
Heaviest — SceneTree overhead per node. |
Only for entities that need per-frame updates or spatial transforms |
The expert pattern: Use RefCounted subclasses for all logic packets and data containers. Reserve Node for things that must exist in the spatial tree. This halves scene tree overhead for complex systems.
🔧 Part 3: Core Workflows
Workflow 1: Professional Scaffolding
From empty project to production-ready container.
MANDATORY — READ ENTIRE FILE: Foundations
- Organize by Feature (
/features/player/, /features/combat/), not by class type. A player/ folder contains the scene, script, resources, and tests for the player.
- READ: Signal Architecture — Create
GlobalSignalBus autoload with < 15 events.
- READ: GDScript Mastery — Enable
untyped_declaration warning in Project Settings → GDScript → Debugging.
- Apply Project Templates for base
.gitignore, export presets, and input map.
- Use Builder (
builder_create_scene.py, builder_add_node.py, builder_save_scene.py) to generate scene hierarchies programmatically via the Godot CLI.
- After the container exists: optional early Workflow 13 (Analyst) on foundations cohesion; before first ship, Workflow 14 (Auditor) on signal/typing/export never-lists.
[!CAUTION] Workflow 1 NEVER List
- NEVER use
res:// paths in logic scripts. Use @export_file or @export_dir to ensure resources remain valid when moved.
- NEVER initialize children in
_init(). The scene tree isn't ready. Use _ready() or @onready.
- NEVER keep "Default" project settings for
Physics Ticks. Set to 60 for consistency, or use Engine.physics_ticks_per_second for adaptive logic.
- NEVER use
print() in _process() for debugging; use the Debugger or push_error() to avoid frame-time spikes.
Do NOT load combat, multiplayer, genre, or platform references during scaffolding.
Workflow 2: Entity Orchestration
Building modular, testable characters.
MANDATORY Chain — READ ALL: Composition → State Machine → CharacterBody2D or Physics 3D → Animation Tree
Do NOT load UI, Audio, or Save/Load references for entity work.
- The State Machine queries an
InputComponent, never handles input directly. This allows AI/Player swap with zero refactoring.
- The State Machine ONLY handles transitions. Logic belongs in Components.
MoveState tells MoveComponent to act, not the other way around.
- Every entity MUST pass the F6 test: pressing "Run Current Scene" (F6) must work without crashing. If it crashes, your entity has scene-external dependencies.
[!CAUTION] Workflow 2 NEVER List
- NEVER call
parent.do_thing(). If the parent changes, the entity breaks. Emit a signal request_action instead.
- NEVER use
_process for movement. Use _physics_process to avoid jitter on variable-refresh-rate monitors.
- NEVER hardcode animation names. Use a
StringName constant or a Resource map to enable easy renaming in AnimationPlayer.
- NEVER use
get_node() with absolute paths. Use %UniqueName to survive tree refactoring.
Workflow 3: Data-Driven Systems
Connecting Combat, Inventory, Stats through Resources.
MANDATORY Chain — READ ALL: Resource Patterns → RPG Stats → Combat → Inventory
- Create ONE
ItemData.gd extending Resource. Instantiate it as 100 .tres files instead of 100 scripts.
- The HUD NEVER references the Player directly. It listens for
player_health_changed on the Signal Bus.
- Enable "Local to Scene" on ALL
@export Resource variables, or call resource.duplicate() in _ready(). Failure to do this is Bug #1 in Part 8.
[!CAUTION] Workflow 3 NEVER List
- NEVER pass
Node references in a Signal Bus. Objects get freed; RIDs or IDs are safer for long-term tracking.
- NEVER modify a
.tres file at runtime via code (it modifies the disk file). Always .duplicate() before modifying.
- NEVER use
Array for high-frequency search. Use Dictionary with StringName keys for O(1) lookups.
- NEVER use
float for item counts or precise resource tracking; use int and scale for display.
Workflow 4: Persistence Pipeline
MANDATORY: Autoload Architecture → Save/Load → Scene Management
- Use dictionary-mapped serialization. Old save files MUST not corrupt when new fields are added — use
.get("key", default_value).
- For procedural worlds: save the Seed plus a Delta-List of modifications, not the entire map. A 100MB world becomes a 50KB save.
[!CAUTION] Workflow 4 NEVER List
- NEVER save whole
Object or Node instances. They contain transient pointers. Extract data into a Dictionary or custom Resource.
- NEVER use
JSON for data that needs strict typing (e.g., Vector2). Use var_to_bytes or ConfigFile for structured Godot types.
- NEVER block the main thread for auto-saves. Use a
Thread or WorkerThreadPool to serialize large dictionaries.
- NEVER save to
res:// in an exported project; strictly use user:// for persistent data.
Workflow 5: Performance Optimization
MANDATORY: Debugging/Profiling → Performance Optimization
Diagnosis-first approach (NEVER optimize blindly):
- High Script Time → Profile with built-in Profiler. Check if
_process is being called on hundreds of nodes. Move to single-manager pattern or Server APIs (see Part 6).
- High Draw Calls → Use
MultiMeshInstance for repetitive geometry. Batch materials with ORM textures.
- Physics Stutter → Simplify collisions to primitive shapes. Load 2D Physics or 3D Physics. Check if
_process is used instead of _physics_process for movement.
- VRAM Overuse → Switch textures to VRAM Compression (BPTC/S3TC for desktop, ETC2 for mobile). Never ship raw PNG.
- Intermittent Frame Spikes → Usually GC pass, synchronous
load(), or NavigationServer recalculation. Use ResourceLoader.load_threaded_request().
[!CAUTION] Workflow 5 NEVER List
- NEVER use
get_nodes_in_group() inside _process. It's an O(n) operation every frame. Cache the array in _ready().
- NEVER use
Area2D signals for "Stay" logic. Use get_overlapping_bodies() periodically or a manager-level PhysicsServer check.
- NEVER optimize before profiling. A 1ms script is irrelevant if you have 2000 draw calls killing the GPU.
- NEVER use
load() in hot paths; strictly preload or use ResourceLoader for async loading.
Workflow 6: Cross-Platform Adaptation
MANDATORY: Input Handling → Adapt Desktop→Mobile → Platform Mobile
Also read: Platform Desktop, Platform Web, Platform Console, Platform VR as needed.
- Use an
InputManager autoload that translates all input types into normalized actions. NEVER read Input.is_key_pressed() directly — it blocks controller and touch support.
- Mobile touch targets: minimum 44px physical size. Use
MarginContainer with Safe Area logic for notch/cutout devices.
- Web exports: Godot's
AudioServer requires user interaction before first play (browser policy). Handle this with a "Click to Start" screen.
[!CAUTION] Workflow 6 NEVER List
- NEVER use
OS.get_name() for feature detection. Use OS.has_feature("mobile") or custom feature tags to handle subsets like "SteamDeck."
- NEVER assume a specific aspect ratio. Always use
Expand or Keep Aspect in combinations with Anchor nodes.
- NEVER use desktop-only shaders (e.g., complex depth sampling) on Mobile/Web without a GLES3/Compatibility secondary path.
- NEVER ignore
physical_keycode for desktop builds; it ensures keyboard layouts (AZERTY/QWERTY) don't break movement.
- NEVER pass unsanitized strings to
JavaScriptBridge.eval() — Prevents script injection in web builds. Use a sanitize_js_string() helper.
Workflow 7: Procedural Generation
MANDATORY: Procedural Gen → Tilemap Mastery or 3D World Building → Navigation
- ALWAYS use
FastNoiseLite resource with a fixed seed for deterministic generation.
- Never bake NavMesh on the main thread. Use
NavigationServer3D.parse_source_geometry_data() + NavigationServer3D.bake_from_source_geometry_data_async().
- For infinite worlds: chunk loading MUST happen on a background thread using
WorkerThreadPool. Build the scene chunk off-tree, then add_child.call_deferred() on the main thread.
[!CAUTION] Workflow 7 NEVER List
- NEVER instantiate nodes for "Background" noise. Use
MultiMeshInstance or draw loops in _draw for thousands of small details.
- NEVER regenerate the entire map for one change. Use a "Dirty Chunk" system to only update what exactly changed.
- NEVER place collisions on the same frame as mesh generation if using
concave_polygon_shape. It stalls the physics thread.
- NEVER perform pathfinding queries every frame for all units. Use a
NavigationAgent with target_position updates on a timer.
Workflow 8: Multiplayer Architecture
MANDATORY — READ: Single→Multiplayer → Networking → Server Arch
Do NOT load single-player genre blueprints.
- Client sends Input, Server calculates Outcome. The Client NEVER determines damage, position deltas, or inventory changes.
- Use Client-Side Prediction with server reconciliation: predict locally, correct from server snapshot. Hides up to ~150ms of latency.
MultiplayerSpawner handles replication in Godot 4. Configure it per scene, not globally.
[!CAUTION] Workflow 8 NEVER List
- NEVER trust
rpc_id(1, ...) (Client to Server) without validation. A hacked client can send damage = 999999.
- NEVER replicate
_process transforms directly. Replicate Input vector and simulate movement on both sides.
- NEVER use
TCP for high-frequency packets (movement). Use UDP / ENet and handle dropped packets with interpolation.
- NEVER synchronize every projectile; use Client-Side Prediction for visuals and only RPC the "Fire" event.
ReflectionProbe vs VoxelGI vs SDFGI: Probes are cheap/static, VoxelGI is medium/baked, SDFGI is expensive/dynamic. Choose based on your platform budget (see Part 5).
Workflow 9: Responsive UI & Expert Theming (Audit Verified)
MANDATORY Chain: UI Containers → UI Theming → Rich Text → Tweening
- The F6 Principle: Every UI scene must be testable in isolation. Use
MOUSE_FILTER_STOP only on the background, PASS on children.
- Breathing Room: Use
add_theme_constant_override("separation", X) over manual padding.
- Adaptive Scaling: Use
ui_containers_responsive_layout_builder.gd for breakpoint-aware mobile/desktop switching.
- Lifecycle Safety: Never scroll to a new child on the same frame.
await get_tree().process_frame before modifying scroll_vertical.
- Data Integration: Use
Resource-to-UI binding; UI nodes MUST be stateless projection layers.
- See it: Close with Workflow 12 — Agent Vision window/asset capture → scored layout/type review. Agents cannot QA UI from text alone.
[!CAUTION] Workflow 9 NEVER List
- NEVER use absolute pixel offsets. UI becomes unreadable on 4K or tiny mobile screens. Use
Container sizing.
- NEVER deep-nest
MarginContainers. It makes the Inspector unusable. Use a single Theme resource for project-wide margins.
- NEVER connect UI buttons to gameplay logic directly. UI sends "Signal",
PlayerController listens. This prevents UI-deletion crashes.
- NEVER use
_process() to move a UI element to a target. Use a Tween to avoid stuttering and frame-rate dependence.
- NEVER leave
mouse_filter as STOP on transparent containers; it "eats" clicks for everything behind it.
- NEVER use dynamic
load() on paths without validating the res:// prefix and safe extension (.tres, .res, .theme) — Prevents arbitrary code/resource execution.
- NEVER declare UI “done” without an Agent Vision capture of the live layout.
Workflow 10: Cinematic Lighting & VFX (Audit Verified)
MANDATORY Chain: 3D Lighting → Particles → 3D Materials → Shaders
- The GI Choice: VoxelGI for interiors, SDFGI for open world. Never ship with both overlapping.
- Shadow Budget: Max 2 Shadow-casting DirectionalLights. Use
3d_lighting_fake_gi_bounce.gd for mobile fills.
- VFX Lifecycle: Use
finished signal over Timers. Re-run with restart() to avoid async GPU stalls.
- Optimization: Use
ORM Texture packing (AO/Rough/Metal) to save GPU cache and texture slots.
- Batching: Use
Instance Uniforms for material variations across thousands of instances without draw call penalties.
- See it: Close with Workflow 12 — Agent Vision editor/window capture to verify lighting, exposure, and VFX read in pixels.
[!CAUTION] Workflow 10 NEVER List
- NEVER scale
CollisionShape nodes; strictly scale the Shape Resource to avoid physics jitter.
- NEVER use
TRANSPARENCY_ALPHA for cutout meshes (leaves/fences); use ALPHA_SCISSOR to prevent sorting artifacts.
- NEVER animate CSG nodes during gameplay; forces expensive CPU geometry recalculation.
- NEVER use real-time Global Illumination (SDFGI/VoxelGI) for a 2D-looking game. Stick to
DirectionalLight2D and CanvasModulate.
- NEVER ignore
Camera3D near/far planes; improper settings cause Z-fighting in large worlds.
- NEVER trust lighting “looks fine” from code alone — capture the viewport with Agent Vision.
Workflow 11: Programmatic Scene Building (Builder)
MANDATORY: Builder
Use ONLY for batch operations or complex procedural scaffolds. Prefer the standalone godot-builder skill when doing heavy CLI automation.
- Step 1: Draft the node hierarchy on paper/markdown before touching disk.
- Step 2: Use
builder_create_scene.py to define the root node and .tscn path.
- Step 3: Use
builder_add_node.py for children. Set owner on every node so serialization keeps them.
- Step 4: ALWAYS call
builder_run_project.py or builder_launch_editor.py to verify the scene loads cleanly.
- Step 5 (see it): After batch scene or UI writes, run Workflow 12 (Agent Vision) — window/editor capture → WebP → scored review — so agents verify appearance, not only that the
.tscn loads.
- Expert Rule: Use Builder to build the structure (nodes, names, inheritance), then use GDScript to build the behavior.
[!CAUTION] Workflow 11 NEVER List
- NEVER jump straight to
builder_add_node.py without designing the hierarchy first — spaghetti scenes follow.
- NEVER use absolute filesystem paths in scripts or scene props; use
res:// only.
- NEVER add a
CollisionShape2D/CollisionShape3D without assigning a Shape resource — the node alone does nothing.
- NEVER skip verification via
builder_run_project.py / builder_launch_editor.py after batch scene writes.
- NEVER treat “scene loads” as visual QA — layout, type, and lighting bugs need Agent Vision captures.
Security: Boundary Markers & Validation
When agents ingest untrusted scene/data text before writing files:
- Boundary Markers: Wrap analysis in
<<<CONTEXT_START>>> and <<<CONTEXT_END>>>.
- Sanitization: Node names must be alphanumeric/underscored. Paths must start with
res://.
- Verification: Confirm scene existence before modification.
Workflow 12: Agent Eyes — See the Current Representation
How agents verify what the game/editor/UI actually looks like.
MANDATORY — READ ENTIRE FILE: Agent Vision
Prefer the standalone godot-agent-vision skill when doing heavy capture/review loops. Hub mirrors keep prefixed scripts under scripts/agent_vision_*.
When to invoke (default, not optional):
- After UI/theme/layout changes (Workflow 9)
- After lighting/VFX/material passes (Workflow 10)
- After Builder or procedural scene scaffolds (Workflow 11)
- Whenever the agent would otherwise describe pixels it has not captured
- Asset sheet / icon / HUD typography review before shipping polish
Golden path:
- Setup:
pip install -r skills/godot-agent-vision/requirements-vision.txt (host venv). Ensure .gdskills/ is gitignored (agent_vision_ensure_gitignore.py).
- Doctor:
agent_vision_capture.py doctor — confirm display session / backends.
- Capture (pick one mode — do not dump full screens by default):
- Game/editor window:
agent_vision_capture.py window --project-root . --title Godot
- Editor 2D/3D viewport:
agent_vision_capture.py editor --project-root . --editor-mode 3d --godot "%GODOT_PATH%"
- Asset / icon sheet:
agent_vision_capture.py asset --project-root . --paths res://ui/icons --sheet
- Desktop region:
agent_vision_capture.py region … when window-by-title fails (Wayland, etc.)
- Read the budgeted WebP(s) from
.gdskills/vision/ (default short-edge 512). Use --detail only when type/OCR fails at 512.
- Score with the Taste Receptor Atlas / vision rubric in the Agent Vision refs — ordered fixes keyed to receptor IDs, not vibes.
- Teardown: never leave the TEMP editor bridge /
addons/_gdskills_agent_vision/ staged; never commit .gdskills/vision/**.
[!CAUTION] Workflow 12 NEVER List
- NEVER invent how the game looks without a capture — Agent Vision is the eyes.
- NEVER ship the editor bridge as an Autoload or leave it in the consumer project.
- NEVER dump uncompressed PNG walls into context — WebP only, budgeted.
- NEVER replace scored taste with binary PASS/FAIL or purple-gradient “AI default” UI praise.
- NEVER put ornate display faces on ammo/HP/timers (
TYPE-DISPLAY-HUD-SPLIT).
Workflow 13: Architecture Scoring — Analyst (Anara)
Certify whether the project can survive tomorrow — not whether it merely runs.
MANDATORY — READ ENTIRE FILE: Analyst
Prefer the standalone godot-analyst skill for full certification loops. Hub mirrors: scripts/analyst_*, nested references/analyst-*.md.
When to invoke:
- Before calling a milestone “architecture complete”
- After large refactors (folder-by-feature, autoload sprawl, Resource graphs)
- When the user asks for modernity / scalability / Visionary Certificate scoring
- After Workflow 1 scaffolding or Workflow 2–4 systems land — score cohesion before more features
Golden path:
- Map: Request the project root; map
res:// structure (feature folders, autoloads, dependency hotspots).
- Atlas: Load analyst-marking_rubrics_atlas.md — pick the Evolutionary Sector(s) in scope.
- Sector only: MANDATORY load matching category rubric file(s) under the Analyst progressive-disclosure tree. Do NOT load every category file.
- Engine helpers (only what exists on disk):
analyst_scoring_logic.gd, analyst_marking_rubrics_atlas.gd, analyst_visionary_comparison.gd — do not invent phantom score_*.py fleets.
- Synthesize: Weighted scores → Visionary Certificate narrative + transcendence blueprint (gaps ordered by impact).
[!CAUTION] Workflow 13 NEVER List
- NEVER certify without the active sector rubric — guessing weights is not Visionary.
- NEVER parse
.tscn/.tres by hand — use ResourceLoader.get_dependencies / PackedScene.get_state.
- NEVER treat “it runs” or green play as a pass — score scale, typing, decoupling, cohesion.
- NEVER load the entire Analyst categories tree into context.
Workflow 14: Never-List Enforcement — Auditor (Aurelius)
Find the invisible slop that invites bugs — then decree remediation.
MANDATORY — READ ENTIRE FILE: Auditor
Prefer the standalone godot-auditor skill for deep audits. Hub mirrors: scripts/auditor_*, nested references/auditor-*.md.
When to invoke:
- Pre-merge / pre-release integrity pass
- After signal, typing, export, or memory regressions
- When Analyst scores flag decay — Auditor proves it with scanners + encyclopedia
- Pair with Workflow 5 (performance) when ObjectDB / orphan / batching slop is suspected
Golden path:
- Survey: Confirm project path + feature-folder integrity.
- Encyclopedia: Open auditor-never_list_encyclopedia.md — identify the Architectural Sector.
- Surgical load: MANDATORY read only the matching category never-list file(s). Do NOT ingest the entire encyclopedia.
- Scanners on disk (call individually — do not invent missing tools):
auditor_audit_signals.py — string .connect decay
auditor_audit_type_hints.py — untyped Array/Dictionary + string-connect
auditor_audit_memory_fragmentation.gd — ObjectDB / orphan snapshots
auditor_purge_report_generator.gd — purge / unused-resource rollup
- Decrees: Findings with the why behind each never-list hit; ordered remediation. For sectors without a scanner, cite engine APIs from the loaded category — do not claim a phantom script ran.
[!CAUTION] Workflow 14 NEVER List
- NEVER load every never-list category at once — progressive disclosure only.
- NEVER invent
audit_*.py scanners that are not in scripts/.
- NEVER soft-pedal export case-sensitivity, signal decay, or untyped hot-path collections.
- NEVER skip deterministic proof when a scanner exists for the request.
Persona triad (ship loop): Builder builds structure → Agent Vision sees pixels → Analyst scores architecture → Auditor enforces never-lists.
🚫 Part 4: The Expert NEVER List
Each rule includes the non-obvious reason — the thing only shipping experience teaches.
- NEVER use
get_tree().root.get_node("...") — Absolute paths break when ANY ancestor is renamed or reparented. Use %UniqueNames, @export NodePath, or signal-based discovery.
- NEVER use
load() inside a loop or _process — Synchronous disk read blocks the ENTIRE main thread. Use preload() at script top for small assets, ResourceLoader.load_threaded_request() for large ones.
- NEVER
queue_free() while external references exist — Parent nodes or arrays holding refs will get "Deleted Object" errors. Clean up refs in _exit_tree() and set them to null before freeing.
- NEVER put gameplay logic in
_draw() — _draw() is called on the rendering thread. Mutating game state causes race conditions with _physics_process.
- NEVER use
Area2D for 1000+ overlapping objects — Each overlap check has O(n²) broadphase cost. Use ShapeCast2D, PhysicsDirectSpaceState2D.intersect_shape(), or Server APIs for bullet-hell patterns.
- NEVER mutate external state from a component — If
HealthComponent calls $HUD.update_bar(), deleting the HUD crashes the game. Components emit signals; listeners decide how to respond.
- NEVER use
await in _physics_process — await yields execution, meaning the physics step skips frames. Move async operations to a separate method triggered by a signal.
- NEVER use
String keys in hot-path dictionary lookups — String hashing is O(n). Use StringName (&"key") for O(1) pointer comparisons, or integer enums.
- NEVER store
Callable references to freed objects — Crashes silently or throws errors. Disconnect signals in _exit_tree() or use CONNECT_ONE_SHOT.
- NEVER use
_process for 1000+ entities — Each _process call has per-node SceneTree overhead. Use a single Manager._process that iterates an array of data structs (Data-Oriented pattern), or use Server APIs directly.
- NEVER use
Tween on a node that may be freed — If a node is queue_free()'d while a Tween runs, it errors. Kill tweens in _exit_tree() or bind to SceneTree: get_tree().create_tween().
- NEVER request data FROM
RenderingServer or PhysicsServer in _process — These servers run asynchronously. Calling getter functions forces a synchronous stall that kills performance. The APIs are intentionally designed to be write-only in hot paths.
- NEVER use
call_deferred() as a band-aid for initialization order bugs — It masks architectural problems (dependency on tree order). Fix the actual dependency with explicit initialization signals or @onready.
- NEVER create circular signal connections — Node A connects to B, B connects to A. This creates infinite loops on the first emit. Use a mediator pattern (Signal Bus) to break cycles.
- NEVER let inheritance exceed 3 levels — Beyond 3, debugging
super() chains is a nightmare. Use composition (Node children) to add behaviors instead.
- NEVER use
_process for hit detection or movement in physics-heavy genres (FPS/ARPG); strictly use _physics_process to ensure frame-independent collision detection.
- NEVER trust the client for authority on persistent game state (Health, XP, Inventory). Handled exclusively via Server-Auth or Secure Checksums.
- NEVER use standard strings for high-frequency runtime checks; strictly use
StringName (&"active") to avoid O(n) hashing.
- NEVER manually handle RVO avoidance every frame in unit-heavy games (RTS/MOBA); offload to
NavigationAgent internal threading.
- NEVER block the main thread for procedural generation or heavy I/O; strictly offload to
WorkerThreadPool.
- NEVER ignore
Local-to-Scene on Resources used in unique instances (e.g. enemy stats); failure causes shared-memory bugs across all instances.
- NEVER use
float for currency; strictly use Integer Cents to avoid precision drift in complex economies.
- NEVER set
target_position before physics_frame; navigati
…(truncated)
1---
2name: godot-master
3description: "Consolidated expert library for professional Godot 4.7+ game and application development. Orchestrates 92 Domain Skills through architectural workflows, anti-pattern catalogs, performance budgets, and Server API patterns. Use when: (1) starting a new Godot project, (2) designing game or app architecture, (3) building entity/component systems, (4) debugging performance or physics issues, (5) choosing between 2D/3D approaches, (6) implementing multiplayer, (7) optimizing draw calls or script time, (8) porting between platforms, (9) migrating from 4.6 to 4.7, (10) visually verifying UI/editor/game appearance via Agent Vision, (11) scoring/certifying architecture with Analyst (Anara), (12) enforcing never-lists with Auditor (Aurelius), (13) programmatic CLI scene building with Builder. Primary entry point for ALL Godot development tasks. Keywords: Godot 4.7, AreaLight3D, HDR, Asset Store, godot-master, agent vision, visual QA, Agent Eyes, analyst, Anara, auditor, Aurelius, builder."
4---
5
6# Godot Master: Lead Architect Knowledge Hub
7
8Every section earns its tokens by focusing on **Knowledge Delta** — the gap between what the base model already knows and what a senior Godot engineer knows from shipping real products.
9
10## Library target — Godot 4.7+
11
12All Domain Skill mirrors target **Godot 4.7+** (stable). For **any engine version upgrade** (1.x/2.x legacy → 3→4 → hop-by-hop 4.x), use **[godot-version-migration](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-version-migration/SKILL.md)** — do not treat this hub as a migration changelog.
13
14Cross-cutting 4.7 reminders while routing: **AreaLight3D** / HDR → [3D Lighting](references/3d-lighting.md); Asset Store vs Asset Library → export/platform modules; RichTextLabel ImageUnit, input device ID constants, Jolt behavior → migration hub module notes.
15
16---
17
18## 🧠 Part 1: Expert Thinking Frameworks
19
20### "Who Owns What?" — The Architecture Sanity Check
21Before writing any system, answer these three questions for EVERY piece of state:
22- **Who owns the data?** (The `StatsComponent` owns health, NOT the `CombatSystem`)
23- **Who is allowed to change it?** (Only the owner via a public method like `apply_damage()`)
24- **Who needs to know it changed?** (Anyone listening to the `health_changed` signal)
25
26If you can't answer all three for every state variable, your architecture has a coupling problem. This is not OOP encapsulation — this is Godot-specific because the **signal system IS the enforcement mechanism**, not access modifiers.
27
28### The Godot "Layer Cake"
29Organize every feature into four layers. Signals travel UP, never down:
30```
31┌──────────────────────────────┐
32│ PRESENTATION (UI / VFX) │ ← Listens to signals, never owns data
33├──────────────────────────────┤
34│ LOGIC (State Machines) │ ← Orchestrates transitions, queries data
35├──────────────────────────────┤
36│ DATA (Resources / .tres) │ ← Single source of truth, serializable
37├──────────────────────────────┤
38│ INFRASTRUCTURE (Autoloads) │ ← Signal Bus, SaveManager, AudioBus
39└──────────────────────────────┘
40```
41**Critical rule**: Presentation MUST NOT modify Data directly. Infrastructure speaks exclusively through signals. If a `Label` node is calling `player.health -= 1`, the architecture is broken.
42
43### The Signal Bus Tiered Architecture
44- **Global Bus (Autoload)**: ONLY for lifecycle events (`match_started`, `player_died`, `settings_changed`). Debugging sprawl is the cost — limit events to < 15.
45- **Scoped Feature Bus**: Each feature folder has its own bus (e.g., `CombatBus` only for combat nodes). This is the compromise that scales.
46- **Direct Signals**: Parent-child communication WITHIN a single scene. Never across scene boundaries.
47
48### 🔗 The "Smart Interconnect" Mandate
49Expert systems are defined not by their isolation, but by their **Payload Synthesis**.
50- **Physics → Performance**: `PhysicsServer2D` and `RenderingServer` bypass `SceneTree` node overhead. Use for 1,000+ bullets or particles to achieve O(1) processing.
51- **Animation → Physics**: `AnimationTree.get_root_motion_position()` converts animation displacement into physics `velocity`, preventing "foot sliding" in complex movement.
52- **Data → Reactivity**: Serialized `Resource` objects (like `Stats`) emit signals when modified, allowing UI to update automatically without tight coupling.
53- **Asset → Spawning**: An O(1) Dictionary-based cache (preloaded during `ResourceLoader` async phases) prevents I/O hitches when spawning items or enemies.
54- **Eyes → Verification**: After UI, lighting, or scene-building work, agents must **see** the current representation — route to [Agent Vision](references/agent-vision.md) (capture → budgeted WebP → scored taste), not verbal guesswork.
55- **Score → Certify**: Before calling architecture “production-ready,” route to [Analyst](references/analyst.md) (Anara) — rubric sectors + helper scripts, not vibes.
56- **Slop → Decree**: Before merge/ship, route to [Auditor](references/auditor.md) (Aurelius) — never-list encyclopedia + deterministic scanners.
57- **Mobile → Visuals**: Prevent runtime frame-hitches by instantiating hidden effects during loading screens to force GPU shader pipeline compilation.
58- **Networking → Bandwidth**: Use bit-packing into `PackedByteArray` for synchronization instead of JSON/Strings to keep packets under 100 bytes.
59- **Genre Synthesis**:
60 - `Shooter`: strictly use `intersect_ray()` (direct space state) over `RayCast3D` nodes for 100x performance.
61 - `RPG`: Damage follows `base * pow(scaling, level)` to sustain end-game progression.
62 - `RTS`: Moves groups based on their Center of Mass with `Relative Offset` to preserve formation integrity.
63 - `Metroidvania`: Uses `ResourceLoader.load_threaded_request()` for seamless room swaps.
64 - `Platformer`: Mandatory `Jump Buffering` (~0.15s) and `Coyote Time` for professional feel.
65 - `Simulation`: `Tick Manager` batch processing; avoid per-entity `_process` to sustain thousands of units.
66 - `Romance`: `Multi-Axial Affection` (Attraction, Trust, Comfort) to map complex narrative branching.
67 - `Architecture`: `Signal Architecture` strictly follows `Signal Up, Call Down` to eliminate circular scene coupling.
68
69---
70
71## 🧭 Part 2: Architectural Decision Frameworks
72
73### The Master Decision Matrix
74
75| Scenario | Strategy | **MANDATORY** Skill Chain | Trade-off |
76| :--- | :--- | :--- | :--- |
77| **Rapid Prototype** | Event-Driven Mono | **READ**: [Foundations](references/project-foundations.md) → [Autoloads](references/autoload-architecture.md). **Do NOT load** genre or platform refs. | Fast start, spaghetti risk |
78| **Complex RPG** | Component-Driven | **READ**: [Composition](references/composition.md) → [States](references/state-machine-advanced.md) → [RPG Stats](references/rpg-stats.md). **Do NOT load** multiplayer or platform refs. | Heavy setup, infinite scaling |
79| **Massive Open World** | Resource-Streaming | **READ**: [Open World](references/genre-open-world.md) → [Save/Load](references/save-load-systems.md). Also load [Performance](references/performance-optimization.md). | Complex I/O, float precision jitter past 10K units |
80| **Server-Auth Multi** | Deterministic | **READ**: [Server Arch](references/server-architecture.md) → [Multiplayer](references/multiplayer-networking.md). **Do NOT load** single-player genre refs. | High latency, anti-cheat secure |
81| **Mobile/Web Port** | Adaptive-Responsive | **READ**: [UI Containers](references/ui-containers.md) → [Adapt Desk→Mobile](references/adapt-desktop-to-mobile.md) → [Platform Mobile](references/platform-mobile.md). | UI complexity, broad reach |
82| **Application / Tool** | App-Composition | **READ**: [App Composition](references/composition-apps.md) → [Theming](references/ui-theming.md). **Do NOT load** game-specific refs. | Different paradigm than games |
83| **Romance / Dating Sim** | Affection Economy | **READ**: [Romance](references/genre-romance.md) → [Dialogue](references/dialogue-system.md) → [UI Rich Text](references/ui-rich-text.md). | High UI/Narrative density |
84| **Secrets / Easter Eggs** | Intentional Obfuscation | **READ**: [Secrets](references/mechanic-secrets.md) → [Persistence](references/save-load-systems.md). | Community engagement, debug risk |
85| **Collection Quest** | Scavenger Logic | **READ**: [Collections](references/game-loop-collection.md) → [Marker3D Placement](references/3d-world-building.md). | Player retention, exploration drive |
86| **Seasonal Event** | Runtime Injection | **READ**: [Easter Theming](references/theme-easter.md) → [Material Swapping](references/3d-materials.md). | Fast branding, no asset pollution |
87| **Souls-like Mortality** | Risk-Reward Revival | **READ**: [Revival/Corpse Run](references/mechanic-revival.md) → [Physics 3D](references/physics-3d.md). | High tension, player frustration risk |
88| **Wave-based Action** | Combat Pacing Loop | **READ**: [Waves](references/game-loop-waves.md) → [Combat](references/combat-system.md). | Escalating tension, encounter design |
89| **Balance / Difficulty / Economy Pacing** | Monte Carlo Balance Lab | **READ**: [Resources](references/resource-data-patterns.md) → [Economy](references/economy-system.md) → [Combat](references/combat-system.md) / [RPG Stats](references/rpg-stats.md) / [Waves](references/game-loop-waves.md) (as needed) → [Monte Carlo Balancer](references/monte-carlo-balancer.md) → [Testing](references/testing-patterns-expert-testing-patterns.md) → [Builder](references/builder.md). | Statistical rigor; abstract sim must calibrate vs headless Godot |
90| **Survival Economy** | Harvesting Loop | **READ**: [Harvesting](references/game-loop-harvest.md) → [Inventory](references/inventory-system.md). | Resource scarcity, loop persistence |
91| **Racing / Speedrun** | Validation Loop | **READ**: [Time Trials](references/game-loop-time-trial.md) → [Input Buffer](references/input-handling.md) → [Genre Racing](references/genre-racing.md). | High precision, ghost record drive |
92| **Horror / Stealth** | Tension Management | **READ**: [Genre Horror](references/genre-horror.md) → [Genre Stealth](references/genre-stealth.md) → [Audio](references/audio-systems.md). | Atmosphere, player vulnerability |
93| **Card / Board Game** | Rule Enforcement | **READ**: [Genre Card Game](references/genre-card-game.md) → [Turn System](references/turn-system.md). | Deterministic state, UI heavy |
94| **Simulation / RTS** | Batch Processing | **READ**: [Genre Simulation](references/genre-simulation.md) → [Genre RTS](references/genre-rts.md) → [Performance](references/performance-optimization.md). | High unit counts, O(1) logic |
95| **HDR / Cinematic Visuals** | Display Pipeline | **READ**: [3D Lighting](references/3d-lighting.md) → [Platform Desktop](references/platform-desktop.md) → [Shaders](references/shaders-basics.md). Enable viewport HDR in Project Settings. | Platform-specific tonemapping tuning |
96| **Rectangular Area Lights** | AreaLight3D | **READ**: [3D Lighting](references/3d-lighting.md) → [3D Materials](references/3d-materials.md). Prefer AreaLight3D over emissive+GI hacks. | Forward+ renderer required for full quality |
97| **Mobile Touch Controls** | Native Joystick | **READ**: [Platform Mobile](references/platform-mobile.md) → [Adapt Desk→Mobile](references/adapt-desktop-to-mobile.md). Use built-in virtual joystick (4.7+). | Less plugin dependency |
98| **Addon / Asset Discovery** | Asset Store | **READ**: [Project Foundations](references/project-foundations.md) → [Export Builds](references/export-builds.md). Asset Store replaces Asset Library. | Beta store UI — verify licensing per addon |
99| **CLI Scene / Headless Build** | Builder Pipeline | **READ**: [Builder](references/builder.md). Programmatic `.tscn` / glTF→collision / CI export via prefixed `builder_*.py`. **Do NOT load** genre refs. | Structure only — pair with Agent Vision for pixels |
100| **Architecture Score / Certificate** | Analyst (Anara) | **READ**: [Analyst](references/analyst.md) → marking rubrics atlas → active sector category only. | Certifies scale/cohesion — not “it runs” |
101| **Never-List / Slop Audit** | Auditor (Aurelius) | **READ**: [Auditor](references/auditor.md) → never-list encyclopedia → active sector + scanners on disk. | Surgical load — do not ingest entire encyclopedia |
102| **Agent Eyes / Visual QA** | Capture → WebP → Rubric | **READ**: [Agent Vision](references/agent-vision.md). Screenshot assets, window/region/screen, or TEMP editor bridge — then structured review. **Do NOT load** genre refs. | Host-side only; never Autoload / never leave staged addon |
103
104### The "When NOT to Use a Node" Decision
105One of the most impactful expert-only decisions. The Godot docs explicitly say "avoid using nodes for everything":
106
107| Type | When to Use | Cost | Expert Use Case |
108| :--- | :--- | :--- | :--- |
109| **`Object`** | Custom data structures, manual memory management | Lightest. Must call `.free()` manually. | Custom spatial hash maps, ECS-like data stores |
110| **`RefCounted`** | Transient data packets, logic objects that auto-delete | Auto-deleted when no refs remain. | `DamageRequest`, `PathQuery`, `AbilityEffect` — logic packets that don't need the scene tree |
111| **`Resource`** | Serializable data with Inspector support | Slightly heavier than RefCounted. Handles `.tres` I/O. | `ItemData`, `EnemyStats`, `DialogueLine` — any data a designer should edit in Inspector |
112| **`Node`** | Needs `_process`/`_physics_process`, needs to live in the scene tree | Heaviest — SceneTree overhead per node. | Only for entities that need per-frame updates or spatial transforms |
113
114**The expert pattern**: Use `RefCounted` subclasses for all logic packets and data containers. Reserve `Node` for things that must exist in the spatial tree. This halves scene tree overhead for complex systems.
115
116---
117
118## 🔧 Part 3: Core Workflows
119
120### Workflow 1: Professional Scaffolding
121*From empty project to production-ready container.*
122
123**MANDATORY — READ ENTIRE FILE**: [Foundations](references/project-foundations.md)
1241. Organize by **Feature** (`/features/player/`, `/features/combat/`), not by class type. A `player/` folder contains the scene, script, resources, and tests for the player.
1252. **READ**: [Signal Architecture](references/signal-architecture.md) — Create `GlobalSignalBus` autoload with < 15 events.
1263. **READ**: [GDScript Mastery](references/gdscript-mastery.md) — Enable `untyped_declaration` warning in Project Settings → GDScript → Debugging.
1274. Apply **[Project Templates](references/project-templates.md)** for base `.gitignore`, export presets, and input map.
1285. Use **[Builder](references/builder.md)** (`builder_create_scene.py`, `builder_add_node.py`, `builder_save_scene.py`) to generate scene hierarchies programmatically via the Godot CLI.
1296. After the container exists: optional early **Workflow 13** ([Analyst](references/analyst.md)) on foundations cohesion; before first ship, **Workflow 14** ([Auditor](references/auditor.md)) on signal/typing/export never-lists.
130
131> [!CAUTION] **Workflow 1 NEVER List**
132> - **NEVER** use `res://` paths in logic scripts. Use `@export_file` or `@export_dir` to ensure resources remain valid when moved.
133> - **NEVER** initialize children in `_init()`. The scene tree isn't ready. Use `_ready()` or `@onready`.
134> - **NEVER** keep "Default" project settings for `Physics Ticks`. Set to 60 for consistency, or use `Engine.physics_ticks_per_second` for adaptive logic.
135> - **NEVER** use `print()` in `_process()` for debugging; use the `Debugger` or `push_error()` to avoid frame-time spikes.
136
137**Do NOT load** combat, multiplayer, genre, or platform references during scaffolding.
138
139### Workflow 2: Entity Orchestration
140*Building modular, testable characters.*
141
142**MANDATORY Chain — READ ALL**: [Composition](references/composition.md) → [State Machine](references/state-machine-advanced.md) → [CharacterBody2D](references/characterbody-2d.md) or [Physics 3D](references/physics-3d.md) → [Animation Tree](references/animation-tree-mastery.md)
143**Do NOT load** UI, Audio, or Save/Load references for entity work.
144
145- The State Machine queries an `InputComponent`, never handles input directly. This allows AI/Player swap with zero refactoring.
146- The State Machine ONLY handles transitions. Logic belongs in Components. `MoveState` tells `MoveComponent` to act, not the other way around.
147- Every entity MUST pass the **F6 test**: pressing "Run Current Scene" (F6) must work without crashing. If it crashes, your entity has scene-external dependencies.
148
149> [!CAUTION] **Workflow 2 NEVER List**
150> - **NEVER** call `parent.do_thing()`. If the parent changes, the entity breaks. Emit a signal `request_action` instead.
151> - **NEVER** use `_process` for movement. Use `_physics_process` to avoid jitter on variable-refresh-rate monitors.
152> - **NEVER** hardcode animation names. Use a `StringName` constant or a `Resource` map to enable easy renaming in `AnimationPlayer`.
153> - **NEVER** use `get_node()` with absolute paths. Use `%UniqueName` to survive tree refactoring.
154
155### Workflow 3: Data-Driven Systems
156*Connecting Combat, Inventory, Stats through Resources.*
157
158**MANDATORY Chain — READ ALL**: [Resource Patterns](references/resource-data-patterns.md) → [RPG Stats](references/rpg-stats.md) → [Combat](references/combat-system.md) → [Inventory](references/inventory-system.md)
159
160- Create ONE `ItemData.gd` extending `Resource`. Instantiate it as 100 `.tres` files instead of 100 scripts.
161- The HUD NEVER references the Player directly. It listens for `player_health_changed` on the Signal Bus.
162- Enable "Local to Scene" on ALL `@export Resource` variables, or call `resource.duplicate()` in `_ready()`. Failure to do this is Bug #1 in Part 8.
163
164> [!CAUTION] **Workflow 3 NEVER List**
165> - **NEVER** pass `Node` references in a Signal Bus. Objects get freed; RIDs or IDs are safer for long-term tracking.
166> - **NEVER** modify a `.tres` file at runtime via code (it modifies the disk file). Always `.duplicate()` before modifying.
167> - **NEVER** use `Array` for high-frequency search. Use `Dictionary` with `StringName` keys for O(1) lookups.
168> - **NEVER** use `float` for item counts or precise resource tracking; use `int` and scale for display.
169
170### Workflow 4: Persistence Pipeline
171**MANDATORY**: [Autoload Architecture](references/autoload-architecture.md) → [Save/Load](references/save-load-systems.md) → [Scene Management](references/scene-management.md)
172
173- Use dictionary-mapped serialization. Old save files MUST not corrupt when new fields are added — use `.get("key", default_value)`.
174- For procedural worlds: save the **Seed** plus a **Delta-List** of modifications, not the entire map. A 100MB world becomes a 50KB save.
175
176> [!CAUTION] **Workflow 4 NEVER List**
177> - **NEVER** save whole `Object` or `Node` instances. They contain transient pointers. Extract data into a `Dictionary` or custom `Resource`.
178> - **NEVER** use `JSON` for data that needs strict typing (e.g., `Vector2`). Use `var_to_bytes` or `ConfigFile` for structured Godot types.
179> - **NEVER** block the main thread for auto-saves. Use a `Thread` or `WorkerThreadPool` to serialize large dictionaries.
180> - **NEVER** save to `res://` in an exported project; strictly use `user://` for persistent data.
181
182### Workflow 5: Performance Optimization
183**MANDATORY**: [Debugging/Profiling](references/debugging-profiling.md) → [Performance Optimization](references/performance-optimization.md)
184
185**Diagnosis-first approach** (NEVER optimize blindly):
1861. **High Script Time** → Profile with built-in Profiler. Check if `_process` is being called on hundreds of nodes. Move to single-manager pattern or Server APIs (see Part 6).
1872. **High Draw Calls** → Use `MultiMeshInstance` for repetitive geometry. Batch materials with ORM textures.
1883. **Physics Stutter** → Simplify collisions to primitive shapes. Load [2D Physics](references/2d-physics.md) or [3D Physics](references/physics-3d.md). Check if `_process` is used instead of `_physics_process` for movement.
1894. **VRAM Overuse** → Switch textures to VRAM Compression (BPTC/S3TC for desktop, ETC2 for mobile). Never ship raw PNG.
1905. **Intermittent Frame Spikes** → Usually GC pass, synchronous `load()`, or NavigationServer recalculation. Use `ResourceLoader.load_threaded_request()`.
191
192> [!CAUTION] **Workflow 5 NEVER List**
193> - **NEVER** use `get_nodes_in_group()` inside `_process`. It's an O(n) operation every frame. Cache the array in `_ready()`.
194> - **NEVER** use `Area2D` signals for "Stay" logic. Use `get_overlapping_bodies()` periodically or a manager-level `PhysicsServer` check.
195> - **NEVER** optimize before profiling. A 1ms script is irrelevant if you have 2000 draw calls killing the GPU.
196> - **NEVER** use `load()` in hot paths; strictly `preload` or use `ResourceLoader` for async loading.
197
198### Workflow 6: Cross-Platform Adaptation
199**MANDATORY**: [Input Handling](references/input-handling.md) → [Adapt Desktop→Mobile](references/adapt-desktop-to-mobile.md) → [Platform Mobile](references/platform-mobile.md)
200**Also read**: [Platform Desktop](references/platform-desktop.md), [Platform Web](references/platform-web.md), [Platform Console](references/platform-console.md), [Platform VR](references/platform-vr.md) as needed.
201
202- Use an `InputManager` autoload that translates all input types into normalized actions. NEVER read `Input.is_key_pressed()` directly — it blocks controller and touch support.
203- Mobile touch targets: minimum 44px physical size. Use `MarginContainer` with Safe Area logic for notch/cutout devices.
204- Web exports: Godot's `AudioServer` requires user interaction before first play (browser policy). Handle this with a "Click to Start" screen.
205
206> [!CAUTION] **Workflow 6 NEVER List**
207> - **NEVER** use `OS.get_name()` for feature detection. Use `OS.has_feature("mobile")` or custom feature tags to handle subsets like "SteamDeck."
208> - **NEVER** assume a specific aspect ratio. Always use `Expand` or `Keep Aspect` in combinations with `Anchor` nodes.
209> - **NEVER** use desktop-only shaders (e.g., complex depth sampling) on Mobile/Web without a GLES3/Compatibility secondary path.
210> - **NEVER** ignore `physical_keycode` for desktop builds; it ensures keyboard layouts (AZERTY/QWERTY) don't break movement.
211- **NEVER** pass unsanitized strings to `JavaScriptBridge.eval()` — Prevents script injection in web builds. Use a `sanitize_js_string()` helper.
212
213### Workflow 7: Procedural Generation
214**MANDATORY**: [Procedural Gen](references/procedural-generation.md) → [Tilemap Mastery](references/tilemap-mastery.md) or [3D World Building](references/3d-world-building.md) → [Navigation](references/navigation-pathfinding.md)
215
216- ALWAYS use `FastNoiseLite` resource with a fixed `seed` for deterministic generation.
217- Never bake NavMesh on the main thread. Use `NavigationServer3D.parse_source_geometry_data()` + `NavigationServer3D.bake_from_source_geometry_data_async()`.
218- For infinite worlds: chunk loading MUST happen on a background thread using `WorkerThreadPool`. Build the scene chunk off-tree, then `add_child.call_deferred()` on the main thread.
219
220> [!CAUTION] **Workflow 7 NEVER List**
221> - **NEVER** instantiate nodes for "Background" noise. Use `MultiMeshInstance` or draw loops in `_draw` for thousands of small details.
222> - **NEVER** regenerate the entire map for one change. Use a "Dirty Chunk" system to only update what exactly changed.
223> - **NEVER** place collisions on the same frame as mesh generation if using `concave_polygon_shape`. It stalls the physics thread.
224> - **NEVER** perform pathfinding queries every frame for all units. Use a `NavigationAgent` with `target_position` updates on a timer.
225
226### Workflow 8: Multiplayer Architecture
227**MANDATORY — READ**: [Single→Multiplayer](references/adapt-single-to-multiplayer.md) → [Networking](references/multiplayer-networking.md) → [Server Arch](references/server-architecture.md)
228**Do NOT load** single-player genre blueprints.
229
230- Client sends Input, Server calculates Outcome. The Client NEVER determines damage, position deltas, or inventory changes.
231- Use Client-Side Prediction with server reconciliation: predict locally, correct from server snapshot. Hides up to ~150ms of latency.
232- `MultiplayerSpawner` handles replication in Godot 4. Configure it per scene, not globally.
233
234> [!CAUTION] **Workflow 8 NEVER List**
235> - **NEVER** trust `rpc_id(1, ...)` (Client to Server) without validation. A hacked client can send `damage = 999999`.
236> - **NEVER** replicate `_process` transforms directly. Replicate `Input` vector and simulate movement on both sides.
237> - **NEVER** use `TCP` for high-frequency packets (movement). Use `UDP` / `ENet` and handle dropped packets with interpolation.
238> - **NEVER** synchronize every projectile; use Client-Side Prediction for visuals and only RPC the "Fire" event.
239
240- `ReflectionProbe` vs `VoxelGI` vs `SDFGI`: Probes are cheap/static, VoxelGI is medium/baked, SDFGI is expensive/dynamic. Choose based on your platform budget (see Part 5).
241
242### Workflow 9: Responsive UI & Expert Theming (Audit Verified)
243**MANDATORY Chain**: [UI Containers](references/ui-containers.md) → [UI Theming](references/ui-theming.md) → [Rich Text](references/ui-rich-text.md) → [Tweening](references/tweening.md)
244
2451. **The F6 Principle**: Every UI scene must be testable in isolation. Use `MOUSE_FILTER_STOP` only on the background, `PASS` on children.
2462. **Breathing Room**: Use `add_theme_constant_override("separation", X)` over manual padding.
2473. **Adaptive Scaling**: Use `ui_containers_responsive_layout_builder.gd` for breakpoint-aware mobile/desktop switching.
2484. **Lifecycle Safety**: Never scroll to a new child on the same frame. `await get_tree().process_frame` before modifying `scroll_vertical`.
2495. **Data Integration**: Use `Resource-to-UI` binding; UI nodes MUST be stateless projection layers.
2506. **See it**: Close with **Workflow 12** — [Agent Vision](references/agent-vision.md) window/asset capture → scored layout/type review. Agents cannot QA UI from text alone.
251
252> [!CAUTION] **Workflow 9 NEVER List**
253> - **NEVER** use absolute pixel offsets. UI becomes unreadable on 4K or tiny mobile screens. Use `Container` sizing.
254> - **NEVER** deep-nest `MarginContainers`. It makes the Inspector unusable. Use a single `Theme` resource for project-wide margins.
255> - **NEVER** connect UI buttons to gameplay logic directly. UI sends "Signal", `PlayerController` listens. This prevents UI-deletion crashes.
256> - **NEVER** use `_process()` to move a UI element to a target. Use a `Tween` to avoid stuttering and frame-rate dependence.
257> - **NEVER** leave `mouse_filter` as `STOP` on transparent containers; it "eats" clicks for everything behind it.
258> - **NEVER** use dynamic `load()` on paths without validating the `res://` prefix and safe extension (`.tres`, `.res`, `.theme`) — Prevents arbitrary code/resource execution.
259> - **NEVER** declare UI “done” without an Agent Vision capture of the live layout.
260
261### Workflow 10: Cinematic Lighting & VFX (Audit Verified)
262**MANDATORY Chain**: [3D Lighting](references/3d-lighting.md) → [Particles](references/particles.md) → [3D Materials](references/3d-materials.md) → [Shaders](references/shaders-basics.md)
263
2641. **The GI Choice**: VoxelGI for interiors, SDFGI for open world. Never ship with both overlapping.
2652. **Shadow Budget**: Max 2 Shadow-casting DirectionalLights. Use `3d_lighting_fake_gi_bounce.gd` for mobile fills.
2663. **VFX Lifecycle**: Use `finished` signal over Timers. Re-run with `restart()` to avoid async GPU stalls.
2674. **Optimization**: Use `ORM Texture` packing (AO/Rough/Metal) to save GPU cache and texture slots.
2685. **Batching**: Use `Instance Uniforms` for material variations across thousands of instances without draw call penalties.
2696. **See it**: Close with **Workflow 12** — [Agent Vision](references/agent-vision.md) editor/window capture to verify lighting, exposure, and VFX read in pixels.
270
271> [!CAUTION] **Workflow 10 NEVER List**
272> - **NEVER** scale `CollisionShape` nodes; strictly scale the Shape Resource to avoid physics jitter.
273> - **NEVER** use `TRANSPARENCY_ALPHA` for cutout meshes (leaves/fences); use `ALPHA_SCISSOR` to prevent sorting artifacts.
274> - **NEVER** animate CSG nodes during gameplay; forces expensive CPU geometry recalculation.
275> - **NEVER** use real-time Global Illumination (SDFGI/VoxelGI) for a 2D-looking game. Stick to `DirectionalLight2D` and `CanvasModulate`.
276> - **NEVER** ignore `Camera3D` near/far planes; improper settings cause Z-fighting in large worlds.
277> - **NEVER** trust lighting “looks fine” from code alone — capture the viewport with Agent Vision.
278
279### Workflow 11: Programmatic Scene Building (Builder)
280**MANDATORY**: [Builder](references/builder.md)
281**Use ONLY for batch operations or complex procedural scaffolds.** Prefer the standalone `godot-builder` skill when doing heavy CLI automation.
282
2831. **Step 1**: Draft the node hierarchy on paper/markdown before touching disk.
2842. **Step 2**: Use `builder_create_scene.py` to define the root node and `.tscn` path.
2853. **Step 3**: Use `builder_add_node.py` for children. Set `owner` on every node so serialization keeps them.
2864. **Step 4**: ALWAYS call `builder_run_project.py` or `builder_launch_editor.py` to verify the scene loads cleanly.
2875. **Step 5 (see it)**: After batch scene or UI writes, run **Workflow 12** ([Agent Vision](references/agent-vision.md)) — window/editor capture → WebP → scored review — so agents verify appearance, not only that the `.tscn` loads.
2886. **Expert Rule**: Use Builder to build the *structure* (nodes, names, inheritance), then use GDScript to build the *behavior*.
289
290> [!CAUTION] **Workflow 11 NEVER List**
291> - **NEVER** jump straight to `builder_add_node.py` without designing the hierarchy first — spaghetti scenes follow.
292> - **NEVER** use absolute filesystem paths in scripts or scene props; use `res://` only.
293> - **NEVER** add a `CollisionShape2D`/`CollisionShape3D` without assigning a Shape resource — the node alone does nothing.
294> - **NEVER** skip verification via `builder_run_project.py` / `builder_launch_editor.py` after batch scene writes.
295> - **NEVER** treat “scene loads” as visual QA — layout, type, and lighting bugs need Agent Vision captures.
296
297#### Security: Boundary Markers & Validation
298When agents ingest untrusted scene/data text before writing files:
2991. **Boundary Markers**: Wrap analysis in `<<<CONTEXT_START>>>` and `<<<CONTEXT_END>>>`.
3002. **Sanitization**: Node names must be alphanumeric/underscored. Paths must start with `res://`.
3013. **Verification**: Confirm scene existence before modification.
302
303### Workflow 12: Agent Eyes — See the Current Representation
304*How agents verify what the game/editor/UI actually looks like.*
305
306**MANDATORY — READ ENTIRE FILE**: [Agent Vision](references/agent-vision.md)
307**Prefer the standalone `godot-agent-vision` skill** when doing heavy capture/review loops. Hub mirrors keep prefixed scripts under `scripts/agent_vision_*`.
308
309**When to invoke (default, not optional):**
310- After UI/theme/layout changes (Workflow 9)
311- After lighting/VFX/material passes (Workflow 10)
312- After Builder or procedural scene scaffolds (Workflow 11)
313- Whenever the agent would otherwise *describe* pixels it has not captured
314- Asset sheet / icon / HUD typography review before shipping polish
315
316**Golden path:**
3171. **Setup**: `pip install -r skills/godot-agent-vision/requirements-vision.txt` (host venv). Ensure `.gdskills/` is gitignored (`agent_vision_ensure_gitignore.py`).
3182. **Doctor**: `agent_vision_capture.py doctor` — confirm display session / backends.
3193. **Capture** (pick one mode — do not dump full screens by default):
320 - Game/editor window: `agent_vision_capture.py window --project-root . --title Godot`
321 - Editor 2D/3D viewport: `agent_vision_capture.py editor --project-root . --editor-mode 3d --godot "%GODOT_PATH%"`
322 - Asset / icon sheet: `agent_vision_capture.py asset --project-root . --paths res://ui/icons --sheet`
323 - Desktop region: `agent_vision_capture.py region …` when window-by-title fails (Wayland, etc.)
3244. **Read** the budgeted WebP(s) from `.gdskills/vision/` (default short-edge 512). Use `--detail` only when type/OCR fails at 512.
3255. **Score** with the Taste Receptor Atlas / vision rubric in the Agent Vision refs — ordered fixes keyed to receptor IDs, not vibes.
3266. **Teardown**: never leave the TEMP editor bridge / `addons/_gdskills_agent_vision/` staged; never commit `.gdskills/vision/**`.
327
328> [!CAUTION] **Workflow 12 NEVER List**
329> - **NEVER** invent how the game looks without a capture — Agent Vision is the eyes.
330> - **NEVER** ship the editor bridge as an Autoload or leave it in the consumer project.
331> - **NEVER** dump uncompressed PNG walls into context — WebP only, budgeted.
332> - **NEVER** replace scored taste with binary PASS/FAIL or purple-gradient “AI default” UI praise.
333> - **NEVER** put ornate display faces on ammo/HP/timers (`TYPE-DISPLAY-HUD-SPLIT`).
334
335### Workflow 13: Architecture Scoring — Analyst (Anara)
336*Certify whether the project can survive tomorrow — not whether it merely runs.*
337
338**MANDATORY — READ ENTIRE FILE**: [Analyst](references/analyst.md)
339**Prefer the standalone `godot-analyst` skill** for full certification loops. Hub mirrors: `scripts/analyst_*`, nested `references/analyst-*.md`.
340
341**When to invoke:**
342- Before calling a milestone “architecture complete”
343- After large refactors (folder-by-feature, autoload sprawl, Resource graphs)
344- When the user asks for modernity / scalability / Visionary Certificate scoring
345- After Workflow 1 scaffolding or Workflow 2–4 systems land — score cohesion before more features
346
347**Golden path:**
3481. **Map**: Request the project root; map `res://` structure (feature folders, autoloads, dependency hotspots).
3492. **Atlas**: Load [analyst-marking_rubrics_atlas.md](references/analyst-marking_rubrics_atlas.md) — pick the Evolutionary Sector(s) in scope.
3503. **Sector only**: **MANDATORY** load matching category rubric file(s) under the Analyst progressive-disclosure tree. **Do NOT** load every category file.
3514. **Engine helpers** (only what exists on disk): `analyst_scoring_logic.gd`, `analyst_marking_rubrics_atlas.gd`, `analyst_visionary_comparison.gd` — do not invent phantom `score_*.py` fleets.
3525. **Synthesize**: Weighted scores → Visionary Certificate narrative + transcendence blueprint (gaps ordered by impact).
353
354> [!CAUTION] **Workflow 13 NEVER List**
355> - **NEVER** certify without the active sector rubric — guessing weights is not Visionary.
356> - **NEVER** parse `.tscn`/`.tres` by hand — use `ResourceLoader.get_dependencies` / `PackedScene.get_state`.
357> - **NEVER** treat “it runs” or green play as a pass — score scale, typing, decoupling, cohesion.
358> - **NEVER** load the entire Analyst categories tree into context.
359
360### Workflow 14: Never-List Enforcement — Auditor (Aurelius)
361*Find the invisible slop that invites bugs — then decree remediation.*
362
363**MANDATORY — READ ENTIRE FILE**: [Auditor](references/auditor.md)
364**Prefer the standalone `godot-auditor` skill** for deep audits. Hub mirrors: `scripts/auditor_*`, nested `references/auditor-*.md`.
365
366**When to invoke:**
367- Pre-merge / pre-release integrity pass
368- After signal, typing, export, or memory regressions
369- When Analyst scores flag decay — Auditor proves it with scanners + encyclopedia
370- Pair with Workflow 5 (performance) when ObjectDB / orphan / batching slop is suspected
371
372**Golden path:**
3731. **Survey**: Confirm project path + feature-folder integrity.
3742. **Encyclopedia**: Open [auditor-never_list_encyclopedia.md](references/auditor-never_list_encyclopedia.md) — identify the Architectural Sector.
3753. **Surgical load**: **MANDATORY** read only the matching category never-list file(s). **Do NOT** ingest the entire encyclopedia.
3764. **Scanners on disk** (call individually — do not invent missing tools):
377 - `auditor_audit_signals.py` — string `.connect` decay
378 - `auditor_audit_type_hints.py` — untyped Array/Dictionary + string-connect
379 - `auditor_audit_memory_fragmentation.gd` — ObjectDB / orphan snapshots
380 - `auditor_purge_report_generator.gd` — purge / unused-resource rollup
3815. **Decrees**: Findings with the *why* behind each never-list hit; ordered remediation. For sectors without a scanner, cite engine APIs from the loaded category — do not claim a phantom script ran.
382
383> [!CAUTION] **Workflow 14 NEVER List**
384> - **NEVER** load every never-list category at once — progressive disclosure only.
385> - **NEVER** invent `audit_*.py` scanners that are not in `scripts/`.
386> - **NEVER** soft-pedal export case-sensitivity, signal decay, or untyped hot-path collections.
387> - **NEVER** skip deterministic proof when a scanner exists for the request.
388
389**Persona triad (ship loop):** [Builder](references/builder.md) builds structure → [Agent Vision](references/agent-vision.md) sees pixels → [Analyst](references/analyst.md) scores architecture → [Auditor](references/auditor.md) enforces never-lists.
390
391---
392
393## 🚫 Part 4: The Expert NEVER List
394
395Each rule includes the **non-obvious reason** — the thing only shipping experience teaches.
396
3971. **NEVER use `get_tree().root.get_node("...")`** — Absolute paths break when ANY ancestor is renamed or reparented. Use `%UniqueNames`, `@export NodePath`, or signal-based discovery.
3982. **NEVER use `load()` inside a loop or `_process`** — Synchronous disk read blocks the ENTIRE main thread. Use `preload()` at script top for small assets, `ResourceLoader.load_threaded_request()` for large ones.
3993. **NEVER `queue_free()` while external references exist** — Parent nodes or arrays holding refs will get "Deleted Object" errors. Clean up refs in `_exit_tree()` and set them to `null` before freeing.
4004. **NEVER put gameplay logic in `_draw()`** — `_draw()` is called on the rendering thread. Mutating game state causes race conditions with `_physics_process`.
4015. **NEVER use `Area2D` for 1000+ overlapping objects** — Each overlap check has O(n²) broadphase cost. Use `ShapeCast2D`, `PhysicsDirectSpaceState2D.intersect_shape()`, or Server APIs for bullet-hell patterns.
4026. **NEVER mutate external state from a component** — If `HealthComponent` calls `$HUD.update_bar()`, deleting the HUD crashes the game. Components emit signals; listeners decide how to respond.
4037. **NEVER use `await` in `_physics_process`** — `await` yields execution, meaning the physics step skips frames. Move async operations to a separate method triggered by a signal.
4048. **NEVER use `String` keys in hot-path dictionary lookups** — String hashing is O(n). Use `StringName` (`&"key"`) for O(1) pointer comparisons, or integer enums.
4059. **NEVER store `Callable` references to freed objects** — Crashes silently or throws errors. Disconnect signals in `_exit_tree()` or use `CONNECT_ONE_SHOT`.
40610. **NEVER use `_process` for 1000+ entities** — Each `_process` call has per-node SceneTree overhead. Use a single `Manager._process` that iterates an array of data structs (Data-Oriented pattern), or use Server APIs directly.
40711. **NEVER use `Tween` on a node that may be freed** — If a node is `queue_free()`'d while a Tween runs, it errors. Kill tweens in `_exit_tree()` or bind to SceneTree: `get_tree().create_tween()`.
40812. **NEVER request data FROM `RenderingServer` or `PhysicsServer` in `_process`** — These servers run asynchronously. Calling getter functions forces a synchronous stall that kills performance. The APIs are intentionally designed to be write-only in hot paths.
40913. **NEVER use `call_deferred()` as a band-aid for initialization order bugs** — It masks architectural problems (dependency on tree order). Fix the actual dependency with explicit initialization signals or `@onready`.
41014. **NEVER create circular signal connections** — Node A connects to B, B connects to A. This creates infinite loops on the first emit. Use a mediator pattern (Signal Bus) to break cycles.
41115. **NEVER let inheritance exceed 3 levels** — Beyond 3, debugging `super()` chains is a nightmare. Use composition (`Node` children) to add behaviors instead.
41216. **NEVER use `_process` for hit detection or movement** in physics-heavy genres (FPS/ARPG); strictly use `_physics_process` to ensure frame-independent collision detection.
41317. **NEVER trust the client for authority** on persistent game state (Health, XP, Inventory). Handled exclusively via Server-Auth or Secure Checksums.
41418. **NEVER use standard strings** for high-frequency runtime checks; strictly use `StringName` (&"active") to avoid O(n) hashing.
41519. **NEVER manually handle RVO avoidance** every frame in unit-heavy games (RTS/MOBA); offload to `NavigationAgent` internal threading.
41620. **NEVER block the main thread** for procedural generation or heavy I/O; strictly offload to `WorkerThreadPool`.
41721. **NEVER ignore `Local-to-Scene` on Resources** used in unique instances (e.g. enemy stats); failure causes shared-memory bugs across all instances.
41822. **NEVER use `float` for currency**; strictly use Integer Cents to avoid precision drift in complex economies.
41923. **NEVER set `target_position` before `physics_frame`**; navigation maps are not ready during `_ready()`.
42024. **NEVER use `TRANSPARENCY_HASH` or `ALPHA`** for large cutout surfaces (foliage); use `ALPHA_SCISSOR` for performance and sorting.
42125. **NEVER scale `CollisionShape` nodes** (Node2D/3D scale) — Use shape handles or resize the resource to avoid unpredictable physics normals and jitter.
42226. **NEVER apply gravity while `is_on_floor()` is true** — Causes micro-jitter and prevents floor-snapping; strictly reset vertical velocity to 0 or a small constant.
42327. **NEVER forget to disconnect dynamic signals (Capturing Lambdas)** — Godot cannot auto-disconnect lambdas that capture local variables; they will cause crashes on freed objects.
42428. **NEVER use mouse events for mobile touch** — Strictly use `InputEventScreenTouch` and `InputEventScreenDrag` for reliable multi-touch support.
42529. **NEVER use Forward+ renderer for mobile** — Strictly use Mobile or Compatibility renderers to avoid GPU bottlenecks and battery drain.
42630. **NEVER accumulate mouse rotation directly on Transforms** — Strictly store separate Yaw/Pitch variables to prevent gimbal lock and precision loss.
42731. **NEVER use standard Strings for high-frequency runtime checks** — Strictly use `StringName` (&"active") to avoid O(n) hashing overhead.
42832. **NEVER trust the client for game state** (Health, Inventory) — Clients suggest actions; Server validates and broadcasts to prevent cheating.
42933. **NEVER use `Reliable` RPCs for movement updates** — Use `UnreliableOrdered` to prevent Head-of-Line blocking in high-latency scenarios.
430
431---
432
433## 📊 Part 5: Performance Budgets (Concrete Numbers)
434
435| Metric | Mobile Target | Desktop Target | Expert Note |
436| :--- | :--- | :--- | :--- |
437| **Draw Calls** | < 100 (2D), < 200 (3D) | < 500 | `MultiMeshInstance` for foliage/debris |
438| **Triangle Count** | < 100K visible | < 1M visible | LOD system mandatory above 500K |
439| **Texture VRAM** | < 512MB | < 2GB | VRAM Compression: ETC2 (mobile), BPTC (desktop) |
440| **Script Time** | < 4ms per frame | < 8ms per frame | Move hot loops to Server APIs |
441| **Physics Bodies** | < 200 active | < 1000 active | Use `PhysicsServer` direct API for mass sim |
442| **Particles** | < 2000 total | < 10000 total | GPU particles, set `visibility_aabb` manually |
443| **Audio Buses** | < 8 simultaneous | < 32 simultaneous | Use [Audio Systems](references/audio-systems.md) bus routing |
444| **Save File Size** | < 1MB | < 50MB | Seed + Delta pattern for procedural worlds |
445| **Scene Load Time** | < 500ms | < 2s | `ResourceLoader.load_threaded_request()` |
446
447---
448
449## ⚙️ Part 6: Server APIs — The Expert Performance Escape Hatch
450
451This is knowledge most Godot developers never learn. When the scene tree becomes a bottleneck, bypass it entirely using Godot's low-level Server APIs.
452
453### When to Drop to Server APIs
454- **10K+ rendered instances** (sprites, meshes): Use `RenderingServer` with RIDs instead of `Sprite2D`/`MeshInstance3D` nodes.
455- **Bullet-hell / particle systems** with script interaction: Use `PhysicsServer2D` body creation instead of `Area2D` nodes.
456- **Mass physics simulation**: Use `PhysicsServer3D` directly for ragdoll fields, debris, or fluid-like simulations.
457
458### 📊 Performance Comparison: SceneTree vs. Server APIs
459
460Bypassing the SceneTree eliminates the heavy CPU overhead of node lifecycle management, signal propagation, and virtual function overhead (like `_process`).
461
462| Metric | SceneTree (Nodes) | Server APIs (RIDs) | Expert Rationale |
463| :--- | :--- | :--- | :--- |
464| **Object Limit** | ~1,000 - 5,000 | 50,000+ | SceneTree has O(n) traversal costs; Servers use O(1) direct RID handles. |
465| **Memory Overhead** | ~2KB - 10KB per Node | < 200 bytes per RID | Nodes carry tree state, signals, and inspector metadata. RIDs are opaque 24-byte handles. |
466| **CPU Time** | High (Virtual calls) | Minimal (Direct API) | Nodes must call `_process` for every instance. Servers batch operations in C++. |
467| **Threading** | Main Thread Only | Inherently Thread-Safe | Most Server APIs are thread-safe (must be enabled in Project Settings). |
468| **Garbage Collection** | Automatic (RefCounted) | Manual (Alloc/Free) | Servers require manual lifecycle management (RID creation/deletion). |
469
470**Expert Note**: Using RIDs allows managing raw data and interacting directly with engine core logic. This is the primary "escape hatch" for bullet-hells, massive foliage, or complex procedural simulations where SceneTree housekeeping becomes the bottleneck.
471
472### The RID Pattern (Expert)
473Server APIs communicate through **RID** (Resource ID) — opaque handles to server-side objects. Critical rules:
474```gdscript
475# Create server-side canvas item (NO node overhead)
476var ci_rid := RenderingServer.canvas_item_create()
477RenderingServer.canvas_item_set_parent(ci_rid, get_canvas_item())
478
479# CRITICAL: Keep resource references alive. RIDs don't count as references.
480# If the Texture resource is GC'd, the RID becomes invalid silently.
481var texture: Texture2D = preload("res://sprite.png")
482RenderingServer.canvas_item_add_texture_rect(ci_rid, Rect2(-texture.get_size() / 2, texture.get_size()), texture)
483```
484
485### Threading with Servers
486- The scene tree is **NOT thread-safe**. But Server APIs (RenderingServer, PhysicsServer) ARE thread-safe when enabled in Project Settings.
487- You CAN build scene chunks (instantiate + add_child) on a worker thread, but MUST use `add_child.call_deferred()` to attach them to the live tree.
488- GDScript Dictionaries/Arrays: reads and writes across threads are safe, but **resizing** (append, erase, resize) requires a `Mutex`.
489- **NEVER** load the same `Resource` from multiple threads simultaneously — use one loading thread.
490
491---
492
493## 🧩 Part 7: Expert Code Patterns
494Expert implementations of common architectural and gameplay systems.
495
496- **[Component Registry](references/patterns/component_registry.md)**: Centralized dictionary-based component retrieval.
497- **[Safe Signal Handler](references/patterns/safe_signal_handler.md)**: Preventing crashes on freed object references.
498- **[Async Resource Loader](references/patterns/async_resource_loader.md)**: Threaded asset ingestion.
499- **[State Machine Transition Guard](references/patterns/state_machine_transition_guard.md)**: Validating state changes.
500- **[Thread-Safe Chunk Loader](references/patterns/thread_safe_chunk_loader.md)**: Low-level server-api construction.
501- **[Vision Cone Detection](references/patterns/vision_cone_detection.md)**: Expert NPC vision with dot products and raycasts.
502- **[Sound Propagation System](references/patterns/sound_propagation_system.md)**: Acoustic occlusion logic.
503- **[Stealth Hiding Logic](references/patterns/stealth_hiding_logic.md)**: Global visibility and concealment management.
504
505---
506
507## 🔥 Part 8: Godot 4.x Gotchas (Veteran-Only)
508
5091. **`@export` Resources are shared by default**: Multiple scene instances ALL share the same `Resource`. Use `resource.duplicate()` in `_ready()` or enable "Local to Scene" checkbox. This is the #1 most reported Godot 4 bug by newcomers.
5102. **Signal syntax silently fails**: `connect("signal_name", target, "method")` (Godot 3 syntax) compiles but does nothing in Godot 4. Must use `signal_name.connect(callable)`.
5113. **`Tween` is no longer a Node**: Created via `create_tween()`, bound to the creating node's lifetime. If that node is freed, the Tween dies. Use `get_tree().create_tween()` for persistent tweens.
5124. **`PhysicsBody` layers vs masks**: `collision_layer` = "what I am". `collision_mask` = "what I scan for". Setting both to the same value causes self-collision or missed detections.
5135. **`StringName` vs `String` in hot paths**: `StringName` (`&"key"`) uses pointer comparison (O(1)). `String` uses character comparison (O(n)). Always use `StringName` for dictionary keys in `_process`.
5146. **`@onready` timing**: Runs AFTER `_init()` but DURING `_ready()`. If you need constructor-time setup, use `_init()`. If you need tree access, use `@onready` or `_ready()`. Mixing them causes nulls.
5157. **Server query stalls**: Calling `RenderingServer` or `PhysicsServer` getter functions in `_process` forces a synchronous pipeline flush. These servers run async — requesting data from them stalls the entire pipeline until the server catches up.
5168. **`move_and_slide()` API change**: Returns `bool` (whether collision occurred). Velocity is now a property, not a parameter. `velocity = dir * speed` before calling `move_and_slide()`.
517
518---
519
520## 📂 Part 9: Module Directory (99 Blueprints)
521
522> [!IMPORTANT]
523> Load ONLY the modules needed for your current workflow. Use the Decision Matrix in Part 2 to determine which chain to follow.
524
525### Architecture & Foundation
526[Foundations](references/project-foundations.md) | [Composition](references/composition.md) | [App Composition](references/composition-apps.md) | [Signals](references/signal-architecture.md) | [Autoloads](references/autoload-architecture.md) | [States](references/state-machine-advanced.md) | [Resources](references/resource-data-patterns.md) | [Templates](references/project-templates.md) | [Analyst](references/analyst.md) | [Auditor](references/auditor.md) | [Builder](references/builder.md) | [Agent Vision](references/agent-vision.md)
527
528**Version upgrades (external hub):** [godot-version-migration](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-version-migration/SKILL.md) — full-history router (legacy eras, 3→4 bridge, 4.0→4.7 hops); not mirrored here.
529
530### GDScript & Testing
531[GDScript Mastery](references/gdscript-mastery.md) | [Testing Patterns](references/testing-patterns-expert-testing-patterns.md) | [Debugging/Profiling](references/debugging-profiling.md) | [Performance Optimization](references/performance-optimization.md)
532
533### 2D Systems
534[2D Animation](references/2d-animation.md) | [2D Physics](references/2d-physics.md) | [Tilemaps](references/tilemap-mastery.md) | [Animation Player](references/animation-player.md) | [Animation Tree](references/animation-tree-mastery.md) | [CharacterBody2D](references/characterbody-2d.md) | [Particles](references/particles.md) | [Tweening](references/tweening.md) | [Shader Basics](references/shaders-basics.md) | [Camera Systems](references/camera-systems.md)
535
536### 3D Systems
537[3D Lighting](references/3d-lighting.md) | [3D Materials](references/3d-materials.md) | [3D World Building](references/3d-world-building.md) | [Physics 3D](references/physics-3d.md) | [Navigation/Pathfinding](references/navigation-pathfinding.md) | [Procedural Generation](references/procedural-generation.md) | [Raycasting](references/raycasting-queries.md)
538
539### Gameplay Mechanics
540[Abilities](references/ability-system.md) | [Combat](references/combat-system.md) | [Dialogue](references/dialogue-system.md) | [Economy](references/economy-system.md) | [Inventory](references/inventory-system.md) | [Questing](references/quest-system.md) | [RPG Stats](references/rpg-stats.md) | [Turn System](references/turn-system.md) | [Audio](references/audio-systems.md) | [Scene Transitions](references/scene-management.md) | [Save/Load](references/save-load-systems.md) | [Secrets](references/mechanic-secrets.md) | [Collections](references/game-loop-collection.md) | [Waves](references/game-loop-waves.md) | [Harvesting](references/game-loop-harvest.md) | [Time Trials](references/game-loop-time-trial.md) | [Revival](references/mechanic-revival.md) | [Monte Carlo Balancer](references/monte-carlo-balancer.md)
541
542### UI & UX
543[UI Containers](references/ui-containers.md) | [Rich Text](references/ui-rich-text.md) | [Theming](references/ui-theming.md) | [Input Handling](references/input-handling.md) | [Seasonal Theming](references/theme-easter.md) | [Agent Vision](references/agent-vision.md)
544
545### Connectivity & Platforms
546[Multiplayer](references/multiplayer-networking.md) | [Server Logic](references/server-architecture.md) | [Export Builds](references/export-builds.md) | [Desktop](references/platform-desktop.md) | [Mobile](references/platform-mobile.md) | [Web](references/platform-web.md) | [Console](references/platform-console.md) | [VR](references/platform-vr.md)
547
548### Adaptation Guides
549- [Adapting Desktop -> Mobile](references/adapt-desktop-to-mobile.md)
550- [Adapting Mobile -> Desktop](references/adapt-mobile-to-desktop.md)
551- [Adapting Single -> Multiplayer](references/adapt-single-to-multiplayer.md)
552- [Adapting 2D -> 3D](references/adapt-2d-to-3d.md)
553- [Adapting 3D -> 2D](references/adapt-3d-to-2d.md)
554
555### Genre Blueprints (Exhaustive)
556[Action RPG](references/genre-action-rpg.md) | [Shooter](references/genre-shooter.md) | [Shooter FPS](references/genre-shooter-fps.md) | [RTS](references/genre-rts.md) | [MOBA](references/genre-moba.md) | [Rogue-like](references/genre-roguelike.md) | [Survival](references/genre-survival.md) | [Open World](references/genre-open-world.md) | [Metroidvania](references/genre-metroidvania.md) | [Platformer](references/genre-platformer.md) | [Fighting](references/genre-fighting.md) | [Stealth](references/genre-stealth.md) | [Sandbox](references/genre-sandbox.md) | [Horror](references/genre-horror.md) | [Puzzle](references/genre-puzzle.md) | [Racing](references/genre-racing.md) | [Rhythm](references/genre-rhythm.md) | [Sports](references/genre-sports.md) | [Battle Royale](references/genre-battle-royale.md) | [Card Game](references/genre-card-game.md) | [Visual Novel](references/genre-visual-novel.md) | [Romance](references/genre-romance.md) | [Simulation](references/genre-simulation.md) | [Tower Defense](references/genre-tower-defense.md) | [Idle Clicker](references/genre-idle-clicker.md) | [Party](references/genre-party.md) | [Educational](references/genre-educational.md)
557
558---
559
560## 🐛 Part 10: Expert Diagnostic Patterns
561
562### The "Invisible Node" Bug
563**Symptom**: Node exists in tree but isn't rendering.
564**Expert diagnosis chain**: `visible` property → `z_index` → parent `CanvasLayer` wrong layer → `modulate.a == 0` → behind camera's `near` clip (3D) → `SubViewport.render_target_update_mode` not set → `CanvasItem` not in any `CanvasLayer` (renders behind everything).
565
566### The "Input Eaten" Bug
567**Symptom**: Clicks or key presses ignored intermittently.
568**Expert diagnosis**: Another `Control` node with `mouse_filter = STOP` overlapping the target. Or, modal `PopupMenu` consuming unhandled input. Or, `_unhandled_input()` in another script calling `get_viewport().set_input_as_handled()`.
569
570### The "Physics Jitter" Bug
571**Symptom**: Character vibrates at surface contacts.
572**Expert diagnosis**: `Safe Margin` too large. Or, `_process` used for movement instead of `_physics_process` (interpolation mismatch). Or, collision shapes overlap at spawn (push each other apart permanently).
573
574### The "Memory Leak"
575**Symptom**: RAM grows steadily during play.
576**Expert diagnosis**: `queue_free()` called but reference held in Array/Dictionary. Or, signals connected with `CONNECT_REFERENCE_COUNTED` without cleanup. Use Profiler "Objects" tab to find orphaned instances. Search for `Node` instances without a parent.
577
578### The "Frame Spike"
579**Symptom**: Smooth FPS but periodic drops.
580**Expert diagnosis**: GDScript GC pass. Or, synchronous `load()` for a large resource. Or, `NavigationServer` rebaking. Or, Server API query stall (requesting data from `RenderingServer` in `_process`). Profile with built-in Profiler → look for function-level spikes.
581
582---
583
584## 🚀 Part 11: Quick Start — Unity (C#) to Godot (GDScript)
585
586Mental model shifts for senior engineers transitioning from the Unity ecosystem.
587
588### 1. Nodes vs. GameObjects & Components
589In Unity, a `GameObject` is a container for `Components`. In Godot, **everything is a Node**.
590- **Unity**: `GameObject` + `Transform` + `MeshFilter` + `Script`.
591- **Godot**: A `MeshInstance3D` node (which *is* a Transform and a Mesh) with a script attached.
592- **Expert Shift**: Use Node composition. If you need a "Health Component", add a `Node` or `Area3D` as a child called "Health". Use `RefCounted` for logic-only components to save memory.
593
594### 2. Scenes are Nested Prefabs
595Godot doesn't have "Prefabs" because **every scene is a prefab**.
596- You can instantiate a scene inside another scene, infinitely.
597- **Expert Shift**: Every reusable system (Player, Enemy, UI Button) should be its own `.tscn` file. This promotes "Post-Order Traversal" (children are ready before parents).
598
599### 3. Signals vs. Events/Actions
600Godot's `Signal` system is a native implementation of the Observer pattern.
601- **Unity**: `event Action OnDeath;`.
602- **Godot**: `signal died`.
603- **Expert Shift**: Signals are first-class citizens. They are visible in the Inspector and can be connected dynamically or via the editor. Use the "Signal Bus" pattern (Autoload) for global events to mimic Unity's Singleton managers.
604
605### 4. Scripts as Class Extensions
606When you attach a script to a node, that script **is** the node.
607- **Unity**: `GetComponent<MyScript>()`.
608- **Godot**: The script *extends* the node's class (e.g., `extends CharacterBody3D`).
609- **Expert Shift**: Use **Typed GDScript** (`var x: int = 5`) to gain compilation speedups and editor completion. Typed GDScript uses optimized opcodes when types are known at compile time.
610
611### 5. Memory Management: No Garbage Collection stalls
612Unlike Unity's C# which can have "GC spikes", GDScript uses Reference Counting.
613- **Expert Shift**: Objects are freed the moment they are no longer referenced. This provides deterministic performance and avoids the intermittent "stutters" common in large Unity projects.
614
615### 6. StringNames & Performance
616Unity uses `int` or `Enum` for performance. Godot uses `StringName`.
617- **Expert Shift**: Use `&"name"` for constant-time (O(1)) pointer comparisons in dictionaries and signal lookups.
618
619---
620
621## Reference
622- [Godot 4.7 Official Documentation](https://docs.godotengine.org/en/4.7/)
623- [Godot 4.7 Migration Guide](https://docs.godotengine.org/en/4.7/tutorials/migrating/upgrading_to_godot_4.7.html)
624- [Godot Engine GitHub Discussions](https://github.com/godotengine/godot/discussions)