Material authoring API

These Extended-mode commands run on the main runtime thread. CPU decoding and copying run on a cancellable worker without touching GUI or renderer state. The World Editor uses the same service as other Blitz3D+ tools.

Lifetime

Pass a JSON object to BeginMaterialAuthoring(request) and keep its returned handle. The service copies the request, so callers may immediately FreeJson request. Poll MaterialAuthoringState(job): 1 queued, 2 running, 3 succeeded, 4 failed, 5 cancelled. MaterialAuthoringResult(job) returns a caller-owned JSON handle only after success; free it normally. Every result includes directory, the owned UUID workspace. MaterialAuthoringError(job) returns a diagnostic.

FreeMaterialAuthoring(job) requests cancellation and releases the handle without waiting for the worker. Its generated files disappear when no worker owns them. After a successful publication, call RetainMaterialAuthoringFiles(job) before freeing the handle. Only successful jobs can be retained. Each runtime context allows 128 active/retained jobs; release superseded results. Handles cannot be reused or transferred to another runtime context.

Requests and results

All paths are UTF-8. Prefer absolute input paths. Images and decoded image buffers are bounded to 256 MiB. PNG output retains straight alpha. Data channels are handled numerically rather than tone mapped.

operation Request members Result members
analyzeTextures files: array of paths to files or folders (one directory level; up to 256 candidates) candidates: path, name, detected role, group, channel, inversion/green-flip defaults, dimensions, thumbnail, or error
inspect path; optional channel (rgba, rgb, r, g, b, a), maximum (16..8192) path to temporary preview PNG; original source, width, height; viewWidth, viewHeight
prepareTextures maps: role/path records with optional channel/invert/flipGreen; optional existing resource, baseDirectory, new name, and removeRoles resource: complete validated-by-consumer candidate material with owned generated images and source metadata
analyzeModel path: GLB or GLTF materials: authored index/name/parts; warnings, source
extractModel path, zero-based material index resource, warnings, selected parts
portable resource, baseDirectory, destinationDirectory; optional publication descriptor path resource with copied image paths; directory

Texture preparation accepts baseColor, normal, roughness, metallic, gloss, emissive, occlusion, orm, metallicRoughness and displacement; Ignore/unassigned records are skipped. Duplicate/conflicting roles fail with a diagnostic. Reflection requires an explicit Ignore choice. Separate roughness/gloss and metalness must share dimensions. Roughness becomes G, metalness B; normal conversion flips G only when requested. One-channel replacements preserve the other current packed channel and its scalar. removeRoles supports roughness or metallic, restoring scalar defaults of 0.5 or 0 while preserving the other channel.

Displacement preparation writes the selected source channel, with optional inversion, into an owned 8-bit grayscale PNG. Source provenance and independent UV settings are retained. It does not promise 16-bit height precision. Adding a first displacement map defaults displacementScale to 0.1 world units when no scale has been authored. Existing strengths, including zero, are preserved when replacing maps. Adjust the signed scale to suit the scene. displacementMidpoint defaults to 0.5 and displacementMipLevel to 0. Height moves existing mesh vertices after morphing and skinning; dense mesh geometry is required for detailed silhouettes. Collision and picking retain the original mesh.

The texture review initially recommends separate maps when both separate and packed sources are present; the native service itself rejects unresolved conflicts. Changing sources creates owned outputs and retains original inputs/fingerprints. Replacing existing maps preserves their appearance multipliers and binding transforms; newly added maps get useful initial factors. PNG/JPEG/BMP and other WIC-readable images use the shared CPU decoder, which reads TGA and PSD images with stb_image when Windows has no codec for them. KTX2/Basis uses the same bounded transcoder as glTF; unsupported image contents fail explicitly. Inspection does not imply that every filename extension can be decoded.

Extraction reads authored glTF 2 data, preserving supported material layers and exact UV transforms. It supports external/data-URI/embedded images, deduplicates an image shared across bindings and reports optional omissions. Required unsupported extensions fail. It uses the runtime's Basis decoder and geometry colour/alpha interpretation. Images are exported as RGBA PNG; geometry remains in the source model. A saved extracted material does not depend on that model for rendering.

The candidate JSON must be passed through the normal resource-document validation/preparation/save APIs. A successful CPU job alone does not mean a runtime material is valid for a particular model. Capture the draft revision when dispatching and discard stale completions.

Publishing and recovery

portable writes each publication into a new UUID directory beneath the requested destination directory. It copies texture dependencies and available authoring inputs; custom shader dependencies remain referenced and are rebased by the resource save API. Save/validate the candidate descriptor with existing revision guards, then retain its images. Never publish a descriptor before its required images are ready.

staging.json records the owner process and publication path. A subsequent job can recover abandoned, uncommitted UUID directories with this exact journal format and a dead owner. A committed marker or descriptor referencing the directory protects it, including the interval after descriptor publication but before the UI retains its handle. Unknown folders, live owners, links and unreadable publication files are left alone. Committed-but-later-unused folders are not automatically garbage-collected.

Named model parts and file drops

EntityMaterialSlots(entity) returns a caller-owned JSON array of one-based slot numbers, readable names, sourceMaterial (-1 when unavailable), materialName, and mesh world-space bounds. Collapsed glTF models retain provenance. Use normal import revision checks when saving numbered bindings.

EnableGadgetFileDrop gadget, True enables Explorer file/folder drops. The event is $404; EventSource is the accepting gadget, EventData counts paths, and EventText() returns newline-separated UTF-8 paths. Read the payload before dequeuing another event. A drop never opens or imports files automatically. Limit: 256 paths and 1 MiB per event. Disable with False.

Back to Guides