Skip to main content
Glama

3D world

world3d

Build 3D levels in Godot with undoable actions: create meshes, CSG blockouts, materials, lights, cameras, environments, and scatter props. Positions in meters, colors in hex, inputs validated.

Instructions

Build 3D levels in few calls: primitive meshes with material + collision, CSG blockouts (nested boolean trees), materials (files or on nodes), lights, WorldEnvironment/sky presets with a sun, cameras aimed at targets, model import options + instancing, GridMap painting and MeshLibrary creation, and scattering props/vegetation over terrain. Every scene change is undoable. Positions are [x, y, z] in meters (Y up; a Node3D looks down its -Z axis). Colors are hex strings like '#aa8844' or names like 'orange'. Numbers and vectors are validated: a malformed value returns an error instead of a zero/NaN result.

Actions:

  • mesh: {shape: box|sphere|capsule|cylinder|cone|plane|prism|torus|quad|text (default box), parent?='.', name?, size? (box/prism [x,y,z] or one number; plane [w,d]; quad [w,h]; sphere/cylinder: diameter from size), radius?, height?, top_radius?, bottom_radius?, inner_radius?, outer_radius?, text?, font_size?, depth?, pixel_size?, font?, mesh_props?: {raw PrimitiveMesh props}, mesh?: 'res://x.tres' (a Mesh resource instead of shape), material?, position?, rotation_degrees?, scale?, look_at?: [x,y,z] | node path, cast_shadow?, props?: {raw MeshInstance3D props}, collision?: none|static|convex|trimesh} MeshInstance3D in one call. collision='static' adds StaticBody3D > CollisionShape3D with a best-fit shape (box/sphere/capsule/cylinder; plane/torus/text -> trimesh, cone/prism -> convex). Defaults: box 1m, sphere r=0.5, plane 2x2.

  • csg: {type: box|sphere|cylinder|cone|torus|polygon|mesh|combiner, parent?, name?, operation?: union|intersection|subtraction, size? (box [x,y,z]; sphere/cylinder diameter), radius?, height?, inner_radius?, outer_radius?, sides?, polygon?: [[x,y],...], depth?, mode?, mesh?: {shape, size...} | 'res://x.tres', material?, use_collision? (root only), position?, rotation_degrees?, scale?, props?, children?: [same spec...]} CSG blockout. Build a whole shape in one call, e.g. {type: 'combiner', name: 'House', use_collision: true, children: [{type: 'box', name: 'Walls', size: [4,3,4]}, {type: 'box', operation: 'subtraction', size: [1,2,1], position: [0,1,2]}]}. A material on a combiner becomes its material_override. Parent can be an existing CSG node.

  • material: {path: 'res://mat.tres' | node path, type?: standard|orm|shader (default: edit the existing material, else standard), props?: {albedo_color, albedo_texture, metallic, roughness, emission: '#hex', emission_energy, emission_texture, normal_texture, normal_scale, ao_texture, height_texture, unshaded, transparent, double_sided, uv_scale, triplanar, billboard, rim, clearcoat, filter: 'nearest', ...any BaseMaterial3D property; for shader: shader, params}, albedo_color?/color?/albedo_texture?/metallic?/roughness?/emission?/shader?/params? (shortcuts for props), material?: 'res://existing.tres' | '#hex' | {props} (node mode: what to assign), surface? (surface override index), save_as? (node mode: also save the material to this .tres and assign the file), assign_to? (file mode: also assign to this node), overwrite?} With a .tres path: create, or edit in place (every user of the file changes; a bad key changes nothing). With a node path: assign to material_override (meshes), material (CSG, CanvasItem, FogVolume) or a surface override; editing a node whose material is a shared file edits an embedded copy (reported in 'note').

  • light: {type: directional|omni|spot (default omni), parent?, name?, color?, energy?, range? (omni/spot), angle? (spot cone degrees 0-180), attenuation?, indirect_energy?, specular?, shadows?, position?, rotation_degrees?, look_at?: [x,y,z] | node path, props?: {raw Light3D props}} add a light. Directional defaults to rotation [-50,-30,0] with shadows.

  • environment: {preset?: default|sunny|night|foggy|studio|space, sky?: {type: procedural|panorama|physical|shader, top_color, horizon_color, ground_color, ground_horizon_color, energy, sun_size, panorama: 'res://sky.hdr', shader, params} | 'res://sky.hdr' | 'res://sky.gdshader' | false, ambient?: '#hex' | energy | {color, energy, source, sky_contribution}, fog?: bool | density | {density, color, height, height_density, sky_affect, ...fog_* without prefix}, volumetric_fog?, glow?: bool | intensity | {intensity, bloom, threshold, ...}, ssao?, ssil?, ssr?, sdfgi?, tonemap?: 'filmic'|'aces'|'agx'|'linear' | {mode, exposure, white}, adjustment?: {brightness, contrast, saturation}, background?: 'sky' | '#hex', props?: {raw Environment props}, sun?: bool | {color, energy, rotation_degrees, shadows, name, props}, update_sun?=true, save_path?, reset?, keep?, parent?, name?} Creates or updates the scene's single WorldEnvironment (+ Sky, + a DirectionalLight3D sun unless one exists, which is updated instead). A preset replaces the current look (keep=true layers it on top); other keys tweak the current one.

  • camera: {parent?, name?='Camera3D', position?=[0,2,5], look_at?: [x,y,z] | node path, rotation_degrees?, fov? (1-179), projection?: perspective|orthographic, size? (orthographic), near?, far?, current?=true, props?} add a Camera3D aimed at a point/node; becomes the current camera (others are un-set, undoably).

  • look_at: {path, target: [x,y,z] | node path, model_front?} rotate a Node3D so its -Z (or +Z with model_front=true, for imported models facing +Z) points at the target.

  • import: {path: 'res://model.glb', props?: {root_type: 'StaticBody3D', root_name, root_scale, root_script, generate_collisions: true, collision_shape: trimesh|convex|decompose_convex|box|sphere|cylinder|capsule|auto, body_type: static|rigid|area, fps, import_animation, generate_lods, light_baking: disabled|static|static_lightmaps|dynamic, or raw keys like 'meshes/ensure_tangents'} (the friendly keys also work at top level)} edit the asset's .import options and reimport. Without props: lists current options. Works for any importer (textures too, with raw keys like 'compress/mode').

  • instance: {model: 'res://x.glb' | 'res://x.tscn', parent?, name?, position?, positions?: [[x,y,z], ...] (several copies, max 500), rotation_degrees?, scale?, props?} instance an imported model or scene.

  • gridmap: {path? (existing GridMap) | parent?+name? (new), mesh_library: 'res://tiles.tres' (required for a new map), cell_size?=[2,2,2], cells?: [{pos: [x,y,z], item: 'Floor' | id, orientation?} or [x,y,z,item,orientation?]], fill?: [{from, to, item, orientation?}] (inclusive boxes, e.g. floors), erase?: [[x,y,z], ...], clear? (wipe first), position?, props?} create or paint a GridMap (undoable). Cells are integer grid coordinates. orientation: 0/90/180/270 (Y degrees), 'x90'/'z-90'/'y180', [rx,ry,rz] multiples of 90, or a raw index 0-23. item -1 erases.

  • mesh_library: {path: 'res://tiles.tres', from_scene?: 'res://tiles.tscn' (each MeshInstance3D becomes an item named after the node; StaticBody3D>CollisionShape3D children become its collision, NavigationRegion3D its navmesh; like Scene > Export As > MeshLibrary; CSG nodes are skipped), items?: [{name, shape|mesh, size?, radius?, height?, material?, collision?: true|false|convex|trimesh (default true), offset?}], replace?} create/merge a MeshLibrary for GridMap. Existing libraries are merged by item name unless replace=true; nothing changes if any item is invalid.

  • scatter: {source: 'res://tree.tscn' | 'res://rock.glb' | 'res://m.tres' (Mesh) | {shape, radius?, size?, material?}, parent?, name?='Scatter', count?=50, area?: {center: [x,y,z], size: [w,d] | [w,h,d] | w, radius?}, seed?, align_to_ground? (raycast down: lands on the LOWEST collider/visible mesh under each point, so props don't stack on roofs, trees or earlier props), ground?: node path | [paths] (only land on these; implies align_to_ground), align_to_normal?, y_offset?, random_rotation_y?=true, scale_range?=[1,1], min_distance?, mode?: multimesh (default for meshes; fast, visual only) | instances (default for scenes; real nodes with collision/scripts, max 2000), material?, item_name?, cast_shadow?} scatter props/vegetation.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
farNoCamera far plane.
fogNotrue | density | {density, color, height, ...}.
fovNoCamera field of view (degrees).
skyNoSky spec: {type, top_color, horizon_color, ground_color, energy, panorama, shader, params} or res:// path, or false.
ssrNotrue | max_steps | {...}.
sunNotrue/false or {color, energy, rotation_degrees, shadows, name, props}.
areaNoScatter area: {center: [x,y,z], size: [w,d]} or {center, radius}.
fillNoGridMap boxes: {from: [x,y,z], to: [x,y,z], item, orientation?}.
fontNoTextMesh font (res:// path).
glowNotrue | intensity | {intensity, bloom, threshold, ...}.
keepNoenvironment: layer the preset on top of the current Environment.
meshNores:// Mesh resource (mesh), or CSGMesh3D mesh: {shape, size...} | res:// path (csg).
modeNoScatter mode: multimesh | instances.
nameNoNode name.
nearNoCamera near plane.
pathNoNode path, or res:// file path (material/import/mesh_library).
seedNoRandom seed (repeatable results).
sizeNoSize: number, [x,y,z] (box/prism/CSG box) or [w,d] (plane/quad); camera orthographic size; scatter area size.
ssaoNotrue | intensity | {radius, intensity, ...}.
ssilNotrue | intensity | {...}.
textNoText for shape='text'.
typeNoCSG type, material type (standard|orm|shader) or light type (directional|omni|spot).
angleNoSpot angle in degrees.
cellsNoGridMap cells: {pos: [x,y,z], item: name|id, orientation?} or [x,y,z,item,orientation?].
clearNoGridMap: clear all cells first.
colorNoLight color: hex, name or [r, g, b].
countNoNumber of scattered items.
depthNoTextMesh / CSG polygon extrusion depth.
eraseNoGridMap cells to clear: [[x,y,z], ...].
itemsNoMeshLibrary items: {name, shape|mesh, size?, material?, collision?, offset?}.
modelNores:// .glb/.gltf/.fbx/.blend/.tscn to instance.
propsNoProperty map. Values are coerced to the property type: numbers, [x,y], 'Vector2(1,2)', '#ff8800', 'res://file', {"type":"RectangleShape2D","size":[32,32]} for new resources, enum names as strings.
rangeNoOmni/spot range.
resetNoenvironment: start from a fresh Environment.
scaleNoUniform number or [x, y, z].
sceneNores:// scene to operate on; opened in the editor if needed. Defaults to the currently edited scene.
sdfgiNotrue | energy | {...}.
shapeNoPrimitive: box|sphere|capsule|cylinder|cone|plane|prism|torus|quad|text.
actionYesWhat to do. See the tool description for each action's parameters.
energyNoLight energy.
groundNoScatter: node path or [paths] to land on (default: lowest surface under each point).
heightNoHeight (meters).
paramsNoShader parameters {uniform: value} (material type 'shader').
parentNoParent node path (default: scene root).
presetNoEnvironment preset: default|sunny|night|foggy|studio|space.
radiusNoRadius (meters).
shaderNores:// .gdshader for a shader material / sky.
sourceNoScatter source: res:// scene/model/mesh or {shape, radius?, size?, material?}.
targetNo[x, y, z] point or node path (look_at).
ambientNoAmbient light: hex color, energy number or {color, energy, source, sky_contribution}.
currentNoMake this the current camera (default true).
look_atNo[x, y, z] point or node path to face.
polygonNoCSGPolygon3D points [[x,y], ...].
replaceNomesh_library: build a fresh library instead of merging.
save_asNomaterial (node mode): also save the material to this .tres.
shadowsNoEnable shadows.
surfaceNoMesh surface index for a surface material override.
tonemapNo'filmic' | 'aces' | 'agx' | 'linear' | {mode, exposure, white}.
childrenNoNested CSG specs.
emissionNoMaterial emission color (hex) or true/false.
materialNores:// material, hex color / color name, or {albedo_color, roughness, metallic, emission, albedo_texture, ...}.
metallicNoMaterial metallic 0-1.
positionNo[x, y, z] position.
specularNoLight specular amount.
y_offsetNoScatter: offset along the ground normal (meters).
assign_toNomaterial (file mode): node path to assign the material to.
cell_sizeNoGridMap cell size [x, y, z] or one number (default [2,2,2]).
collisionNomesh: none | static | convex | trimesh.
font_sizeNoTextMesh font size.
item_nameNoScatter (instances mode): base name of the placed nodes.
operationNoCSG operation: union | intersection | subtraction.
overwriteNoReplace an existing file.
positionsNoSeveral [x,y,z] positions (instance).
roughnessNoMaterial roughness 0-1.
save_pathNoAlso save the Environment to this .tres.
adjustmentNo{brightness, contrast, saturation} (enables adjustments).
backgroundNo'sky' | '#hex' (solid color) | 'clear'.
from_sceneNoScene whose MeshInstance3D nodes become MeshLibrary items.
mesh_propsNoRaw PrimitiveMesh properties (e.g. {subdivide_width: 32}).
pixel_sizeNoTextMesh pixel size (meters per font pixel).
projectionNoCamera projection: perspective | orthographic.
top_radiusNoCylinder/cone top radius (0 = cone).
update_sunNoenvironment: let a preset update an existing sun (default true).
attenuationNoOmni/spot attenuation.
cast_shadowNoGeometryInstance3D cast_shadow: on|off|double_sided|shadows_only.
model_frontNolook_at: point +Z (imported model front) at the target instead of -Z.
scale_rangeNo[min, max] random uniform scale.
albedo_colorNoMaterial albedo color: hex, name or [r, g, b] (shortcut for props.albedo_color).
inner_radiusNoTorus inner radius.
mesh_libraryNores:// MeshLibrary (.tres) for the GridMap.
min_distanceNoScatter: minimum distance between items.
outer_radiusNoTorus outer radius.
bottom_radiusNoCylinder/cone bottom radius.
use_collisionNoCSG root collision.
albedo_textureNoMaterial albedo texture res:// path.
volumetric_fogNotrue | density | {density, albedo, emission, ...}.
align_to_groundNoDrop scattered items onto the ground below (raycast).
align_to_normalNoTilt scattered items to the ground normal.
indirect_energyNoLight indirect (GI) energy.
rotation_degreesNo[x, y, z] rotation in degrees.
random_rotation_yNoScatter: random yaw (default true).

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare mutation and non-destructive status, and the description adds substantial behavioral context beyond them: undoable scene changes, validation errors instead of NaN/zero, material file edit side effects, mesh library merge behavior, and scatter ground raycasting. No annotation contradiction is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but front-loads the overall purpose before an action-by-action breakdown. Most sentences earn their place for a tool this complex, though there is some density and repetition with schema descriptions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the 101 parameters, 12 actions, nested objects, and absence of an output schema, the description is remarkably complete. It covers action semantics, defaults, validation, file side effects, and scene mutation behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is already 100%, but the description adds crucial action-discriminated semantics for 101 flat parameters: per-action defaults, allowed shapes, nested CSG trees, collision mappings, material modes, import keys, and scatter modes. This is far beyond what the schema alone conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Starts with a specific verb and resource: 'Build 3D levels in few calls', then enumerates all 12 actions (mesh, csg, material, light, etc.). This makes the tool's scope immediately distinguishable from generic sibling tools like scene or node.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context for when to use it: building 3D levels and performing specific 3D operations. However, it never names sibling alternatives or states when not to use it versus tools like scene, node, or tiles.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.