Skip to main content

Reference, examples and troubleshooting

Find the right control​

TaskWhere to work
Place an existing meshTile Picker, compact mesh sidebar, Rect tool
Open full mesh constructionEdit mesh
Return to placementBack to map
Create a part from a templateMeshes → New mesh / Browse recipes…
Make an independent variationBrowser → Project, then create a copy
Change the shared assetSelect its Group and edit published controls
Change what a control drivesPublish controls… → Recipe parameter / Recipe input
Calculate a dependent measurementPublisher → Formula
Edit a shared project materialTile Picker or linked material opening control in the mesh editor
Edit inline surface valuesMesh recipe → PBR Material
Define ground-contact geometryMesh recipe → Contour + Footprint
Define attachment locationsMesh recipe → Connector
Update placement collision from the recipeFollow recipe shape
Join nearby mesh partsSnap connectors
Remove a placement's parent connectionSelect it → Detach connection
Sculpt a hillTerrain tool
Color a terrain surfaceTerrain-aware Paint workflow

Common problems​

I changed a construction value and nothing happened​

A published parameter may override that literal value during evaluation. Select the outer Group and change the published control. Inspect the binding if the wrong input is driven. Formula controls are calculated from their dependencies and cannot be changed directly while using a recipe.

All my walls changed together​

They use the same recipe. Use a project recipe copy for an independent variation. A shared material edit similarly affects all recipes that reference that material.

My wall blocks a rectangle larger than its base​

Enable Follow recipe shape and provide a ground-contact footprint. Without one, the fallback is the mesh's bounds. For a tree, use the trunk contour rather than the canopy bounds. Keep Walkable top off for ordinary blocking props.

My doorway is blocked​

Check that its footprint has separate jamb regions and that the lintel has no ground footprint. A single outer rectangle still fills the doorway even if its rendered image is transparent there. Test the clearance with the player's collision radius, not only a point at the opening's center.

A hole does not show through the mesh​

Footprints affect collision and support. They do not cut visible mesh triangles. Build an actual opening in the geometry and add the corresponding footprint hole.

Bricks stretch or restart at every part​

Check both the source material and the mesh's Material Texture projection. Ground materials can use continuous world X/Z coordinates; custom mesh UVs retain their authored layout. Continuous texturing cannot smooth a stepped mesh or merge separate modeled slopes.

The preview shows grayscale noise instead of my material​

It may be displaying the selected operation or a single channel. Choose the material output and Color channel to inspect the final color.

I cannot find the brick material in a mesh​

Select its Material Texture operation. A project material reference opens a shared source that also appears in the Tile Picker. A PBR Material operation is an inline surface with palette color, roughness and metallic controls; it does not have a separate project material tile.

Parts do not snap​

Check Snap connectors and Follow recipe shape. Both parts need static connector caches, matching family keys and opposing directions. Move the tentative placement closer: the search radius is 0.8 world units in three dimensions. Raise Top height when attaching a roof to a wall top. An already occupied connector is unavailable.

A connected part stopped following​

Check that its parent still exists, the recipe still exposes the same connector IDs and families, and Follow recipe shape is enabled. Missing connectors and cycles freeze affected links. Detach and re-place the part to establish a new connection. Editing a closed room's dimensions may leave its closing seam open because the links form a parent forest, not a closed-loop solver.

A recipe error leaves the previous picture in place​

The last valid render and placement cache are retained so an invalid edit does not destroy the scene. Read the recipe error, fix it and allow the next bake to finish. Check formula ranges, contour validity, duplicate bindings and missing upstream references.

Lighting an isometric scene​

MZ recipes define surface colour and shape. Eldiron's sun simulation and local lights provide illumination in the map preview and game. The iso cache retains unlit colours, normals, heights and material properties. A deferred SceneVM GPU pass shares the existing device and scene lights, and evaluates lighting and mesh shadow maps in the editor and game; changing a light or time of day updates the scene without regenerating the assets.

The sun's morning, midday, evening and night colours come from the project's [simulation] settings, together with its changing direction. Editor preview time and game time drive the same lighting. Local Point lights supply their own colour, intensity, range and flicker.

The relevant Game settings are:

[render]
ambient_strength = 0.24
point_shadow_softness = 0.075

[simulation]
enabled = true
night_ambient_strength = 0.12

point_shadow_softness defaults to 0.075. It is an effective source radius in world units: larger values soften point-light shadow edges more, especially when the blocking object is far from the receiving surface. Set it to zero for sharp point lights. Filtering follows surface geometry and does not blur material pixels or the whole scene. This setting currently applies to GPU 2D iso lighting.

night_ambient_strength is optional and omitted by default. The example uses 0.12 for darker nights while retaining the daytime ambient strength. It fades at dusk/dawn and leaves local lights and sun colours alone. Ambient fill colour is independent of simulated sky colour.

See Game Configuration: 2D Isometric Lighting for the full controls, defaults, a complete example and transition times.

An emissive material makes a lamp's glass visible; a local Point light illuminates its surroundings. Opaque frame parts still cast shadows. Keep a path open beneath a hanging lantern: a solid tray very close below the source can project a large rectangular shadow onto the ground. The Wayfarer's Rest recipe has an open lower frame, reduced light intensity and soft point shadows for a gradual pool of light.

GPU cast shadows use the actual MZ triangles, their repeating UVs and alpha masks. The shared terrain triangles cast shadows too, including newly sculpted hills. Sun shadows use a stabilized orthographic depth map; local Point lights use six depth views so furniture, walls and hills can block light in every direction. Openings and disconnected parts stay open, without filling their bounding boxes. Hidden cutaway roofs continue to block outside light.

The maps follow the shadow enable and strength settings and update with the sun, local lights, recipe changes, placement and terrain sculpting. Source triangles and sampled terrain are cached; changing the time does not rebake MZ materials or sprites. The CPU fallback and older unsynchronized mesh caches retain height-column shadows. Up to 32 local Point lights cast GPU shadows; additional local lights still illuminate the scene.

Ordinary bitmap tiles remain sprites. Preserve original artwork retains their supplied shading and colours, including beside dynamically lit MZ meshes. World lighting tint lets a sprite receive live light and mesh/terrain shadows with its flat surface normal. Neither mode invents a 3D caster from a PNG. Bitmap-only organic stamps likewise do not become opaque mesh volumes.

MZ Particle Effect operations on placed iso meshes are live attachments. The existing particle simulator advances them in world XYZ, and SceneVM draws instanced billboards with geometry occlusion. Flame size, rate, colours and light output remain editable in the mesh recipe. An open window needs an actual geometry opening; an opaque dark panel still blocks the view and light.

Avoid painting a fixed directional shadow into a tree or ground material: it cannot follow the sun. Natural pigment, grain and leaf colour variation belong in the MZ material. See the editable scene sources in crates/shared/examples/iso_2d/uo_art/ for a lantern, leafy tree and day/night study.

Worked source examples​

All of these are editable sources in the repository. The mesh browser uses the same recipe files.

ExampleSource
Ground starterSTARTER in creator/src/procedural_material.rs
Continuous brick materialcrates/materialz/examples/continuous-bricks.material
Wall and cornercreator/embedded/meshes/recipes/wall-segment.mzgeometry.json, wall-corner.mzgeometry.json
Paired roof with derived dimensionscreator/embedded/meshes/recipes/gable-roof.mzgeometry.json, roof-slope.mzgeometry.json
Fence with count, spacing and derived lengthcreator/embedded/meshes/recipes/fence.mzgeometry.json
Doorway, posts and holed walkwaycreator/embedded/meshes/recipes/doorway.mzgeometry.json, repeated-posts.mzgeometry.json, ring-walkway.mzgeometry.json

These source paths are for repository users; creating a built-in mesh through the browser does not require editing JSON. Downloadable copies are provided below for studying the format. They are source documents, not a new asset-import UI:

Reproduce the playground​

From a native development checkout with the terrain example available under generated/:

cargo test -p eldiron-creator --lib build_iso_published_controls_playground -- --ignored --nocapture

The builder first looks for generated/iso-organic-stamps/OrganicTerrain.eldiron, then the earlier terrain playground. It writes generated/mz-iso2d-recipe-playground/MZRecipePlayground.eldiron and review captures. It leaves the input project intact. The recipe playground adds reusable room parts, a roof, fences, separate posts, a holed walkway and a connector assembly exercise.

This is a developer reproduction harness, not a prerequisite for the tutorials. In a normal project, create the same assets through the browser and assemble them with the editor tools.

Format and evaluation details​

For operation-level source documentation, see crates/materialz/docs/geometry-prototype.md. Geometry documents use stable row and operation IDs. References point to earlier rows. Groups retain embedded construction documents, controls, bindings and formulas. Generated geometry, directional art and placement caches can be rebuilt from those sources and their dependencies.

Static Repeat accepts 1–128 copies within the geometry vertex budget. Footprints allow 128 regions, 256 rings and 4096 points. Connectors allow 256 entries per mesh. Prefer a modest number of purposeful parts and connectors over repeating invisible metadata on every decorative detail.

The older Procedural Materials guide contains additional material composition, image source and preview details. MZ Recipes on Geometry describes applying a recipe to selected 3D geometry; that is a separate workflow from placing iso parts.

Rebuild the procedural art study​

The Wayfarer's Rest scene combines a timber-and-plaster cottage, transparent window openings, live hearth particles, three oak recipes, planted borders and a winding MZ earth trail over shared sculptable terrain. Its materials use Guildhall 256 by Eric Johnson from Lospec. Colour variation describes the surface; the sun, lanterns and hearth supply the illumination.

With the local generated/mz-iso2d-native/MZIso2D.eldiron experiment available:

cargo test -p eldiron-creator --release --lib build_uo_art_study -- --ignored --nocapture

This writes the playable generated/uo-art-study/WayfarersRest.eldiron and same-scene day, dusk, night, interior and hill captures. It also walks a player through the doorway and up/down the hill. Generated projects, captures and performance logs stay under the ignored generated/ directory.

To measure the warmed renderer, including GPU uploads and readback:

cargo run -p eldiron-shared --release --example mz_iso_profile -- \
generated/uo-art-study/WayfarersRest.eldiron --gpu --size 1280x900 --walking

Use --hour 18.5 or --hour 23 for dusk and night, and --no-shadows to isolate the shadow cost. The report gives median and 95th-percentile milliseconds after five warmup frames. These are scene-renderer timings, rather than total editor frame times.