2d-essentials
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
Works with
Agent Skills format with YAML frontmatter. Claude Code reads it as-is.
---
name: "2d-essentials"
description: "Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+"
license: "MIT"
---
# 2D Essentials in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.
> **Related skills:** **player-controller** for CharacterBody2D movement patterns, **animation-system** for AnimatedSprite2D and sprite animation, **physics-system** for collision shapes and raycasting, **camera-system** for Camera2D follow and shake, **shader-basics** for 2D shaders and post-processing, **godot-optimization** for rendering and draw call tuning.
---
## 1. Canvas Layers and Draw Order
### Draw Order Rules
Within a single canvas layer, nodes draw in **scene tree order** — nodes listed lower in the Scene panel draw **on top**. Use `z_index` to override without rearranging the tree.
```gdscript
# Draw this node above siblings (default z_index is 0)
z_index = 10
# Make z_index relative to parent (default: false = global)
z_as_relative = true
```
### CanvasLayer
`CanvasLayer` creates a separate rendering layer with its own transform, independent of the camera. Higher `layer` values draw on top.
| Layer | Typical Use |
|-------|-------------|
| -1 | Parallax backgrounds |
| 0 | Default game layer (all Node2D without CanvasLayer) |
| 1 | HUD / UI overlay |
| 2 | Pause menu, screen transitions |
```
# Scene tree example
Main
├── ParallaxBackground (CanvasLayer, layer = -1)
│ └── Parallax2D
├── World (Node2D — default layer 0)
│ ├── TileMapLayer
│ └── Player
└── HUD (CanvasLayer, layer = 1)
└── Control
```
> **Note:** CanvasLayers are NOT required to control draw order. For objects within the same game world, use `z_index` or scene tree ordering. CanvasLayers are for elements that should be independent of the camera (HUD, parallax, transitions).
### Canvas Transform
`Camera2D` works by modifying the viewport's `canvas_transform`. For manual control:
```gdscript
# Scroll the canvas directly (equivalent to camera movement)
get_viewport().canvas_transform = Transform2D(0, Vector2(-200, 0))
```
### Coordinate Conversion
```gdscript
# Local to canvas (world) coordinates
var world_pos: Vector2 = get_global_transform() * local_pos
var local_pos: Vector2 = get_global_transform().affine_inverse() * world_pos
# Local to screen coordinates (accounts for camera, stretch, window)
var screen_pos: Vector2 = get_viewport().get_screen_transform() * get_global_transform_with_canvas() * local_pos
```
```csharp
// Local to canvas (world) coordinates
Vector2 worldPos = GetGlobalTransform() * localPos;
Vector2 localFromWorld = GetGlobalTransform().AffineInverse() * worldPos;
// Local to screen coordinates
Vector2 screenPos = GetViewport().GetScreenTransform() * GetGlobalTransformWithCanvas() * localPos;
```
---
## 2. TileMap System
`TileMapLayer` (Godot 4.5+) is the modern API — one tilemap = one node = one layer. Drive painting with a `TileSet` resource (atlas + properties + physics + custom data). Use **terrain autotiling** for biome-aware tile selection, **scene collection tiles** for placing scene instances on tiles.
> See [references/tilemap.md](references/tilemap.md) for full TileSet setup, atlas / physics / terrain configuration, custom data on tiles, scene collection tiles, and the 4.5+ tile-collision-bump auto-merge fix.
---
## 3. Parallax Scrolling
`Parallax2D` (Godot 4.4+) replaces the older `ParallaxBackground`/`ParallaxLayer` pair. Set `scroll_scale` per layer (0 = static, 1 = follows camera 1:1, fractional values for depth). Add `repeat_size` for infinite tiling.
> See [references/parallax.md](references/parallax.md) for `Parallax2D` setup, side-scroller layer example, infinite repeat, split-screen parallax, common mistakes.
---
## 4. 2D Lights and Shadows
`PointLight2D` and `DirectionalLight2D` cast lighting onto sprites — pair with a normal map for 3D-style shading or use additive-blend illumination on flat sprites. Cast shadows with `LightOccluder2D`.
> See [references/lights-and-shadows.md](references/lights-and-shadows.md) for node overview, PointLight2D properties, shadow settings, cull masks, occluders, 2D normal maps, pixel-art lighting tips, and additive-sprite fake-light tricks.
---
## 5. 2D Particle Systems
`GPUParticles2D` for high counts (≥ 50 particles, GPU-driven), `CPUParticles2D` for low counts or platforms without GPU support. Both share the same `ParticleProcessMaterial` interface; differences are mainly performance.
> See [references/2d-particles.md](references/2d-particles.md) for the GPU-vs-CPU distinguishing choices, basic setup, ParticleProcessMaterial 2D properties, emission from textures, flipbook, visibility rect, common 2D recipes.
---
## 6. Custom Drawing
Override `_draw()` on any `CanvasItem` to draw lines, polygons, text, or arbitrary shapes. Call `queue_redraw()` to trigger a re-render (never call `_draw()` directly).
> See [references/custom-drawing.md](references/custom-drawing.md) for the `_draw()` method, redrawing patterns, full drawing-methods reference, default font usage, `@tool` editor preview, line-width gotchas.
> **Godot 4.7+:** `DrawableTexture2D` — a runtime-drawable texture type — shipped experimental in 4.7 and is not yet recommended for production.
---
## 7. 2D Meshes
### When to Use
`MeshInstance2D` replaces `Sprite2D` when large transparent areas waste GPU fill rate. The GPU draws the entire texture quad including fully transparent pixels — a mesh eliminates those.
### Converting Sprite2D to MeshInstance2D
1. Select the `Sprite2D`
2. Menu: **Sprite2D → Convert to MeshInstance2D**
3. Adjust growth and simplification parameters
4. Click "Convert 2D Mesh"
Best candidates:
- Screen-sized images with transparency
- Parallax layers with irregular shapes
- Layered images with large transparent borders
- Mobile/low-end GPU targets
---
## 8. 2D Antialiasing
### Per-Node Antialiasing (Recommended)
Many drawing methods support an `antialiased` parameter:
```gdscript
draw_line(Vector2.ZERO, Vector2(100, 50), Color.WHITE, 2.0, true) # antialiased = true
```
```csharp
// Equivalent in a CanvasItem subclass (e.g., a custom Control or Node2D):
public override void _Draw()
{
DrawLine(new Vector2(0, 0), new Vector2(100, 50), Colors.White, width: 2.0f, antialiased: true);
}
```
`Line2D` has an `Antialiased` property in the inspector — set it via `line2D.Antialiased = true` in C# or as an Inspector toggle in the editor. This works by generating additional geometry — no MSAA needed.
> ⚠️ **Changed in Godot 4.7:** `CanvasItem` antialiased line drawing no longer adds the antialiasing feather. The feather made `draw_line()`-style lines appear thicker than intended, so antialiased lines render thinner after upgrading — projects that relied on the old look must draw a thicker `width`. See the [4.7 migration guide](https://docs.godotengine.org/en/latest/tutorials/migrating/upgrading_to_godot_4.7.html).
### MSAA 2D
Available in Forward+ and Mobile renderers only (NOT Compatibility).
**Project Settings → Rendering → Anti Aliasing → Quality → MSAA 2D**
Levels: 2x, 4x, 8x.
| MSAA affects | MSAA does NOT affect |
|-------------|---------------------|
| Geometry edges (lines, polygons) | Aliasing within nearest-neighbor textures |
| Sprite edges touching texture edges | Custom 2D shader output |
| | Font rendering |
| | Specular aliasing with Light2D |
> **For pixel art:** Do NOT enable MSAA 2D — it blurs intentionally sharp edges. Use the per-node `antialiased` parameter selectively.
---
## 9. 2D Snapping and Pixel-Perfect
### Editor Snapping
Three-dot menu in the 2D toolbar:
- **Grid Step** — snap to grid (configure Grid Offset and Step)
- **Rotation Step** — snap rotation to degrees
- **Smart Snap** — snap to parent, node anchors, sides, centers, guides
### Runtime Pixel Snap
For pixel-art games, enable pixel snapping to prevent subpixel jitter:
- **Node2D:** Project Settings → Rendering → 2D → Snapping → `Snap 2D Transforms to Pixel`
- **Vertices:** Project Settings → Rendering → 2D → Snapping → `Snap 2D Vertices to Pixel`
- **Controls:** Project Settings → GUI → General → `Snap Controls to Pixels`
---
## 10. Implementation Checklist
- [ ] Background is a Sprite2D or ColorRect (not the default clear color) so it receives 2D lighting
- [ ] TileSet is saved as an external `.tres` resource for reuse across levels
- [ ] TileSet has `Use Texture Padding` enabled to prevent texture bleeding
- [ ] Parallax2D textures have top-left at (0,0), not centered
- [ ] `repeat_size` matches actual texture dimensions
- [ ] `repeat_times` is increased if the camera can zoom out
- [ ] LightOccluder2D nodes are added to shadow-casting objects when shadows are enabled
- [ ] Light and occluder cull masks are configured to avoid unnecessary light calculations
- [ ] GPUParticles2D has a valid Visibility Rect (auto-generate via Particles menu)
- [ ] `queue_redraw()` is called when custom drawing state changes
- [ ] Collision shapes on tiles use the Physics Layer system, not manual CollisionShape2D nodes
- [ ] Large transparent sprites are converted to MeshInstance2D on mobile/low-end targetsMore General & Other skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.

