Assetspreview
Models, materials, graphics settings and sounds, and how Motoko code refers to them.
Assets live in the directories listed in asset_roots. Each asset file has a .meta.yaml file beside it that gives it a permanent id and the name your code uses.
Asset metadata#
format_version: 1
uuid: 11111111-0000-4000-8000-000000000003
address: material/blue
importer: copy
importer_version: 1
kind: material
binding: blue
| Field | Meaning |
|---|---|
uuid | The asset's permanent id. Saves and packages refer to it. Never change it |
kind | model, material, audio, ui, or bytes for anything else |
binding | The Motoko name. Letters, digits and underscores |
address | Optional unique path. The player finds ui/main and settings/graphics by address |
importer, importer_version | copy, 1 |
moxzi-game init-assets . creates missing metadata files with kind: bytes and a binding taken from the file name. Edit them, then commit them with the assets. To move or rename an asset, move its .meta.yaml file with it; the id and binding stay the same.
Using assets in Motoko#
The build generates a module, mo:game-assets/Assets, from the metadata:
// Generated by Moxzi. Edit source metadata, not this file.
import Asset "mo:moxzi/Asset";
module {
public let asset_blue : Asset.Material = #material("11111111-0000-4000-8000-000000000003");
public let asset_controls : Asset.Ui = #ui("11111111-0000-4000-8000-000000000005");
public let asset_cube : Asset.Model = #model("11111111-0000-4000-8000-000000000001");
public let asset_graphics : Asset.Bytes = #bytes("11111111-0000-4000-8000-000000000006");
public let asset_grey : Asset.Material = #material("11111111-0000-4000-8000-000000000004");
public let asset_ground : Asset.Model = #model("11111111-0000-4000-8000-000000000002");
public let asset_sound_click : Asset.Audio = #audio("11111111-0000-4000-8000-000000000007");
public let material_blue : Nat32 = 1;
public let material_grey : Nat32 = 2;
public let mesh_cube : Nat32 = 1;
public let mesh_ground : Nat32 = 2;
};
| Constant | Type | Use |
|---|---|---|
mesh_BINDING | Nat32 | mesh in a Render.Entity |
material_BINDING | Nat32 | material in a Render.Entity |
asset_BINDING | Asset.Model, Asset.Audio, … | Typed references, for example in Audio.play |
Using a name that doesn't exist is a compile error. Two assets can't share a binding.
Models#
A model is a primitive shape in YAML, or a .glb file.
version: 1
primitive:
shape: cuboid
size: [1, 1, 1]
shape | Parameters |
|---|---|
cuboid | size: [x, y, z] in metres |
sphere | radius in metres |
.glb files are supported with limits: one mesh, transforms already applied, no textures, skins or animations.
Materials#
version: 1
base_color_linear: [0.05, 0.3, 0.9, 1]
metallic: 0.1
roughness: 0.5
emissive_linear: [0.0, 0.0, 0.0]
| Field | Meaning |
|---|---|
base_color_linear | Colour as linear RGBA, each 0 to 1 |
metallic | 0 (not metal) to 1 (metal) |
roughness | 0 (mirror) to 1 (matte) |
emissive_linear | Light the surface gives off, linear RGB. Values above 0 glow, and bloom if enabled |
Colours are linear, not sRGB. To convert an sRGB value c between 0 and 1, use ((c + 0.055) / 1.055) ^ 2.4 (or c / 12.92 for values below 0.04).
Graphics settings#
version: 1
bloom: false
shadows: true
Give this file kind: bytes and address: settings/graphics. To let players turn effects down, add a button with local: reduced_effects (see Controls).
The scene#
The scene is built in Motoko from mo:moxzi/Render:
| Type | Fields |
|---|---|
Entity | id (your own Nat64), mesh, material, transform, visible |
Transform | translation (metres), rotation (quaternion x, y, z, w), scale. Start from Render.identity |
Camera | transform, fov (radians), near, far, exposure |
Light | id, kind (#directional, #point { range }, #spot { range; inner; outer }), transform, color, intensity, shadows |
moxzi_snapshot returns the whole scene with Render.snapshot. Each tick, return only the changes, built from Render.empty:
Delta field | Use |
|---|---|
created, destroyed | Entities that appeared or were removed |
transforms | New positions, as (id, Transform) |
materials | New materials, as (id, material) |
visibility | Show or hide, as (id, Bool) |
lights, removed_lights | Lights added or changed, and removed |
camera | A new camera position, or null to keep it |
Between ticks, the player interpolates entity positions, so movement looks smooth at any frame rate.
Sounds#
Sounds are WAV files with kind: audio:
| Limit | Value |
|---|---|
| Format | 16-bit PCM, mono or stereo, 8 to 96 kHz |
| Length | 10 seconds, 4 MiB |
| Cues per tick | 32 |
Return sounds from moxzi_advance in the audio field, created with Audio.play. See Writing a game. Sounds are presentation only: they aren't saved, and they're skipped if they arrive more than half a second late.
To let players change the volume, return audio_gain = ?g (0 to 1) in your replies, as Pong does.
Limitations#
| Not supported yet | |
|---|---|
| Textures and images on models | Use materials and emissive colour |
| Animated or skinned models | Move entities from Motoko instead |
| Music, compressed audio, 3D positional sound |