Skip to content
Development
Skill

/godot-3d-essentials

Set up a Godot 4.7 3D scene: Node3D transforms, Camera3D, lighting (DirectionalLight3D/OmniLight3D), WorldEnvironment for sky/ambient/tonemap/post, MeshInstance3D materials, and GridMap for tile-based 3D levels. Use when building a 3D scene in a Godot project, placing

From plugin
awesome-gamedev-agent-skills
6.3k77 skills

Claude Code

$ npx -y skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-3d-essentials --agent claude-code

SKILL.md

godot-3d-essentials.SKILL.md
name: godot-3d-essentials
description: >
  Godot 4.7 3D scene setup: Camera3D, lights, WorldEnvironment (sky, ambient, tonemap, fog),
  StandardMaterial3D, GridMap and local vs global transforms, with a headless scene check. Use
  when a 3D scene renders black or washed out, a mesh is invisible, or a child rotates on the
  wrong axis. Not for spatial shaders (`godot-shaders`), bodies and raycasts (`godot-physics`) or
  camera feel (`camera-systems`).

Godot 3D Essentials (4.x)

Assemble a 3D scene that shows what it should in the running game: a current camera, real lights, an environment, materials and GridMap blockouts. Targets **Godot 4.7**; read `config/features` and `rendering/renderer/rendering_method` in `project.godot` first, because Forward+, Mobile and Compatibility differ in what they draw.

Workflow

1. **Check the renderer** (`rendering/renderer/rendering_method`: `forward_plus`, `mobile` or `gl_compatibility`). Mobile and Compatibility (web, low-end) have no SDFGI, SSIL, screen-space reflections or volumetric fog, and Mobile also has no SSAO, so do not build the look on them for those targets. The reference has the renderer table. 2. **One current `Camera3D` per viewport.** Set `current = true` on the one you want. Godot's convention is -Z forward, +Y up. 3. **Light the scene in the scene itself.** The editor viewport's preview sun and preview environment (toolbar toggles) do not exist at runtime. Add a `DirectionalLight3D` and a `WorldEnvironment` to the main scene, or set `rendering/environment/defaults/default_environment`. 4. **Configure the `Environment`:** background (sky or colour), ambient source, tonemapper, then post effects. Pick the tonemapper before tuning light energy or glow. 5. **Materials:** `StandardMaterial3D` on `MeshInstance3D.material_override` (all surfaces) or `set_surface_override_material(i, mat)`; `ShaderMaterial` for custom looks. 6. **Block out with `GridMap`** and a `MeshLibrary`. 7. **Verify before you finish** (paths are relative to this skill's folder):

  • If `godot-nodes-scenes` is installed, run `python3 ../godot-nodes-scenes/scripts/check_godot_project.py <project>`

and fix every `ERROR`.

  • Run `godot --headless --path <project> --script <this skill>/assets/check_3d_scene.gd -- res://level.tscn`

(no scene argument means the main scene). It needs no GPU and exits 1 when there is no current camera, nothing lights the meshes, a sky background has no `Sky`, or a mesh is hidden by the camera's `cull_mask`, behind the camera or past `far`.

  • To see a frame without a GPU, render one in software with Movie Maker:

`xvfb-run -a godot --path <project> --rendering-driver opengl3 --write-movie shots/f.png --quit-after 3 res://level.tscn` writes `shots/f00000000.png` and up, which you can open and inspect. This draws with the Compatibility renderer, so judge Forward+ looks by asking the user for a screenshot.

Patterns

1. Sun and environment from code

func _ready() -> void:
    var sun := DirectionalLight3D.new()
    sun.rotation_degrees = Vector3(-50, -30, 0)   # pointing down: -X tilt
    sun.shadow_enabled = true
    add_child(sun)

    var env := Environment.new()
    env.background_mode = Environment.BG_SKY
    env.sky = Sky.new()
    env.sky.sky_material = ProceduralSkyMaterial.new()
    env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
    env.tonemap_mode = Environment.TONE_MAPPER_AGX
    var world_env := WorldEnvironment.new()
    world_env.environment = env
    add_child(world_env)

Only one `WorldEnvironment` applies per world: the first one keeps control and a later one is ignored without a runtime message (the editor shows a node warning).

2. A material from code

func tint(mesh: MeshInstance3D, color: Color) -> void:
    var mat := StandardMaterial3D.new()
    mat.albedo_color = color
    mat.roughness = 0.6
    mesh.material_override = mat   # wins over surface and mesh materials

3. Fill a GridMap from code

@onready var grid: GridMap = $GridMap   # mesh_library and cell_size set on the node

func build_floor(width: int, depth: int, item_id: int) -> void:
    for x in width:
        for z in depth:
            grid.set_cell_item(Vector3i(x, 0, z), item_id)   # -1 clears a cell

Gotchas

  • **Fine in the editor, dark or flat in the game** → the editor preview sun and environment

were doing the lighting. Put a light and a `WorldEnvironment` in the scene.

  • **Meshes are black** → nothing lights them. With no `Environment`, Forward+ and Mobile still

add flat ambient from `rendering/environment/defaults/default_clear_color`, but Compatibility adds none, so the same scene is dim grey on desktop and black on web. An `Environment` with ambient `Disabled` or a black colour background does the same.

  • **Plain grey screen** → no current camera, so you only see the clear colour; or the camera

sits inside a mesh, whose back faces are culled.

  • **Wrong camera renders** → a camera in an instanced sub-scene also has `current = true`.

Keep `current` on one camera, or call `make_current()` after the scene loads.

  • **A mesh is missing** → its `layers` do not overlap the camera's `cull_mask`, it is past

`far`, or an imported mesh has flipped normals (try `cull_mode = CULL_DISABLED` to test).

  • **`look_at()` errors and does nothing** → the target equals the node's position, the up

vector is parallel to the view direction (looking straight down with `Vector3.UP`), or the node is not in the tree yet; use `look_at_from_position()` before `add_child()`.

  • **Local vs global mix-ups** → `position`/`rotation` are parent-relative; `look_at()` and

`global_position` are world space.

  • **Non-uniform scale distorts collision and lights** → scale the mesh resource or use uniform

scale on bodies.

  • **Washed-out or blown highlights** → the tonemapper is `Linear` (no tonemapping) or glow

thres

Read more
@gamedev-skills
Ships withawesome-gamedev-agent-skills

<img src="docs/assets/awesome-gamedev-agent-skills-banner.png" width="820" alt="awesome-gamedev-agent-skills — game-dev skills for AI coding agents.

Stars on GitHub

Momentum

stars in total
6.3k
Star history of gamedev-skills/awesome-gamedev-agent-skills on GitHub, a chart by star-history.com

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills12d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about godot-3d-essentials.

Which coding agents can use godot-3d-essentials?
godot-3d-essentials installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.