Vehicle upgrades
Modules fitted on a vehicle, one per slot, at a garage or a workbench for a cost in items: driving multipliers, cargo, needs supplied to the driver; settings, the vehicle_modules collection, service, events, hooks.
Vehicle upgrades in your game (vehicle.upgrades) #
What it is for #
vehicle.upgrades lets the player improve a vehicle with modules: one module per slot (engine, wheels, storage, tool, anything the game names), fitted near a garage or a workbench for a cost in items. A module changes how the vehicle drives (top speed, acceleration, grip, steering, braking), adds cargo slots, or supplies the driver's needs. A module is a document of the vehicle_modules collection. The fitted modules live on the vehicle, so the save keeps them. The garage screen is a ui.webui fragment. The cars themselves come from vehicle.driveable: see the vehicles guide.
Turn it on #
gripforge_gamekit_install { project_id: "gkp_…", id: "vehicle.upgrades" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "vehicle.upgrades",
config: { "stations": ["workbench", "garage"], "reach": 8, "cargoLabel": "Cargo" } }
It requires vehicle.drive (from vehicle.driveable), input.actions and game.engine. Cost needs an inventory (inventory.basic), stations come from the craft kits, cargo from storage.containers, needs from survival.needs; each is optional.
First example #
<!-- test: kits/game_engine/host/parity/vehicle.upgrades.garage.json --> A module with a cost, fitted with the service; the trace replays this against the Rust kit:
{ "id": "engine_2", "name": "Engine II", "slot": "engine",
"stats": { "topSpeed": 1.5, "acceleration": 1.25 },
"cost": [{ "item": "scrap", "count": 2 }, { "item": "bolt" }] }
vehicle.upgrades.fit("e2", "engine_2") // { ok: true } once the vehicle is near a station and the bag holds the cost
Settings and defaults #
| Setting | Type | Default | Meaning |
|---|---|---|---|
stations | string[] | ["workbench", "garage"] | kinds of craft.station where modules are fitted (empty: anywhere) |
reach | number (m) | 8 | how near a station the vehicle must stand, and how near the vehicle the player must stay with the garage open |
cargoLabel | string | Cargo | name of the hold that storage modules give |
A vehicle_modules document: { id, name, description?, slot, stats?, storage?, needs?, cost?, unlocked?, requires? }. stats holds the multipliers topSpeed, acceleration, grip, steer, brake (0.05 to 20, 1 unchanged); storage adds cargo slots; needs is { "oxygen": { "supply": 2, "drain": 0 } }, applied while the player drives; cost is a list of { item, count }; unlocked: false hides it until unlocked; requires lists modules that must already be fitted in other slots. The fitted modules multiply together.
Services, events, variables #
vehicle.upgrades(service):modules(),fitted(vehicle),fit(vehicle, module)(answers{ ok, reason? }),unfit(vehicle, slot),unlock(id),unlocked(id),stats(vehicle),cargo(vehicle),canFitHere(vehicle),open(vehicle?),close(),current().- Events:
vehicle.module_fitted(with the module it replaced),vehicle.module_removed(no refund),vehicle.module_unlocked,garage.opened,garage.closed. - Variables:
garage.open,vehicle.modules. - Content: action
unlock_vehicle_module, conditionvehicle_has_module, and the archetype componentvehicle_modules({ "engine": "engine_2" }) for a vehicle placed with modules already fitted, at no cost. - Input:
garage_menu(V) opens the garage by the vehicle; using a vehicle near a station opens it too.
Hooks and modding #
| Hook | Payload | What a tap may do |
|---|---|---|
vehicle.fit | vehicle, module, slot, replaced, costScale | scale the cost (costScale, 0 is free) or refuse the fit |
vehicle.unfit | vehicle, module, slot | cancel (a welded part): the module stays |
vehicle.unlock_module | module, slot | cancel: it stays locked |
garage.open | vehicle, station | cancel: the garage stays closed |
{ "id": "sale", "hook": "vehicle.fit", "match": { "slot": "engine" }, "mul": { "costScale": 0.5 } }
A mod can change the three settings and add, patch or remove documents of vehicle_modules.
When it does not do what you expect #
fit answers { ok: false, reason }: unknown (no such module), vehicle, locked, requires, station (no station of a configured kind within reach), cost (the bag lacks items), fitted (already in place), or the reason of a hook tap.
Limits #
No refund when a module is replaced or removed. Removing a storage module never drops what the hold contains. Web and native players run it; the garage screen is drawn by the ui.webui fragment.
Versions #
Kit version 1.1.0: adds the hooks and the moddable collection.