godot-engine
Godot 4 engine quirks, known bugs, workarounds, scene builder patterns, and material/lighting setup.
Skill by dragoscirjan
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/dragoscirjan-godot-engine
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: writing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/godot-engine
What's inside
- Skill name
godot-engine- Description
- Godot 4 engine quirks, known bugs, workarounds, scene builder patterns, and material/lighting setup. Load before writing GDScript that interacts with the engine.
- License
- MIT
- Instructions
- 334 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Godot Engine — Quirks & Scene Generation
## Two Script Types
GDScript files in this pipeline fall into two categories. Confusing them is a major bug source.
### Scene Builders (build-time, headless)
- `extends SceneTree` with `_initialize()` entry point
- Run via `godot --headless --script build_scene.gd`
- Build node hierarchy, set owners, pack, validate, save `.tscn`, then `quit()`
- Do NOT use: `@onready`, `preload()`, signal connections, `look_at()`, `to_global()`
- `_process()` signature: `func _process(delta: float) -> bool:` (returns bool, not void)
### Runtime Scripts (game logic)
- `extends Node2D/3D`, `CharacterBody3D`, etc.
- Use `_ready()`, `_process()`, `_physics_process()`, signals, `@onready`
- Attached to scene nodes via `set_script()` in builders or editor
## Known Quirks
### Headless / Scene Builder Specific
- **RID leak errors on exit** — headless builders always produce these. Harmless; ignore.
- **`add_to_group()` in builders** — groups set at build-time persist in saved `.tscn` files.
- **`_ready()` skipped in `_initialize()`** — `_ready()` on instantiated scene nodes does NOT fire during `_initialize()`. Call init methods manually after `root.add_child()`.
- **Autoloads in SceneTree scripts** — cannot reference autoload singletons by name (compile error). Find via `root.get_children()` and match by `.name`.
- **`preload()` vs `load()` during generation** — do NOT use `preload()` for scenes/resources that may not exist yet. Use `load()`.
- **No spatial methods in `_initialize()`** — `look_at()`, `to_global()` fail because nodes aren't in the tree yet. Use `rotation_degrees` or compute transforms manually.
### Serialization
- **MultiMeshInstance3D + GLBs** — does NOT render after pack+save (mesh resource reference lost). Use individual GLB instances instead.
- **GLB `material_override` doesn't serialize** — setting `material_override` on GLB-internal MeshInstance3D nodes does NOT persist in `.tscn` because `set_owner_on_new_nodes()` skips GLB children. Use procedural ArrayMesh when custom material is required.
- **MultiMeshInstance3D `Mesh.duplicate()`** — needed before freeing the source GLB instance, otherwise the mesh resource is garbage-collected.
### Physics
- **`free()` vs `queue_free()` in test harnesses** — `queue_free()` leaves the node in `root.get_children()` until frame end, blocking name reuse. Use `free()` when immediately replacing scenes.
- **BoxShape3D on trimesh** — snags on collision edges (Godot/Jolt bug). Use CapsuleShape3D for objects that slide across trimesh surfaces.
- **Default collision mask misses non-default layers** — new bodies get `collision_mask = 1`. If terrain/walls use layer 2+, player falls through. Always set mask to include all needed layers.
- **Collision layer bitmask vs UI index** — `collision_layer`/`collision_mask` are bitmasks. UI Layer 1 = bitmask 1, Layer 2 = bitmask 2, Layer 3 = bitmask 4, Layer 4 = bitmask 8 (powers of 2).
- **Collision state changes in callbacks** — changing `.disabled` inside `body_entered`/`body_exited` → "Can't change state while flushing queries". Use `set_deferred("disabled", false)`.
- **`CharacterBody3D.MOTION_MODE_FLOATING`** — needed for non-platformer 3D movement (vehicles, snowboards). GROUNDED mode's `floor_stop_on_slope` fights slope movement.
- **`reset_physics_interpolation()`** — call when teleporting or switching cameras to prevent interpolation glitch.
- **2D collision shape sizing** — slightly smaller than tile (e.g., 48px in 64px grid) allows smooth cornering through 1-tile corridors.
### Camera
- **Camera2D has no `current` property** — use `make_current()`, only after node is in scene tree.
- **Camera lerp from origin** — cameras using `lerp()` in `_physics_process()` will swoop from (0,0,0) on first frame. Use an `_initialized` flag to snap position on first frame, then lerp.
- **Chase camera `current` re-assertion** — game cameras that set `current = true` in `_physics_process()` override the test harness camera every frame. Test harnesses must disable the game camera EVERY frame.
### Video/Movie Writer
- **`--write-movie` frame 0** — first frame renders before `_process()` runs. Camera position set in `_process()` won't appear until frame 1. Pre-position camera in `_initialize()` via `position`/`rotation_degrees` (NOT `look_at()`).
- **`await` during `--write-movie`** — `await get_tree().process_frame` advances the movie frame counter each tick. Use `_init_frames` counter in `_physics_process()` instead of await chains.
### Visual / Material
- **Frame-rate dependent drag** — `speed *= (1 - drag)` per tick is exponential decay tied to tick rate. Use `speed *= exp(-rate * delta)` for frame-rate independent damping.
- **ProceduralSkyMaterial sun disc** — uses DirectionalLight3D direction/color. Set `sky_mode = SKY_MODE_LIGHT_AND_SKY` on sun, `SKY_MODE_LIGHT_ONLY` on fill lights — otherwise multiple sun discs appear.
- **Smooth yaw tracking 360 spin** — `lerp()` on raw angles causes 360-degree spin-arounds. Wrap difference to [-PI, PI]: `var diff: float = fmod(target_yaw - current_yaw + 3.0 * PI, TAU) - PI`.
- **`StandardMaterial3D` with `no_depth_test = true` + `TRANSPARENCY_ALPHA`** → invisible. Use opaque + unshaded for overlays.
- **Z-fighting** between layered surfaces: offset 0.15-0.30m vertically + `render_priority = 1`.
- **`cull_mode = CULL_DISABLED`** as safety net on all procedural meshes until winding is confirmed correct.
- **UV tiling double-scaling** — do NOT use world-space UV coords AND `uv1_scale` together. Pick one.
- **MultiMeshInstance3D `custom_aabb`** — must cover the entire visible area. Without it, the MultiMesh gets frustum-culled when the camera moves to edges.
- **MultiMeshInstance3D materials** — has no `set_surface_override_material()`. Use `material_override` or keep materials from source mesh.
### Timing / Signals
- **Sibling signal timing in `_ready()`** — `_ready()` fires on children in tree order. If sibling A emits in its `_ready()`, sibling B hasn't connected yet. Fix: after connecting, check if the emitter already has data and call the handler manually.
- **`get_path()` is a built-in Node method** — returns NodePath. Cannot override. Name yours `get_track_path()`, `get_road_path()`, etc.
- **Spawn immunity for revealed items** — items spawned inside an active Area2D get `area_entered` immediately → destroyed same frame. Track `_alive_time` in `_process()`, ignore `area_entered` for ~0.8s.
## Type Inference Errors
Three common issues — applies in both scene builders and runtime scripts:
```gdscript
# WRONG — load() returns Resource, no instantiate():
var scene := load("res://assets/glb/car.glb")
var model := scene.instantiate() # Error
# WRONG — := with instantiate() causes Variant inference error:
var scene: PackedScene = load("res://assets/glb/car.glb")
var model := scene.instantiate() # Error
# CORRECT — type load() AND use = (not :=) for instantiate():
var scene: PackedScene = load("res://assets/glb/car.glb")
var model = scene.instantiate() # Works
# WRONG — := with polymorphic math functions (return Variant):
var x := abs(speed) # Error
# Affected: abs, sign, clamp, min, max, floor, ceil, round, lerp,
# smoothstep, move_toward, wrap, snappedf, randf_range, randi_range
# WRONG — := with array/dictionary element access (returns Variant):
var pos := positions[i] # Error
# CORRECT — explicit type or untyped:
var pos: Vector3 = positions[i] # OK
var val = my_dict["key"] # OK (untyped)
```
## Pass-by-Value Pitfall
`bool`, `int`, `float`, `Vector3`, `AABB`, `Transform3D` etc. are value types — assigning to a parameter inside a function does NOT update the caller:
```gdscript
# WRONG — result never updates caller:
func collect(node: Node, result: AABB) -> void:
result = result.merge(child_aabb) # lost at return
# CORRECT — use Array accumulator:
func collect(node: Node, out: Array) -> void:
out.append(child_aabb)From dragoscirjan/opencode-config, MIT.
More from dragoscirjan/opencode-config
- 0.474score
develop-tdd
dragoscirjan
When this skill is loaded, the developer follows the Red-Green-Refactor cycle.
SkillCFreshness: CClaude Code +9 - 0.471score
clean-code
dragoscirjan
Clean code principles, SOLID, design patterns, readability, error handling, and universal quality tooling.
SkillCFreshness: CClaude Code +9 - 0.471score
developer-devops
dragoscirjan
DevOps and infrastructure standards — principles for IaC, CI/CD, and automation.
SkillCFreshness: CClaude Code +9 - 0.471score
developer-frontend
dragoscirjan
Frontend development standards — UI/UX principles, accessibility, state management, and component patterns.
SkillCFreshness: CClaude Code +9 - 0.471score
game-bootstrap
dragoscirjan
Godot 4 project scaffolding — project.godot, architecture notes, script stubs, scene builders, build order.
SkillCFreshness: CClaude Code +9 - 0.471score
game-design
dragoscirjan
Visual target generation, risk-first game decomposition, and verification criteria.
SkillCFreshness: CClaude Code +9 - 0.471score
game-execution
dragoscirjan
Task implementation workflow, test harnesses, screenshot/video capture, visual debugging.
SkillCFreshness: CClaude Code +9 - 0.471score
issue-tracking
dragoscirjan
Manage tasks, epics, and bugs based on ISSUE_TRACKING environment variable.
SkillCFreshness: CClaude Code +9 - 0.468score
game-assets
dragoscirjan
Budget-aware asset planning, image/3D/animation generation, background removal.
SkillCFreshness: CClaude Code +9 - 0.468score
platform-export
dragoscirjan
Cross-platform Godot 4 export — Windows, macOS, Linux, Android, iOS.
SkillCFreshness: CClaude Code +9 - 0.467score
cvs
dragoscirjan
Rules for interacting with local version control and remote platforms (GitHub, GitLab, Forgejo) based on the CVS_TOOL environment variable.
SkillCFreshness: CClaude Code +9 - 0.464score
developer-backend
dragoscirjan
Backend development standards — general backend architecture, security, and tooling.
SkillCFreshness: CClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 3
- Last commit (this folder)
- May 28, 2026 (5 months ago)
- Last release
- Jun 2, 2026 (4 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/dragoscirjan/opencode-config
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from dragoscirjan
- 0.474score
develop-tdd
dragoscirjan
When this skill is loaded, the developer follows the Red-Green-Refactor cycle.
SkillCFreshness: CClaude Code +9 - 0.471score
developer-frontend
dragoscirjan
Frontend development standards — UI/UX principles, accessibility, state management, and component patterns.
SkillCFreshness: CClaude Code +9 - 0.471score
clean-code
dragoscirjan
Clean code principles, SOLID, design patterns, readability, error handling, and universal quality tooling.
SkillCFreshness: CClaude Code +9 - 0.471score
developer-devops
dragoscirjan
DevOps and infrastructure standards — principles for IaC, CI/CD, and automation.
SkillCFreshness: CClaude Code +9 - 0.471score
game-bootstrap
dragoscirjan
Godot 4 project scaffolding — project.godot, architecture notes, script stubs, scene builders, build order.
SkillCFreshness: CClaude Code +9 - 0.471score
game-design
dragoscirjan
Visual target generation, risk-first game decomposition, and verification criteria.
SkillCFreshness: CClaude Code +9
Cite this page
godot-engine skill. Agent Mart. https://agentmart.dev/skills/dragoscirjan-godot-engine (last updated 2026-10-24)