# core
The shared contract of **Mario Kart OrigoZ**. Every slice reads its rules
here, so no slice hard-codes a number that belongs to the game.
`require("game.core")` from anywhere in this world.
## What it holds
| Field | What it is |
|---|---|
| `TITLE`, `PROMPT`, `ART` | The game's name, the *pulsa J para jugar* prompt, and the art-direction sentence — word for word from the reference pass, reused by every prompt. |
| `CIRCUITS` | The three circuits: id, name, laps, layout (`ring` / `square` / `ribbon`), racing surface, what lies beyond the edges, and half-width. |
| `KART` | How a kart feels: max speed, acceleration, braking, turn rates, hop and gravity, drift multipliers, trick spin. |
| `SURFACE` | What each surface does to you: `road` 100%, `water` 75%, `grass` 50%, `space` falls. |
| `SPARK` | The drift charge table: blue at 1.0s (0.5s boost), orange at 2.5s (1.25s), rainbow at 4.0s (2.5s). |
| `BOOST` | Trick 0.75s, mushroom 2.0s, feather 2.0s. |
| `ITEMS` | Crate respawn (8s) and the mushroom / feather odds. |
| `RESCUE` | How Lakitu puts you back: drop height, lift speed, lift duration. |
| `PHASE`, `flow`, `race` | The flow state machine and the live race clock. |
| `records` | The best time on each circuit, kept in `runtime_data.world` — shared and durable. |
## API
- `M.circuits()`, `M.circuit(id)`, `M.circuitIndex(id)`
- `M.register(name, api)` / `M.system(name)` — how slices reach each other
- `M.on(name, fn)` / `M.emit(name, payload)` — the slices' event bus
(`phase`, `circuit`, `lap`, `crate`, `boost`, `rescue`, `finish`)
- `M.setPhase(p)`, `M.selectCircuit(id)`, `M.openControls()`, `M.beginRace()`,
`M.startRace()`, `M.tick(dt)`, `M.reachPoint(total)`, `M.finishRace()`
- `M.records.get(id)` / `M.records.set(id, ms)` / `M.records.all()`
- `M.formatTime(ms)` → `"00:45.678"`, `M.countdownLabel(seconds)`
- `M.clamp`, `M.lerp`, `M.approach`
## Who reads what
- **kart** — `KART`, `SURFACE`, `SPARK`, `BOOST`, `RESCUE`, `race`.
- **tracks** — `CIRCUITS`, `SURFACE`, `reachPoint`, `PHASE`.
- **items** — `ITEMS`, `BOOST`, `FEATHER_LIFT`, `emit("crate")`.
- **screens** — `flow`, `race`, `records`, `formatTime`, `PHASE`.
- **audio** — `on("phase")`, `on("boost")`, `on("crate")`, `on("finish")`.
# kart — Mu Mu's kart
The driving model, the whole K button, the surface penalties, the Lakitu
rescue and the chase camera. This is where the game's feel lives.
## What is here
| File | What it is |
|---|---|
| `game/kart.module` (`game.kart`) | The slice's API — finds the local player's kart and asks it. |
| `Kart.component` | The kart itself, on the scene's `kart` body. One instance per player. |
| `KartCamera.component` | The chase camera, in the scene's CameraRig's `behavior` slot. |
| `drive.inputMap` | A/D steer, J accelerate, K hop and drift, L item, O brake — keyboard, gamepad and touch on every control. |
## The controls
| Key | What it does |
|---|---|
| **J** | Accelerate. |
| **O** | Brake; held past a stop, reverses. |
| **A / D** | Steer left / right. |
| **K** | At a standstill, a small straight hop. While steering, a hop to the OPPOSITE side that lands into a drift the way you turned. |
| **K** held in a drift | Wheel sparks charge: blue at 1.0s, orange at 2.5s, rainbow at 4.0s. Releasing pays out 0.5s / 1.25s / 2.5s of boost for the colour that was showing. |
| **K** off a ramp lip | A trick spin in the air; landing it pays out 0.75s of boost. |
| **L** | Use the item in the slot. |
## The rules it enforces
- **Surfaces**: sand/dirt/rainbow 100%, water 75%, grass 50%, space is not
drivable at all. Any boost except the drift one cancels the penalty while
it runs.
- **Lakitu**: falling into space lifts the kart and sets it back down at the
nearest point of the racing line, then hands control back.
- **Laps**: `tracks.advance` is called only while the kart is on the racing
surface, so falling past a line in space never counts as crossing it.
## API (for the other slices)
```lua
local K = Core.system("kart")
K.player() -- the local kart entity, or nil
K.public() -- its component: item, speed, lap, charge
K.boost(seconds, "mushroom") -- fire a boost
K.jump(Core.FEATHER_LIFT) -- lift it (a feather)
K.placeOnTrack() -- put it on the line
K.teleport({ x, y, z }, yaw) -- put it down anywhere
K.setLocked(true) -- hold it (countdown, menus)
K.held() -- the item string it is carrying
```
## Who drives
Only the peer's own kart reads input. It decides that from the layer's
local-player handle, from the entry point's `player` event, or — a world with
one kart having only one candidate — from there being a single kart.
## Verified
Driving on circuit 1: J accelerates, A/D steer, O stops it; the water caps the
speed at exactly 24 m/s (75% of 32). On circuit 2: steering off the dirt onto
the grass caps it at exactly 16 m/s (50%). K with D held hops into a drift;
holding it charges to rainbow and releasing pays out the boost for the stage
reached (1.25s at orange, timed from when the drift actually started, not from
the hop). K off a ramp on circuit 3 spins a trick and landing pays out 0.75s.
Driving off the rainbow ribbon drops the kart and Lakitu sets it back on the
line. Crossing each gate in turn walks the lap counter up. The chase camera
follows from low and close behind, and none of it depends on the engine's
frame rate (the step is clamped).