Skip to main content
Part of the scene-scripting skill. The skill links here when your agent needs the detail.
Every recipe below is the source of one call: summer_run_script(scenePath="res://<the scene>.tscn", source=<the recipe>). Name the scene every time; it is opened first when it is not the edited one, and the person’s tab comes back after the run. The core helpers (add_node, find, add_mesh, make_material, save_scene …) are in the scene-scripting skill itself.

Scatter N instances with randomized transforms

Procedural mesh via SurfaceTool

For grids/heightfields, build PackedVector3Arrays and feed ArrayMesh.add_surface_from_arrays directly. Call st.generate_normals() before commit() when you did not set normals by hand.

CSG primitives (fast blockouts)

Live CSG nodes are the older-engine fallback — they re-evaluate every frame and should be converted before shipping (scene-composition). On a geometry-tier engine prefer ctx.boolean(...), which bakes to a plain ArrayMesh and leaves no CSG nodes behind.

Boolean blockout — carve a doorway (geometry tier)

Box minus box, baked. The inputs are consumed; only the result remains.
Then summer_snapshot_diff must show Wall and DoorHole GONE and WallWithDoorway added — leftover inputs mean the boolean failed and returned null. Screenshot to check the opening is where you meant.

Lathe a goblet / pillar (geometry tier)

lathe revolves a 2D profile (x = radius, y = height) around Y. Design the profile from the axis outward.
A square-ish profile with sides: 8 and spin_degrees: 360 makes a chamfered pillar; spin_degrees: 180 makes an apse/half-dome.

Sweep a rail / pipe (geometry tier)

sweep extrudes a 2D cross-section along a 3D polyline.
Rails, roads, cables, gutters — same recipe, different cross-section. Keep path points a reasonable distance apart; hairpin corners self-intersect.

Terrain with collision (geometry tier)

Collision arrives automatically (a StaticBody3D + HeightMapShape3D child), already owned. Same seed → same terrain, so re-runs are deterministic. Pass image_path to drive heights from a grayscale heightmap instead of noise. Verify with summer_screenshot framing:"camera" — terrain reads wrong from preset framings’ top-down angles.

Text signage (geometry tier)

add_mesh accepts torus and text on geometry-tier engines:
Emissive text only proves itself in a framing:"camera" screenshot — preset framings substitute the environment and mute emission.

Decimate for LOD, convex collision for props (geometry tier)

Dense generated/imported meshes (Meshy-class output) want both before they ship:
decimate returns false (with a report entry) instead of ruining the mesh when the ratio is out of range. convex_collision owns every body it creates — the diff after save_scene is your receipt that nothing was silently dropped. Simple convex props (crates, rocks): leave decompose false, one hull is cheaper.

Mirror symmetry (geometry tier)

The mirror is a real duplicate with flipped winding/normals — edit either side independently afterward.

Animate — camera flythrough and a door-open (geometry tier)

animate collapses the AnimationPlayer/library/track boilerplate into one call per property. Multiple calls with the same anim_name append tracks to the same clip.
Pass plain position / rotation_degrees values — the helper picks the right track type and handles the quaternion conversion for rotation. Verify by playing: summer_play, trigger the clip (or set autoplay), summer_screenshot target:"game", summer_stop.

make_shader — dissolve / glow FX with the compile-error loop (geometry tier)

make_shader is the safe lane for text shaders because compile errors come back verbatim in the result (the make_shader_errors report entry, with the line number) instead of failing silently to a magenta material:
The loop when it fails: read the exact compile error (line number included) from the make_shader_errors report entry → fix that line → re-run. Do not guess-and-mutate; the error text names the line and identifier. For production-grade dissolve/fire/glow (FBM noise include, controllers, cookbook variants) use the vfx-<effect> recipes — make_shader is the fast lane for one-off FX and for iterating on a shader before writing it to a file.

GridMap fills

Cells serialize into packed data — scripting is the ONLY sane way to fill them; never hand-edit tile_map_data-style fields as text.

3-point lighting rig

Then summer_screenshot — lighting is exactly the kind of change you cannot judge without pixels.

Pitfalls


Source: library/skills/scene-scripting/references/recipes-3d.md, rendered from summer-engine@4.3.0 on npm.