Tawpy
The goura the player is. Sits on the `GouraPlayer` PlayerPrototype's `body`, so every peer that joins the world gets one and each reads only its own controls (`entity:isLocal()`).
Tawpy
The goura the player is. Sits on the GouraPlayer PlayerPrototype's body, so
every peer that joins the world gets one and each reads only its own controls
(entity:isLocal()).
What she does
A crowned pigeon is heavy and a poor flier, and she moves like it.
| State | What it is |
|---|---|
idle | standing |
walk | a deliberate 2.2 m/s, reached and lost over about a fifth of a second |
gather | holding Flurry roots her and builds the charge, 0.3 → 1 over gatherTime; she can still swing round slowly to aim |
flurry | released: a hop off the floor to 0.85 m at up to 12.5 m/s, committed to the heading she launched on, veering and beating sideways as she goes |
boom | the answer to the flock; roots her for 1.15 s wherever she stands |
startled | the eagle's gaze found her; frozen for 0.9 s, charge lost |
caught | taken |
roosted | home |
The stagger off a landing is a ninth reading and not a ninth state: state()
reports walk (she is on the floor and still moving), phase() reports
stumble, and for about half a second she cannot boom, gather or steer while
her speed decays and her heading wobbles. That is the price of the flurry, and
it is why a flurry across open floor is a gamble rather than a free sprint —
8.6 m in about 1.8 s door to door against 2.2 m/s of walking, at the cost of
being unable to answer or turn for the whole of it.
A flurry into the trunks at the lane's edge ends the flight where it hit.
A boom pressed while she is committed (mid-flurry, mid-stagger) is remembered for 0.4 s and fires the moment she can act, so a landing on the beat still answers the flock.
Tuning
The feel numbers are the FEEL table at the top of init.luau, not public
fields. A public field is serialised with the entity, so a baked scene keeps
whatever default it was written against and that copy silently wins over
anything changed in the component — which is exactly what happened to this one.
state, subState, power and speed stay public because the camera and the
art read them off the component.
The surface
FL.provide("player", …) — the spec's shape, plus four additive readings the
art and the camera can use:
| Call | |
|---|---|
position() | { x, y, z }; y lifts during a flurry |
heading() | unit { x, z } on the floor |
state() | one of the eight above |
phase() | the same, plus stumble |
speed() | metres per second this frame |
power() | gathered charge, 0..1 |
airborne() | feet off the floor |
stumbling() | staggering off a landing |
entity() | her entity |
startle() | the gaze found her |
catch() | the eagle took her; emits caught |
reset() | back to the lane start for a new run |
Events emitted
boom, flurry ({ position, power }), step (every 0.62 m of walking),
roost, caught.
Controls
goura.inputMap beside this file — move, flurry, boom, pause, each bound on
keyboard+mouse, gamepad and touch. The pause control toggles playing ⇄ paused
from the same press on every device.
Scoped to this part · feeds back into the world's score.