Skip to main content

Audio and animation contracts

Audio and animation have no playback backends. Their support queries return .not_implemented; playback, stopping, seeking, gain changes, and blending return error.NotImplemented. No output device, decoder, animation importer, or skinning backend is created.

Asset references​

pub const CharacterAssets = struct {
footstep: eggy.AssetRef(.audio) = .init("resources/sounds/step.ogg"),
model: eggy.AssetRef(.model) = .init("resources/models/character.glb"),
};

List the component in your plugin's components to edit it in the Inspector. The slots accept files of the matching kind and scenes store the paths. Setting a slot does not load or play the resource.

Audio requests​

app.audio.play(sound, options) describes a playback request and would return a Voice only after a backend actually starts it. Options describe linear gain, .once/.loop, an optional world position in metres, and a bus. Listener placement is explicit rather than inferred from a global camera.

The remaining contract operations are pause, unpause, stop, setGain, setBusGain, and setListener. They also fail explicitly today; stopping an unsupported voice is not a successful no-op. Do not construct fake handles to make a call look successful.

Check eggy.audio.support when deciding whether to offer sound controls. Disable unsupported controls or propagate the failure with context. Do not repeatedly attempt playback and log the same unsupported error every frame.

Animation requests​

An eggy.animation.Clip names a model and a clip within it:

const run = eggy.animation.Clip{
.model = .init("resources/models/character.glb"),
.name = "run",
};

The name is borrowed for a request. app.animation.play(entity, run, options) describes the target, speed, repeat mode, and start time in seconds. blendTo supplies a transition duration in seconds; seek supplies a time, not an undocumented normalized fraction. pause and stop complete the small playback contract.

These requests do not change an entity's pose today. Packaged .eggmodel data currently contains static geometry, parts, and textures, not skeletons or animation clips. No controller graphs, retargeting, root motion, or physics integration is implied. Check eggy.animation.support rather than assuming a model file enables animation.

Component motion​

Game code can animate ordinary component values using frame time:

pub fn bob(
app: *eggy.App,
entity: eggy.ecs.EntityId,
base_height_m: f32,
amplitude_m: f32,
) !void {
if (!app.world.isAlive(entity)) return error.InvalidEntity;
const transform = app.world.get(entity, eggy.Transform) orelse return error.NoTransform;
const phase: f32 = @floatCast(app.time.elapsed_s);
transform.position[1] = base_height_m + @sin(phase) * amplitude_m;
app.world.markChanged(entity, eggy.Transform);
}

Call it from update. It follows gameplay time and editor Play/pause behavior. See Input and gameplay time, Render entities and cameras, and the capability support table.