Gessa Docs
Recipes

Recipe

Capability ceiling what the agent cannot author and the in-envelope fallback

Read this before promising anything that sounds like arbitrary-code rendering (voxels, custom shaders, hand-built meshes, rigged animation). The typed surface takes the agent FARTHER than raw code for game systems (netcode, physics, persistence, mobs, UI, audio) but LESS far for a few raw content primitives. Those few are listed here with the substitute that IS expressible. Each is a redirect, not
engine v1.0.234Copy for LLM

Use this for

knowing the honest limits before you start; avoiding tool calls that will be rejected; choosing the in-envelope path when a request exceeds the typed surface; designing to what the engine actually expresses

Not for

the positive recipes themselves (see the paired playbooks for how to do each fallback)

Pairs with: Model authoring parametric primitives and CSG for custom meshes, Materials and looks PBR surfaces color metalness and textures, Terrain and heightmaps procedural generation biomes and foliage

When to use

Read this before promising anything that sounds like arbitrary-code rendering (voxels, custom shaders, hand-built meshes, rigged animation). The typed surface takes the agent FARTHER than raw code for game systems (netcode, physics, persistence, mobs, UI, audio) but LESS far for a few raw content primitives. Those few are listed here with the substitute that IS expressible. Each is a redirect, not a dead end: design to the fallback and the request ships.

The five ceilings and what to use instead

  1. Per-voxel / blocky mineable terrain at scale is not authorable. Use instead: procedural HEIGHTFIELD terrain (terrain.patch.apply generate, biome, erosion, scatter, then terrain.artifacts.build; see terrain-and-heightmaps). For a truly blocky world the only path is instantiating the voxel_frontier template WHOLE at project creation (project_create_game creationIntent { mode:"template", templateId:"voxel_frontier" }); it cannot be edited as typed capabilities afterward and per-block entities breach the 1000-entity/collider runtime cap (runtimePolicies maxEntitiesPerTick). Do not attempt per-block set/place ops or spawn thousands of block entities; both fail-closed or stall physics.

  2. Raw vertex/index buffers and marching-cubes meshes are not authorable. Use instead: parametric primitives plus CSG booleans through model_save (box/sphere/cylinder/capsule/cone/torus/plane, union/subtract/intersect; see model-authoring-parametric-csg), OR import a gltf/glb/obj asset (primitiveType: "imported"), OR take a fitting mesh from the catalog. There is no vertex-array field anywhere; RenderableComponent.shape is a fixed enum (box, sphere, disc, capsule, billboard, mesh, plane).

  3. Custom shader code (WGSL/GLSL) is rejected by design. Use instead: the twelve ai_safe PBR ops (base color, metallic, roughness, emissive, alpha, double-sided, texture slots; see materials-and-looks). Any key like shaderSource, wgsl, glsl, rawShader, fragmentShader, vertexShader triggers raw_shader_source_forbidden. Never emit shader strings.

  4. Procedural material networks beyond the small node catalog are not expressible. The graph ops themselves (addCatalogNode, connectSockets, disconnectEdge, setNodeParameter and friends) ARE ai_safe, the same alphabet the visual editor gets (authoring symmetry); only replaceGraph stays import-only, and trustedOnly nodes (trusted.shader.plugin) are rejected for every normal source. The ceiling is the CATALOG: an OpenPBR surface, output, color and float constants, texture sample, water depth, scalar math, color mix, and procedural noise. A look those nodes cannot express (custom lighting response, stylized ramps) is out of reach; for most looks the twelve PBR ops stay the shorter path (see materials-and-looks).

  5. Skeletal animation authoring beyond clip playback is not expressible. Use instead: AnimationStateComponent to PLAY a named clip off a rigged imported model (clipKey, playMode loop/once/ping-pong, speed, startTime), plus transform animation authored as a TimerComponent firing a handler that patches a TransformComponent (bob, spin, scale). You cannot author or blend new skeletal clips; a walk cycle needs an imported rigged asset that already carries the clip.

  • Runtime block place/mine works only at SMALL N: ctx.world.spawn/despawn of entities under the 1000-entity/collider cap. A dozen placeable blocks is fine; a mineable voxel field is not.
  • Instanced rendering is not a direct AI authoring primitive EXCEPT terrain scatter foliage, which bakes a foliage_instance_buffer the renderer instances. Scatter renders real geometry ONLY for the grass/tall_grass (blade tufts) and rock/boulder (deformed stone) keys; every other foliageKey, tree and flower keys included, renders as a small placeholder cone today (the terrainDetailGeometry fallback), and there is no mesh-backed scatter. Use scatter for grass and rock ground cover; a tree line is a modest number of placed model entities under the entity/collider cap, and do not spawn thousands of entities to fake instancing.
  • Water is planar only (WaterComponent); there is no volumetric fluid or lava component. Approximate lava with a recolored water surface plus an emissive PBR material and a damage script.

How to respond when a request exceeds the ceiling

Name the limit in one sentence, propose the in-envelope design, and build that. Do not loop retrying a rejected op, and do not invent a tool name (there is no set_voxel, no create_shader, no author_animation). A first-person survival world with procedural terrain, mobs, inventory, health, day-night, server-authoritative multiplayer, persistence, sound, and particles is fully expressible; lead with that.

Verify

  • If unsure whether a capability exists, engine_list_component_types and engine_get_component_schema show the real component surface, and the action catalog shows the real tools. Absence there is the ceiling; trust it.
Was this helpful?Report an issueContact support

On this page