Cameras & expressions
Choose what each player sees, and make cameras, visuals, disc paint and HUD styles follow the match every frame.
Each player's screen shows part of the world. Your game decides which part with a camera. Without one, every player sees the default view: 340 × 160 world units around the center.
Cameras, visuals, disc paint and HUD styles can also take expressions:
small formulas that every player's client works out on each frame it draws,
such as "halfway between me and the ball" or "fade in with speed". You
declare them once; they follow the match smoothly without any code in your
tick handler.
Frame a field
world.camera takes a center and a width and/or height in world units. With
both, the area is fitted to the screen; with one, the other follows the
screen's shape. Cameras belong to the match, like the world.
Expressions
Expressions come from the standard module
disko:expr. Its functions have the same names and
meanings as disko:math's, but return expressions
instead of numbers. Import it as a namespace so the names never clash with
disko:math:
Expressions read:
expr.disc(disc): a disc as the player sees it:.position,.velocity,.x,.y,.radius,.speed;expr.me: the player's own disc (spectators have none);expr.time: match time in seconds (it stops while paused);expr.screen: the player's screen,.width,.height,.aspect.
When something an expression reads doesn't exist on a frame (a destroyed
disc, me for a spectator), the expression has no value. expr.or gives a
fallback; otherwise a camera is skipped (the player sees the previous camera,
or the default view), a visual is hidden for that frame, and a paint or HUD
number uses its default.
Each player uses the newest camera whose audience includes them and that
has a value, so one camera can follow every player's own disc.
Visuals and disc paint
Every number in a visual and in disc paint can be an expression, and both
take an opacity from 0 to 1:
HUD styles
Numeric HUD styles (sizes, spacing, radius, font size, opacity) take expressions too. The HUD isn't rebuilt each frame; only the value changes: