# Vehicles in your game (vehicle.* kits) Driveable cars and ships, getting in and out, damage, upgrades, and the pieces of an arena match. Readable offline: `gripforge docs vehicles`, or the MCP tool `gripforge_docs` (topic `vehicles`). ## What it is for | Kit | What it adds | | --- | --- | | `vehicle.driveable` | cars as rigid bodies with a per-vehicle force model: throttle, steering, handbrake, optional boost tank, health and collision damage; arcade, sim or kart handling | | `vehicle.enter_exit` | getting in and out: interaction prompt, detaching the character, the camera following the car; with doors, an animated approach, door, seat and close sequence | | `vehicle.doors` | independent, reversible doors on the prepared parts of the vehicle model, cycled on enter and exit, saved | | `vehicle.damage` | a dedicated damage model: impact damage per zone scaled by speed, smoke then fire stages, burning wrecks that explode with area damage, bullet hits, repair | | `vehicle.upgrades` | modules (engine, wheels, storage, anything the game names) fitted at a garage or a workbench for a cost in items | | `vehicle.boostpads` | pads on the ground that refill the boost of the car driving over them | | `vehicle.rivals` | the cars of an arena match: the player's and bot drivers on a circle, bots that line up and ram | | `vehicle.spaceship` | pilotable ships with simplified six degrees of freedom, guns, hull and shield, enemy ships | ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "vehicle.driveable" } gripforge_gamekit_configure { project_id: "gkp_…", id: "vehicle.driveable", config: { "handling": "arcade", "maxSpeed": 42, "boost": { "enabled": true, "tank": 100 } } } gripforge_gamekit_install { project_id: "gkp_…", id: "vehicle.enter_exit" } gripforge_gamekit_install { project_id: "gkp_…", id: "vehicle.damage" } ``` `vehicle.driveable` requires `input.actions`, `spawn.entities`, `world.ground` and the host rigid-body physics. `vehicle.enter_exit` requires a character kit (`character.control`), `vehicle.drive` and `interaction.use`. `vehicle.damage`, `vehicle.doors`, `vehicle.upgrades` and `vehicle.boostpads` require `vehicle.drive`. Vehicles spawn from the `spawns` collection, from a scene instance or from a `spawn.request` event of kind `vehicle`. A vehicle needs a model in the slot `vehicle_default` (and optionally `vehicle_variants`); a box with four wheels is drawn otherwise. Controls: `vehicle.throttle` and `vehicle.steer` (axes), `vehicle.handbrake`, `vehicle.boost`; the controls guide explains how a device maps to them. ## Settings and defaults ### vehicle.driveable | Key | Default | Meaning | | --- | --- | --- | | `handling` | `arcade` | `arcade`, `sim` or `kart` (a power-slide above 8 m/s with the handbrake and steering) | | `maxSpeed` / `acceleration` / `steer` | 42 / 14 / 2.2 | m/s, force scale, steering rate at low speed (rad/s) | | `boost.enabled` / `boost.tank` | `true` / 100 | boost available and its units (drain while boosting) | | `damage.enabled` / `damage.health` | `true` / 100 | health and destruction | | `maxVehicles` | 8 | live vehicle cap | | `mass` | 1200 | rigid body mass; the collider box (`size`) follows the model | ### vehicle.enter_exit `animatedTransitions` `true` (with doors: approach, open, sit, close before driving), `entryDuration` 1.65 s, `exitDuration` 1.5 s, `enterRadius` 3 m, `exitOffset` (local exit position), `ownedTag` `player_owned` (a vehicle without this tag is reported `stolen: true`, which a wanted-level kit counts). Entry is refused above 1.25 m/s; driving input is locked during a transition and a save during it keeps the phase. The animated entry needs a humanoid rig and the model's `Entry_*` / `Seat_*` sockets; without doors or with `animatedTransitions: false` the seat is taken at once. ### vehicle.doors, vehicle.damage `vehicle.doors`: `duration` (seconds per full travel), `hold`, `autoOnEnterExit`, `driverDoor`; hinges are the `gf_door` parts of the model (without them the state still runs and nothing moves). `vehicle.damage`: `health` 100, `collisionScale` 1 (damage per m/s of impact), `explode` `true`, `explosionRadius` 6, and on the web `deformation` `true` (bounded cosmetic dents), `maxDent` 0.18 m, `effects` `true` (smoke, fire, glow). Stages: smoking at 50 % health or less, burning at 25 % or less (the car loses 5 % of its maximum health per second), wrecked at 0; every other car within the explosion radius takes damage that falls with distance. ### vehicle.upgrades, boostpads, rivals `vehicle.upgrades`: `stations` (kinds of crafting station where modules are fitted, empty: anywhere), `reach` 8 m, `cargoLabel`; modules are documents of `vehicle_modules`: `{ id, name, slot, stats: { topSpeed, acceleration, grip, ... }, cost: [{ item, count }], requires?, storage?, needs?, unlocked? }`. A module must be unlocked, its required modules fitted, a station in reach and its cost in the bag; refusals are `unknown`, `vehicle`, `locked`, `requires`, `station`, `cost`, `fitted`. `vehicle.boostpads`: `count` 6 on a circle (`radius`, `center`, `big`), `bigAmount` 100, `smallAmount` 25, `bigCooldown` 8 s, `smallCooldown` 4 s, `reach` 2.4 m; or documents of `boost_pads` (`{ id, at: [x, z], big }`). `vehicle.rivals`: `cars` 3, `player` `true`, `spawnRadius`, `ringRadius`, `aggression` 0.6, `think` 0.25 s, `playerWeight` 0.8, tags `contestant`. ### vehicle.spaceship A ship is a document of `spaceships`: `{ id, name, thrust, maxSpeed, boostSpeed, pitchRate, yawRate, rollRate, hull, shield, shieldRegen, shieldDelay, guns: [{ offset, damage, speed, rate }], size }`. Settings: `playerShip` (the id of a ship the player starts in), `cameraDistance` 14, `cameraHeight` 5, `minAltitude` 0.5, `maxAltitude` 0 (no ceiling), `autoLevel` 0.8, `collisionSpeed` 6, `collisionDamage` 4, `boardReach` 4, `enemyRange` 90, `enemyStandOff` 14, `enemyFireRange` 45. Guns fire through `combat.projectiles`, else `combat.ranged`; hull and shield are those of `combat.core`. ## Services, events, variables - `vehicle.drive`: `vehicles()`, `speed(entity)`, `setDriver(entity, driver | null)`, `drive(entity, { throttle, steer, handbrake, boost })`, `refill(entity, units)`, `setModifiers(...)`. `vehicle.damage`: `health`, `damage`, `destroyed`, `repair`, `wreck`. `vehicle.enter` / `vehicle.exit`: `enter(vehicle, entity?)`, `current()`, `exit()`. `vehicle.doors`: `set(vehicle, door, open)`, `cycle`, `state` (doors `Door_FL`, `Door_FR`, `Door_RL`, `Door_RR`). - Events: `vehicle.spawned`, `vehicle.damaged`, `vehicle.destroyed`, `vehicle.collided`, `vehicle.speed` (10 Hz, in km/h and m/s), `vehicle.entry.started`, `vehicle.entered`, `vehicle.exited`, `vehicle.exploded`, `vehicle.stage`, `vehicle.repaired`, `vehicle.module_fitted`, `boostpad.taken`, `rivals.ready`, `spaceship.boarded`, `spaceship.destroyed`... - Variables `vehicle.speed` (km/h) and `vehicle.health`. Verbs `set_door`, `unlock_vehicle_module`, `spawn_spaceship`, `board_spaceship`, `leave_spaceship`. In engine content an archetype of kind `vehicle` takes the component `vehicle { health?, boost? }` and `doors { open: [...] }`. ## Hooks and modding | Hook | Payload | What a tap may do | | --- | --- | --- | | `vehicle.spawn` | `{ archetype, x, z, yaw, adopted }` | change the archetype (another model variant), cancel | | `vehicle.crash` | `{ vehicle, other, speed, amount }` | change the impact damage, cancel | | `vehicle.wreck` | `{ vehicle, driver, reason, source }` | cancel (the car survives) | | `vehicle.boost` | `{ vehicle, driver, boost }` | cancel for the length of the press | | `vehicle.enter` / `vehicle.exit` | seat, stolen / speed | change `stolen`, cancel (refused events are emitted) | | `vehicle.door` | `{ vehicle, door, open, cycle, hold, by }` | change `hold`, cancel (a locked car) | | `vehicle.damage` | `{ vehicle, amount, zone, health, source }` | change `amount`, cancel | | `vehicle.destroy`, `vehicle.explode`, `vehicle.repair` | | cancel a destruction, change the blast radius and damage, change the amount restored | | `vehicle.fit`, `vehicle.unfit`, `vehicle.unlock_module`, `garage.open` | | change `costScale`, cancel | | `boostpad.take`, `rivals.target` | | change `amount`, change or cancel a target | | `spaceship.board`, `.leave`, `.fire`, `.boost`, `.collide` | | change damage or speed, cancel | ```json { "id": "locked", "hook": "vehicle.door", "match": { "vehicle": "e12", "open": true }, "cancel": true, "reason": "locked" } ``` The force model of each tick is not a hook: tune it with the settings and the modifiers. Moddable: the settings above (not `size`) and the collections `vehicle_modules`, `boost_pads`, `spaceships`. ## Engines The vehicles run as the same Rust logic on the web and in the native player. `vehicle.driveable`, `vehicle.enter_exit`, `vehicle.damage` and `vehicle.doors` are also delivered to Godot and Unity as files (a vehicle body with four wheels, the animated entry, the door hinges) and to Unreal through the shared kit library. `vehicle.upgrades`, `vehicle.boostpads`, `vehicle.rivals` and `vehicle.spaceship` run on the web and in the native player. The dents, smoke and fire are web presentation options; the hooks run in the web and Rust players. ## When it does not do what you expect | Symptom | Cause and fix | | --- | --- | | The player cannot get in | out of `enterRadius`, the car is a wreck, or the speed is above 1.25 m/s | | The car has no health bar | the HUD is not bound to `vehicle.health`, or `damage.enabled` is `false` | | Doors do not move | the model has no `gf_door` parts; the state still runs | | Damage seems doubled or missing | both damage models are installed on purpose: with `vehicle.damage` the driveable kit stops pricing collisions itself | | A module cannot be fitted | read the refusal reason (`station`, `cost`, `requires`, `locked`) | | A boost pad does nothing | the car is jumping (above `maxHeight`) or already has `below` boost units or more |