Godot Adapt 2d To 3d logo

Godot Adapt 2d To 3d

Community
thedivergentai
godot-adapt-2d-to-3d

Expert patterns for migrating 2D games to 3D including node type conversions, camera systems (third-person, first-person, orbit), physics layer migration, sprite-to-model art pipeline, and control scheme adaptations. Use when porting 2D projects to 3D or adding 3D elements. Trigger keywords: CharacterBody2D to CharacterBody3D, Area2D to Area3D, Camera2D to Camera3D, Vector2 to Vector3, collision_layer migration, sprite to MeshInstance3D, 2D to 3D conversion.

Overview

Publisherthedivergentai
RepositoryGD-Agentic-Skills
Skill namegodot-adapt-2d-to-3d
Stars
727
Forks
43
Bundled files
12
LicenseLGPL-3.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 12 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by thedivergentai on GitHub. Read the source before you install it.

Installation

Install the Godot Adapt 2d To 3d AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/thedivergentai/GD-Agentic-Skills.git /tmp/GD-Agentic-Skills
mkdir -p .claude/skills
cp -r /tmp/GD-Agentic-Skills/skills/godot-adapt-2d-to-3d .claude/skills/godot-adapt-2d-to-3d
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Godot Adapt 2d To 3d in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Godot Adapt 2d To 3d on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Godot Adapt 2d To 3d is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

NEVER Do

  • NEVER directly replace Vector2 with Vector3(x, y, 0) — This creates a "flat 3D" game with no depth gameplay. Add Z-axis movement or camera rotation to justify 3D.
  • NEVER keep 2D collision layers — 2D and 3D physics use separate layer systems. You must reconfigure collision_layer/collision_mask for 3D nodes.
  • NEVER forget to add lighting — 3D without lights is pitch black (unless using unlit materials). Add at least one DirectionalLight3D.
  • NEVER use Camera2D follow logic in 3D — Camera3D needs spring arm or look-at logic. Direct position copying causes clipping and disorientation.
  • NEVER assume same performance — 3D is 5-10x more demanding. Budget for lower draw calls, smaller viewport resolution on mobile.
  • NEVER use the rotation property for complex 3D logic — 3D rotation uses Euler angles. Interpolating Euler angles causes unpredictable paths and Gimbal Lock. Always use Quaternion for 3D rotation interpolation or the Basis matrix for directional vectors.
  • NEVER ignore metric scaling — 3D physics and lighting assume 1 unit = 1 meter. Scaling models inside the engine introduces precision errors. Export assets from DCCs at the correct metric scale.
  • NEVER disable physics interpolation when using custom camera follow scripts — Updating camera position in _process to follow a body moving in _physics_process causes jitter. Use Node3D.get_global_transform_interpolated() for smooth transforms.

Available Scripts

MANDATORY: Load migration scripts before pasting camera/movement recipes.

spring_arm_camera_setup.gd

MANDATORY third-person SpringArm3D + Camera3D. Do not parent Camera3D bare to the body.

characterbody3d_migration_movement.gd

MANDATORY camera-relative CharacterBody3D movement for 2D→3D ports.

physics_layer_migration_checklist.gd

MANDATORY checklist: 3D Physics layer names are separate from 2D — mirror names, then apply bits.

sprite_plane.gd

Sprite3D billboard configuration and world-to-screen projection for placing 2D UI over 3D objects.

vector_mapping.gd

Vector2↔Vector3 mapping helpers (Y-up vs Z-forward pitfalls).

crisp_projected_ui.gd

Diegetic / projected UI sharpness patterns.

adapt_2d_to_3d_patterns.gd

Billboards, mouse→3D rays, CanvasLayer overlay helpers.

navigation_bridge_2d5d.gd

Projects NavigationServer3D paths to 2D screen/gameplay plane for 2.5D sprite actors.

massive_crowd_manager.gd

MultiMesh + billboard shader crowd (GPU orientation; not per-node Sprite3D).

Do NOT Load lighting deep-dives here — route to godot-3d-lighting. Add a DirectionalLight3D + ambient only; GI/cascades live there.


Node Conversion Matrix

2D Node3D EquivalentNotes
CharacterBody2DCharacterBody3DMANDATORY characterbody3d_migration_movement.gd
RigidBody2DRigidBody3DGravity Vector3(0, -9.8, 0)
StaticBody2DStaticBody3DShape3D resources (no auto-convert)
Area2DArea3DSame trigger idea; new layers
Sprite2DMeshInstance3D / Sprite3DBillboard vs mesh art choice
Camera2DCamera3DMANDATORY spring_arm_camera_setup.gd
CollisionShape2DCollisionShape3DRe-author shapes
RayCast2DRayCast3Dtarget_position is Vector3

Migration Steps (script-first)

  1. Physics layersMANDATORY physics_layer_migration_checklist.gd. Project Settings → Layer Names → 3D Physics.
  2. CameraMANDATORY spring_arm_camera_setup.gd. Never copy Camera2D follow onto Camera3D.
  3. MovementMANDATORY characterbody3d_migration_movement.gd. Camera-relative XZ; jump on Y.

Art Pipeline: Sprites → 3D Models

Option 1: Billboard Sprites (2.5D)

gdscript
# Use Sprite3D for quick conversion
extends Sprite3D

func _ready() -> void:
    texture = load("res://sprites/character.png")
    billboard = BaseMaterial3D.BILLBOARD_ENABLED  # Always face camera
    pixel_size = 0.01  # Scale sprite in 3D space

Option 2: Quad Meshes (Floating Sprites)

gdscript
# Create textured quads
var mesh_instance := MeshInstance3D.new()
var quad := QuadMesh.new()
quad.size = Vector2(1, 1)
mesh_instance.mesh = quad

var material := StandardMaterial3D.new()
material.albedo_texture = load("res://sprites/character.png")
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
material.cull_mode = BaseMaterial3D.CULL_DISABLED  # Show both sides
mesh_instance.material_override = material

Option 3: Full 3D Models (Blender/Asset Library)

gdscript
# Import .glb, .fbx models
var character := load("res://models/character.glb").instantiate()
add_child(character)

# Access animations
var anim_player := character.get_node("AnimationPlayer")
anim_player.play("idle")

Lighting Considerations

Minimum: one DirectionalLight3D + WorldEnvironment ambient so the scene is not black. Do NOT Load cascade/GI/bake tutorials in this skill — godot-3d-lighting.


UI Adaptation

gdscript
# ✅ GOOD: Keep 2D UI overlay
# Scene structure:
# Main (Node3D)
#   ├─ WorldEnvironment
#   ├─ DirectionalLight3D
#   ├─ Player (CharacterBody3D)
#   └─ CanvasLayer  # 2D UI on top of 3D world
#       └─ Control (HUD)

# UI remains 2D (Control nodes, Sprite2D for HUD elements)

Performance Budgeting (profiler gates)

Speculative "2D vs 3D budget" tables lie. Gate on measured data:

  1. Open Profiler / Debugger → Monitors after the port runs on target hardware.
  2. Draw calls / primitives — if MeshInstance count explodes, add Mesh LOD / Visibility Ranges before guessing vertex caps.
  3. Shadow cost — lower directional_shadow_max_distance and shadowed Omni/Spot count until frame time recovers (tune in godot-3d-lighting).
  4. LOD procedure — set visibility_range_* on distant GeometryInstance3D; unlit/simplified materials past the near band.
  5. Fail gate — ship only when 95th-percentile frame time meets the platform target (e.g. ≤16.6 ms for 60 FPS), not when a spreadsheet says "50–100 draw calls".

Input Scheme Changes

2D → 3D Input Mapping

gdscript
# 2D: left/right for horizontal movement
Input.get_axis("left", "right")

# 3D: Add forward/back, use get_vector()
var input := Input.get_vector("left", "right", "forward", "back")
# Returns Vector2(horizontal, vertical) for 3D movement

# Configure in Project Settings → Input Map:
# forward: W, Up Arrow
# back: S, Down Arrow
# left: A, Left Arrow
# right: D, Right Arrow

# Mouse look (lock cursor)
func _ready() -> void:
    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _input(event: InputEvent) -> void:
    if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
        rotate_camera(event.relative)

Edge Cases

Physics Not Working

gdscript
# Problem: Forgot to set collision layers for 3D
# Solution: Reconfigure layers

var body := CharacterBody3D.new()
body.collision_layer = 0b0001  # What AM I?
body.collision_mask = 0b0110   # What do I DETECT?

Camera Clipping Through Walls

Use MANDATORY spring_arm_camera_setup.gd — set spring_arm.collision_mask to the World layer so the boom retracts instead of clipping.

Player Falling Through Floor

gdscript
# Problem: StaticBody3D floor has no CollisionShape3D
# Solution: Add collision

var floor_collision := CollisionShape3D.new()
var box_shape := BoxShape3D.new()
box_shape.size = Vector3(100, 1, 100)
floor_collision.shape = box_shape
floor.add_child(floor_collision)

Decision Tree: When to Go 3D

FactorStay 2DGo 3D
GameplayPlatformer, top-down, no depth neededExploration, first-person, 3D space combat
Art budgetPixel art, limited resources3D models available or necessary
Performance targetMobile, web, low-endDesktop, console, high-end mobile
Development timeLimitedHave time for 3D learning curve
Team skills2D artists only3D artists or asset library

Expert Techniques & Optimizations

1. Vector Math over Euler Angles

When moving a 3D character, rely heavily on Transform3D basis vectors rather than calculating trigonometric angles. To move forward locally, extract the negative Z-axis of your transform's basis: velocity = transform.basis.z * speed.

2. Understanding Coordinate Discrepancies

In 2D, the Y-axis points down. In 3D, Godot uses a right-handed system where Y-axis points UP, and forward is -Z. Translating 2D jumps to 3D requires inverting the Y velocity logic (e.g., velocity.y = JUMP_SPEED instead of -JUMP_SPEED).

3. 2.5D Navigation (Camera-Projected Paths)

For 2.5D games where actors move on a 3D floor but are displayed as 2D sprites, query the NavigationServer3D directly and project the resulting PackedVector3Array into 2D screen space (or a flattened gameplay plane) using Camera3D.unproject_position.

gdscript
class_name NavigationBridge2D5D extends Node

## Projects 3D NavigationServer paths to 2D screenspace for 2.5D movement.
static func query_2_5d_path(camera: Camera3D, map_rid: RID, start_2d: Vector2, target_2d: Vector2) -> PackedVector2Array:
    # 1. Project 2D screen points to the 3D ground plane (Y=0).
    var start_3d := camera.project_position(start_2d, 0.0)
    var target_3d := camera.project_position(target_2d, 0.0)
    
    # 2. Query optimized 3D path.
    var path_3d := NavigationServer3D.map_get_path(map_rid, start_3d, target_3d, true)
    
    # 3. Project 3D world points back to 2D screenspace coordinates for the sprite.
    var path_2d := PackedVector2Array()
    for point in path_3d:
        path_2d.append(camera.unproject_position(point))
        
    return path_2d

4. Shader-Based Billboarding (Massive Crowd Rendering)

To render millions of instances, use MultiMeshInstance3D paired with a custom Visual Shader. Use VisualShaderNodeBillboard with BILLBOARD_TYPE_FIXED_Y to ensure sprites stay upright on flat terrain.

gdscript
class_name MassiveCrowdManager extends MultiMeshInstance3D
## Efficiently manages millions of camera-facing instances via GPU hardware.

func _ready() -> void:
    # 1. Configure the MultiMesh for 3D transforms.
    multimesh = MultiMesh.new()
    multimesh.transform_format = MultiMesh.TRANSFORM_3D
    multimesh.instance_count = 10000
    
    # 2. Build a ShaderMaterial using VisualShaderNodeBillboard.
    var material := ShaderMaterial.new()
    # Note: Logic assumes billboard_type=BILLBOARD_TYPE_FIXED_Y and keep_scale=true.
    multimesh.mesh = QuadMesh.new()
    multimesh.mesh.surface_set_material(0, material)
    
    # 3. Populate transforms. The GPU handles orientation.
    for i in range(multimesh.instance_count):
        var pos := Vector3(randf() * 100, 0, randf() * 100)
        multimesh.set_instance_transform(i, Transform3D(Basis(), pos))

5. Lighting Migration

PointLight2D→OmniLight3D conversion is one-shot editor work — keep a project tool if needed. Ongoing lighting quality belongs in godot-3d-lighting.

Deep recipes (on demand)

TopicReference / script
Step-by-step migration / perf gatesmigration-recipes.md
2.5D nav bridge / crowd billboardsinline Expert Techniques + bundled scripts

Reference

Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.

Official Documentation

  • Introduction to 3D — Coordinate system, Node3D, and camera basics you must adopt when leaving the CanvasItem/Y-down 2D world.
  • Using transformsBasis/Transform3D/Quaternion patterns that replace Euler-angle Camera2D follow and 2D rotation habits.
  • CharacterBody3D — Destination move_and_slide API after CharacterBody2D → CharacterBody3D conversion (no dedicated 3D tutorial page).
  • Physics introduction — Separate 2D/3D layer systems, units (1 unit ≈ 1 m), and gravity vectors that invalidate copied 2D masks.
  • Collision shapes (3D) — Shape3D equivalents for BoxShape2D/CapsuleShape2D when rebuilding CollisionShape3D stacks.
  • SpringArm3D — Third-person boom + occlusion pull-in that must replace direct Camera2D position copying.
  • 3D lights and shadows — Minimum DirectionalLight3D/OmniLight3D setup; 3D scenes are black without lights or unlit materials.
  • Environment and post-processing — WorldEnvironment ambient fill so ports are not pitch-black between key lights.
  • Standard Material 3D — Billboard, transparency, and shading modes for Sprite3D/QuadMesh sprite→plane art paths.
  • Using GridMaps — MeshLibrary/GridMap replacement for TileMapLayer-style level layouts in 3D.
  • Importing 3D scenes — GLB/FBX scale and animation import when leaving the sprite pipeline for real meshes.
  • Physics interpolation introduction — Why camera follow in _process needs interpolated transforms after physics-step movement.

Related Skills

Prerequisites
  • godot-gdscript-mastery — Typed Vector2/Vector3 and Transform3D fluency before applying Y→Z mapping helpers.
  • godot-characterbody-2d — Source platformer/top-down movement semantics you are lifting into CharacterBody3D.
  • godot-2d-physics — Existing 2D layer/mask design that must be recreated under the separate 3D physics layer table.
  • godot-input-handlingInput.get_vector plus mouse-capture look so 2D left/right maps become camera-relative XZ.
Complements
  • godot-camera-systems — SpringArm3D / orbit / first-person rigs that replace Camera2D follow after the port.
  • godot-3d-lighting — DirectionalLight3D, shadows, and ambient environments required once sprites become lit meshes.
  • godot-3d-materials — PBR/billboard/alpha materials for QuadMesh and Sprite3D art migration.
  • godot-3d-world-building — GridMap, collision generation, and LOD after TileMapLayer worlds move to 3D.
  • godot-raycasting-queries — Mouse→world PhysicsRayQueryParameters3D picks used by point-and-click 3D ports.
  • godot-ui-containers — CanvasLayer HUD that stays 2D while world content becomes Node3D.
  • godot-navigation-pathfinding — NavigationServer3D paths for 2.5D bridges that still project to screen or gameplay planes.
  • godot-adapt-3d-to-2d — Inverse adaptation lattice when deciding to flatten back or keep hybrid 2.5D.
Downstream / consumers
Master
  • godot-master — Library router and mirrored module entry; open when discovering which Domain Skill owns a cross-cutting 2D/3D concern.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Godot Adapt 2d To 3d AI skill do?

Expert patterns for migrating 2D games to 3D including node type conversions, camera systems (third-person, first-person, orbit), physics layer migration, sprite-to-model art pipeline, and control scheme adaptations. Use when porting 2D projects to 3D or adding 3D elements. Trigger keywords: CharacterBody2D to CharacterBody3D, Area2D to Area3D, Camera2D to Camera3D, Vector2 to Vector3, collision_layer migration, sprite to MeshInstance3D, 2D to 3D conversion.

Why use Godot Adapt 2d To 3d on TypingMind?

Because you install it once and use it with any model. Godot Adapt 2d To 3d is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Godot Adapt 2d To 3d in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/thedivergentai/GD-Agentic-Skills/tree/main/skills/godot-adapt-2d-to-3d. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Godot Adapt 2d To 3d?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Godot Adapt 2d To 3d?

As many as you like. As long as a model supports skills, you can use Godot Adapt 2d To 3d with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Godot Adapt 2d To 3d AI skill free?

Yes. It is published on GitHub by thedivergentai under the LGPL-3.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇