# Tutorial: first motion

Motion Kit (`hi.motion`, `hi.Tween`, `hi.Spring`, …) animates **values you own** — entity fields, subsystem HUD state, editor chrome. Do not hang timelines on `UiContext`.

Deep reference: [Motion Kit](/docs/systems/motion-kit.md). Sample: `disco_light_data.zig` (`disco_light` archetype).

## Tween on an entity field

Use `FadeLight` as the `.data` of a `defineComponent` that requires `hi.ComponentLight`, then include both components in your actor. The methods below are component lifecycle hooks.

```zig
const hi = @import("hikari_game");

const FadeLight = struct {
    intensity: f32 = 2.0,
    fade: hi.Tween = .{},

    pub const metadata = .{
        .properties = .{
            .intensity = hi.UserDataPropertyOptions{ .label = "Intensity", .min = 0 },
            .fade = hi.UserDataPropertyOptions{ .transient = true },
        },
    };

    pub fn start(self: *@This(), actor: hi.ActorContext) void {
        self.fade = hi.Tween.init(0.0, self.intensity, 1.5, .ease_out_cubic);
        hi.render().setLight(actor.id, .{ .intensity = 0.0 });
    }

    pub fn update(self: *@This(), actor: hi.ActorContext, ctx: *const hi.TickContext) void {
        hi.render().setLight(actor.id, .{ .intensity = self.fade.update(ctx.dt) });
    }
};
```

## Wave / helpers

```zig
const bob = hi.motion.wave(ctx.total_time * bob_speed + phase) * amplitude;
hi.world().setPosition(id, .{ x, base_y + bob, z });
```

Respect `reduce_motion` when driving UI opacity/shift: use `hi.motion.resolve` (see Motion Kit + accessibility prefs).

## HUD motion

Store `Tween` / `Spring` on `GameSubsystem` (or a scene HUD entity), sample into widget styles each `onTick` / `update`. Retained editor chrome uses `opacity` / `shift` on `WidgetStyle` plus `overlay_motion.zig` — same value layer, different host.

## Verify

1. Play a `disco_light` in `physics_playground.json` — lights fade in and orbit.
2. Change intensity in the inspector — sample `onChanged` restarts a tween.
3. Enable Reduce motion in editor settings — UI transitions snap; gameplay waves still run unless you gate them yourself.

## Next

- [First user_data](/docs/tutorials/first-user-data.md)
- [First UI](/docs/tutorials/first-ui.md)
