Modding API reference¶
API version 1. Generated from the game's code by scripts/mod_api_docs.lua; edit the
definitions there, not this file. Start with the modding guide.
- mod.json
- Mod settings
- Lua API
- Events
- Drawing
- Perk flags
- Run state
- Art and sound folders
- Balance
- Weapon patterns
- Safehouse stats
- Counters
- Announcer
- Translations
- Content files
mod.json¶
| Field | Type | Required | Meaning |
|---|---|---|---|
id |
text | yes | Letters, digits and _, no dots. Unique among installed mods; every new id the mod adds starts with it and a dot. |
title |
text | yes | Name in the MODS list, up to 60 characters. |
api |
whole number | yes | The API version the mod was made for. This game reads 1. |
version |
text | Your mod's version, shown in the MODS list. | |
author |
text | Who made it. | |
description |
text | Up to 400 characters. | |
scripts |
list of file names | Lua files to run, in order. A mod with scripts loads only when the player turns on MOD CODE. | |
settings |
list of settings | Up to 16 options the player sets on the mod's page in Settings > CREDITS. Scripts read them with game.setting. Only mods with scripts. See Mod settings. |
|
workshop |
text | The Steam Workshop item the mod is published as, written by the uploader after the first upload so later uploads update that item. |
Mod settings¶
A code mod lists its options in mod.json settings. Each loaded mod with settings has
a page in Settings > CREDITS, and the player's choices are saved with their other
preferences. Scripts read them with game.setting(id).
"settings": [
{"id": "panel", "label": "SHOW PANEL", "type": "toggle", "default": true},
{"id": "opacity", "label": "OPACITY", "type": "slider", "min": 0.2, "max": 1, "step": 0.1, "default": 0.8},
{"id": "side", "label": "SIDE", "type": "choice", "values": ["LEFT", "RIGHT"], "default": "LEFT"}
]
| Field | Meaning |
|---|---|
id |
Letters, digits and _. What game.setting takes. |
label |
Name on the mod's page, up to 32 characters. |
help |
Optional line under the list when the setting is selected, up to 96 characters. |
type |
toggle (on or off), slider (a number) or choice (one of several texts). |
default |
The value before the player changes it: true or false for a toggle, a number for a slider, one of values for a choice. |
min, max, step |
slider: the range and the step between values. |
values |
choice: 2 to 8 texts of up to 20 characters, in order. |
Lua API¶
Scripts listed in mod.json scripts find these in the game table. Within one API
version entries are only added, never changed or removed. Scripts can also reach any
game module (require), but only what is listed here is kept stable.
Adding and changing content¶
The same rows as the JSON files, from Lua. Rows are checked exactly like JSON rows when the mod finishes loading; a bad row skips the whole mod with a reason. Call these at the top level of a script, not inside handlers.
game.add(kind, row)¶
Add a new content row of kind (one of cards, weapons, counters, cars, parts, maps, paints, safehouse, lockbox, enemies, announcer, difficulties, modifiers, balance, music, languages). The row's id must start with your mod id and a dot. Same fields as the JSON files.
game.add('enemies', {id = 'neon.van', base = 'gang', label = 'NEON VAN', hp = 40, gold = 60,
spawn = {heat = 3, every = 25}})
game.change(kind, id, fields)¶
Change fields of an existing row, from the base game or a mod loaded earlier. Only the fields you give change.
Registering behaviour¶
Code that content rows point at by id. Ids start with your mod id and a dot. Register before (or in the same script as) the rows that name them.
game.enemy(id, handlers)¶
Behaviour for an enemies row whose behavior is id. Handlers (all optional): think(s, e, dt) every tick, return true to replace the base driving that tick; damage(s, e, amount, source) before damage lands, return a new amount; death(s, e) when destroyed (not when it drives off screen); phase(s, e, n) when a boss passes its nth health phase (e.boss_phase holds the phases passed); draw(e, clock, d) each displayed frame, with the drawing kit d (see Drawing): return true to replace the sprite.
game.enemy('neon.van', {
think = function(s, e, dt)
if game.distance(e, s.player) < 150 then
game.drive(s, e, s.player.x, s.player.y, 520, dt)
return true
end
end,
death = function(s, e) game.blast(s, e.x, e.y, 40, 300) end,
})
game.weapon(id, handlers)¶
A weapon pattern of your own, for a weapons row whose pattern is id (see Weapon patterns for the built-in ones). fire(s, w, dt) runs every tick while the player owns the row's card. w is the weapon: id (its card), rank, stats (this tick's numbers with upgrades applied: range, interval, damage, rounds, spread in radians, speed, radius, the other numbers the row sets, and each trait its cards switch on as true) and state, a table of your own kept for the run. Optional hit(s, e, damage) runs when one of its rounds hits an enemy; return a new damage. Optional draw(s, w, d) runs each displayed frame while the card is owned, with the drawing kit d (see Drawing). Damage the weapon deals is credited to its card on the results screen.
game.weapon('neon.ring', {
fire = function(s, w, dt)
w.state.wait = (w.state.wait or 0) - dt
if w.state.wait > 0 or not game.target(s, w.stats.range) then return end
w.state.wait = w.stats.interval
for i = 1, w.stats.rounds do
game.fire(s, w, i / w.stats.rounds * 2 * math.pi)
end
end,
})
game.trait(pattern, id, handlers)¶
A new trait for one of the game's weapon patterns (see Weapon patterns), switched on like the pattern's own: a weapons row on that pattern names it in an upgrade card, {"neon.emp": true}. Handlers (all optional) get the weapon w as game.weapon does, with a state table of the trait's own: tick(s, w, dt) every tick while the trait is on; hit(s, e, damage, w) when that weapon damages an enemy, return a new damage; draw(s, w, d) each displayed frame, with the drawing kit d. Damage dealt inside a handler is credited to the weapon.
game.trait('drone', 'neon.emp', {
hit = function(s, e, damage, w)
e.spin_time = math.max(e.spin_time or 0, 0.5)
return damage
end,
})
game.add('cards', {id = 'neon.emp_card', name = 'EMP DRONES', tier = 'part', max = 1, icon = 12,
requires = 'drone', description = 'Drone zaps stall the car they hit.'})
game.change('weapons', 'drone', {upgrades = {['neon.emp_card'] = {['neon.emp'] = true}}})
game.effect(id, handlers)¶
A card effect, named by a cards row's effect. Handlers are events (see Events) and run only while the player owns the card; each gets the card's rank last. Damage dealt inside an effect is credited to the card on the results screen.
game.effect('neon.static', {
kills = function(s, count, rank)
game.blast(s, s.player.x, s.player.y, 40, 150 * rank * count)
end,
})
game.perk(id, handlers)¶
A car perk, named by a cars row's perk. Handlers are events (see Events) and run while that car is driven, with rank 1. A perk may also set the flags in Perk flags.
game.mechanics(id, handlers)¶
A map's own code, named by a maps row's mechanics. Its events (see Events) run only in runs on that map, with rank 1. It can also have the handlers in Map handlers: the objective, a finale of its own, a guidance route and damage rules.
game.mechanics('neon.rules', {
finale = function(s)
if not s.neon_drop then
local x, y = game.street(s, 0, -4000)
s.neon_drop = {x = x, y = y}
end
if game.distance(s.player, s.neon_drop) < 120 then game.win(s, 'THE DROP GOT YOU OUT.') end
return true
end,
objective = function(s)
if s.neon_drop then return 'REACH THE DROP', 'IT LEAVES WITH YOUR CASH' end
end,
route = function(s)
if s.neon_drop then return s.neon_drop.x, s.neon_drop.y end
end,
})
game.on(event, fn)¶
Listen to an event (see Events) in every run, whatever the car and cards. The function gets the run state and the event's value, with no rank.
Acting on a run¶
Helpers for use inside handlers. Each takes the run state s first. Those that change the run (spawn, shoot, fire, drive, blast, win, sound, say, heal, cash, nos, count) cannot be called from draw handlers.
game.spawn(s, type_id) returns enemy or nil¶
Spawn an enemy of an enemies row now, where its family arrives (see base). Returns nil when there is no room, or, for a boss, when it may not fight now.
game.shoot(s, e, angle, speed, lanes, spread)¶
Fire police rounds from enemy e toward angle (radians) at speed pixels per second. lanes rounds fan out spread degrees apart (default one round). Rounds look and hurt like every enemy bullet.
game.fire(s, w, angle, x, y) returns round¶
Fire one round of weapon w (from fire) toward angle (radians), from the car or from x, y. It flies at w.stats.speed for w.stats.range and deals w.stats.damage, on the same path as the player's guns.
game.target(s, range, x, y) returns target or nil¶
The nearest live target within range of the car (or of x, y) that it can see: an enemy, the job van or a wanted civilian, as the player's guns pick them. Nil when there is none.
game.drive(s, e, x, y, speed, dt)¶
Steer enemy e toward a point through the streets this tick, like a cop car. Use it from think and return true.
game.enemies(s, x, y, radius) returns list¶
Live enemies within radius of a point, nearest first.
game.blast(s, x, y, radius, damage)¶
Damage every enemy within radius of a point, as an explosion would.
game.difficulty(s) returns id¶
The id of the run's difficulties row (standard to fast_cops in the base game, or a mod's).
game.map(s) returns id¶
The id of the run's maps row (city, shell_cay, monte_fisco or panopticon in the base game, or a mod's).
game.island(s) returns left, top, right, bottom¶
The edges of the run's island in world pixels: land runs from left to right and from top (north) to bottom. A district is 2048 pixels across.
game.street(s, x, y) returns x, y¶
The point on a street nearest to x, y, or nothing when there is no street near it.
game.win(s, reason) returns true or false¶
End the run as an escape. reason is the results line, up to 60 characters, and defaults to YOU ESCAPED and the map's name. It counts like any escape: toward the difficulty ladder, escapes and the map's own escapes counter. False when the run is already over.
game.modifiers(s) returns list¶
The ids of the modifiers rows the run plays with, in load order. Empty without modifiers.
game.sound(s, name, volume, pitch)¶
Play a sound: a game sound by name (a file name in the game's sfx/ folder) or one from your mod's sfx/ folder as modid.name. volume 0 to 1 (default 0.3), pitch 1 is normal. Follows the player's vehicle volume.
game.say(s, id, lines)¶
Show an announcer line: the id of an announcer row, the game's or your mod's (see Content files). It waits its turn like the game's calls, by the row's priority, and plays the row's sound. lines (optional) is one or two texts of up to 40 characters to show instead of the row's, for live numbers. Nothing shows while the player has the announcer off.
game.enemy('neon.van', {
death = function(s, e)
s.neon_vans = (s.neon_vans or 0) + 1
game.say(s, 'neon.van_down', {'Van down.', s.neon_vans .. ' wrecked so far.'})
end,
})
game.heal(s, hearts)¶
Give the player hearts hearts back (0.5 is half a heart), up to their maximum.
game.cash(s, amount)¶
Give the player cash, as if they collected it.
game.nos(s, share)¶
Add a share of a full NOS tank (1 fills it, negative drains it).
game.count(s, id, amount)¶
Add amount (default 1) to one of your counters rows (see Content files) in this run. Rewards whose counter it is move toward their target as the game's own contracts do, across runs or within one by their scope. Only runs the player starts count, not the tutorial. The game feeds its own counters; they cannot be counted from a mod.
Utilities¶
game.random(s, lo, hi) returns number¶
A random number from the mod stream, seeded per run: random(s) is 0 to 1, random(s, n) is a whole number 1 to n, random(s, lo, hi) is lo to hi. Use it instead of math.random so modded runs stay reproducible; it never changes what the game itself rolls. Not from draw handlers: animate with d.time instead.
game.setting(id) returns value¶
The player's value for one of your mod's settings (mod.json settings, see Mod settings): true or false for a toggle, a number for a slider, the chosen text for a choice. Read it where you use it: the player can change it at any time. Until the game has read the player's saved preferences, during loading, it is the default.
game.text(key, values) returns text¶
Text in the player's language for a key: your mod's own (its text/en.json, keys under your mod id) or one of the game's. A language without the key reads in English. values fills the text's {name} tokens. An unknown key is an error. Call it from handlers: while mods load, the text is not ready. See Translations.
game.distance(a, b) returns number¶
Distance in pixels between two things with x and y (the player, an enemy).
game.angle(a, b) returns radians¶
Angle from a to b, for game.shoot and game.fire.
game.log(...)¶
Print a line to the game's console output, prefixed with your mod id.
game.HEART¶
Health units in one heart. s.player.hp and s.player.max_hp use these units.
game.API¶
The API version this game provides; mod.json api must match it.
Events¶
Handler names for game.effect, game.perk, game.mechanics and game.on. Card effects
get the card's rank last and Safehouse line effects the line's level; perks, difficulty
and modifier effects and map mechanics get 1; game.on listeners get no rank. Handlers
run in a fixed order (car perk, difficulty, map, modifiers, Safehouse lines, cards in
catalog order, listeners in load order).
A handler that errors is switched off for the session; the run continues.
| Event | Arguments | When |
|---|---|---|
run_start |
s, rank |
Once, on a run's first played tick. |
tick |
s, dt, rank |
Every simulation tick; dt is the tick length in seconds. |
kills |
s, count, rank |
Vehicles were destroyed this tick. |
hurt |
s, rank |
The player lost health this tick. |
nos_start |
s, rank |
The player started boosting. |
wrecked |
s, rank |
The run is lost to damage. |
draw_ground |
s, d, rank |
Each displayed frame, in world coordinates below the cars. d is the drawing kit (see Drawing). |
draw_world |
s, d, rank |
Each displayed frame, in world coordinates above the cars and aircraft. |
draw_hud |
s, d, rank |
Each displayed frame, in HUD coordinates (640 by 360) over the game's HUD. |
Drawing¶
The draw_ground, draw_world and draw_hud events, content enemies' draw and code
weapons' draw get a drawing kit d. They run once per displayed frame, which differs
from machine to machine, so they only draw: game calls that change the run refuse to
run inside them, and anything they need from the run should be worked out in tick.
World layers use world pixels (the player is at s.player.x, s.player.y); the HUD
layer uses the 640 by 360 HUD space. Each layer may make 2000 calls per frame;
calls past that are dropped.
Colours are a name (black, panel, gray, white, red, green, gold, blue, cyan, amber) or {r, g, b} from 0 to 255.
alpha is 0 to 1 and defaults to 1.
game.on('draw_hud', function(s, d)
d.anchor('top_right')
d.text('WRECKS ' .. s.kills, 632, 150, 'gold', 'right')
end)
| Kit | Arguments | Does |
|---|---|---|
d.rect |
x, y, w, h, colour, alpha |
A filled rectangle. |
d.box |
x, y, w, h, colour, alpha |
A rectangle outline. |
d.line |
x1, y1, x2, y2, colour, alpha, width |
A line, width pixels wide (default 1). |
d.circle |
x, y, radius, colour, alpha |
A filled circle. |
d.ring |
x, y, radius, colour, alpha |
A circle outline. |
d.sprite |
name, x, y, angle, scale, alpha |
A game sprite or one from your mod's sprites/ folder (modid.name), centred on x, y and turned angle radians. |
d.text |
text, x, y, colour, align, alpha |
One line of text in the game's font, from x (align 'left'), around it ('center') or up to it ('right'). At most 80 characters. |
d.textWidth |
text |
The width d.text gives text. |
d.light |
x, y, radius, colour, strength |
World layers: a light at night, like the game's headlights and blasts. Nothing in daylight. |
d.visible |
x, y, reach |
World layers: whether anything within reach of a point is on screen. Skip what is not. |
d.anchor |
name |
HUD: which edge of the screen the HUD scale grows from for what you draw next: top_left (the default), top, top_right, left, center, right, bottom_left, bottom or bottom_right. Coordinates stay 640 by 360. |
d.width, d.height |
The layer's size: 640 by 360 for the HUD, the view in world pixels for the world. | |
d.time |
Seconds the game has been running, for animation. Not the run's clock (s.time). |
|
d.reduced_flashes, d.reduced_motion |
The player's accessibility settings. Skip flashing and moving effects when they are true. |
Perk flags¶
Set to true in a game.perk table.
| Flag | Effect |
|---|---|
contact_proof |
Contact with light cop cars and bikes costs no hearts. |
nos_ram |
Boosting rams wreck light cop cars and bikes. |
Map handlers¶
A game.mechanics table may have these besides events. The game asks them before the
base map's own mechanics.
| Handler | Arguments | Returns | When |
|---|---|---|---|
objective |
s |
text, next | The objective pill's text while it returns one, in place of the map's, with next (optional) as the objective panel's second line. Up to 40 characters each. |
finale |
s |
true or nothing | Each tick from the end of the five-star minute until the run ends. Return true while the map's own endgame is on, and end it with game.win. Return nothing to hand over to the map's boss, the Collector or the freeway escape, as on its base map. |
route |
s |
x, y | A place to guide the player to. The game routes there along the streets, with the arrows the game's own finales use. Return nothing for no guide. |
damage |
s, e, amount |
amount | Damage the player deals to enemy e on this map. Return a new amount, or nothing to keep it. |
Run state¶
Every handler gets the run state s. These fields are kept stable; read them freely and
change the run through the API.
| Field | Meaning |
|---|---|
s.player |
The player car: x, y, angle, vx, vy, hp, max_hp, boost (NOS tank 0 to 1), boosting, car (car id). |
s.enemies |
Every enemy. Each has x, y, angle, hp, max_hp, role (its family) and, for content enemies, enemy_type (the row id). Use e.hp > 0 for live ones. |
s.time |
Seconds since the run started. |
s.heat |
Wanted level, 1 to 5. |
s.kills |
Vehicles destroyed this run. |
s.upgrades.ranks |
Card ranks by card id (s.upgrades.ranks['neon.static']). |
s.safehouse |
The run's Safehouse stats by id (see Safehouse stats), or nil in a run without a Safehouse (the demo, the tutorial). |
Art and sound folders¶
Folders inside the mod. They load without MOD CODE.
| Folder | Files | Meaning |
|---|---|---|
sprites/ |
.png | A file named like a game sprite replaces it and must be the same size; the masks the game makes from that sprite (a car's _paint and _invulnerable, an art sprite's _mask) are rebuilt from your file unless you ship them too. Any other becomes a new sprite modid.name, up to 256 by 256 pixels. |
sfx/ |
.wav | A file named like a game sound replaces it. Any other becomes a new sound modid.name for game.sound. |
music/ |
.ogg, .mp3, .wav, .flac | Tracks named by the mod's music.json rows (file). |
Balance¶
The game's tuning numbers, changed with rows in balance.json (or
game.change('balance', id, fields)). A row names a system and gives only the values
it changes. Difficulties scale the pursuit numbers further. Lists with five
entries are one value per wanted level, I to V.
[{"id": "economy", "van_cash": 360, "style_cash": {"near_miss": 10}},
{"id": "pursuit", "wanted_at": [0, 45, 110, 190, 270]}]
economy¶
Cash: what the run pays and what laundromat upgrades cost.
| Value | Type | Default | Meaning |
|---|---|---|---|
upgrade_base |
whole number, 0 to 100000 | 80 | Price of the first laundromat upgrade. |
upgrade_step |
whole number, 0 to 10000 | 30 | Price added per upgrade bought. |
upgrade_curve |
number, 0 to 1000 | 4 | Price added per upgrade bought, squared. |
drift_rate |
number, 0 to 100 | 2 | Cash per second of drifting. |
combo_seconds |
list of 4 numbers, 0 to 600 | [5, 12, 22, 35] | Seconds of unbroken combo to reach each cash multiplier step, ascending. |
style_cash |
object of numbers (0 to 1000) with keys bait_escape, chain_reaction, clean_exit, double_takedown, drift_kill, near_miss, needle, showboat, sliding_heist, switchback, triple_takedown, wall_skim |
bait_escape 6, chain_reaction 8, clean_exit 2, double_takedown 6, drift_kill 2, near_miss 3, needle 6, showboat 5, sliding_heist 8, switchback 3, triple_takedown 10, wall_skim 4 | Cash for each driving trick. Give only the tricks you change. |
club_cash |
whole number, 0 to 10000 | 20 | Cash from a club pickup. |
van_cash |
whole number, 0 to 100000 | 180 | Base cash in a cash van. |
van_step |
whole number, 0 to 10000 | 12 | Cash van bonus per upgrade level. |
van_level_cap |
whole number, 0 to 100 | 10 | Upgrade level where the van bonus stops growing. |
van_per_minute |
whole number, 0 to 10000 | 30 | Cash van bonus per minute of the run. |
raid_cash |
whole number, 0 to 1000000 | 500 | Base cash at stake in a raid, the timed dash to a stash that police seize as time runs out. |
raid_step |
whole number, 0 to 100000 | 80 | Raid cash bonus per upgrade level. |
raid_level_cap |
whole number, 0 to 100 | 10 | Upgrade level where the raid bonus stops growing. |
raid_per_minute |
whole number, 0 to 100000 | 25 | Raid cash bonus per minute of the run. |
pursuit¶
Police pressure: how fast the wanted level climbs, when each enemy family joins, and how often the police send units at each wanted level (I to V). Difficulties scale these further.
| Value | Type | Default | Meaning |
|---|---|---|---|
wanted_at |
list of 5 numbers, 0 to 3600 | [0, 30, 75, 135, 195] | Seconds into a run at which wanted levels I to V begin, ascending. The first is 0. |
warmup |
number, 0 to 120 | 15 | Seconds of gentle opening before the full patrol count and specialists. |
opening |
whole number, 0 to 12 | 2 | Cop cars at the start of a run. |
foot_share |
number, 0 to 1 | 0.2 | Share of dispatches on foot at wanted I and II. |
unlock |
object of whole numbers (1 to 5) with keys attack_bike, fighter_jet, gang, gunship, heli_troops, helicopter, interceptor, officer, orbital, patrol, roadblock, rocket, soldier, tank, twin_rotor, ufo |
attack_bike 2, fighter_jet 3, gang 2, gunship 4, heli_troops 2, helicopter 2, interceptor 2, officer 1, orbital 5, patrol 1, roadblock 3, rocket 4, soldier 3, tank 3, twin_rotor 4, ufo 5 | Wanted level at which each police family can appear. Give only the families you change. |
aggression |
list of 5 numbers, 0.1 to 10 | [1.35, 1.35, 1.15, 1, 1] | Per wanted level: multiplies the dispatch rate and divides specialist intervals. |
rate |
list of 5 numbers, 0 to 200 | [5, 10.5, 13.5, 16.5, 20.5] | Per wanted level: how often cop cars are dispatched (higher is more often). |
cut_size |
list of 5 whole numbers, 0 to 20 | [0, 3, 4, 5, 6] | Per wanted level: cars in a cut-off group. |
cut_interval |
list of 5 numbers, 0.5 to 600 | [16, 8, 6, 5, 4] | Per wanted level: seconds between cut-offs. |
bike_interval |
list of 5 numbers, 0.5 to 600 | [16, 14, 12, 10, 8] | Per wanted level: seconds between attack bike groups. |
gang_interval |
list of 5 numbers, 0.5 to 600 | [18, 18, 15, 12, 10] | Per wanted level: seconds between gang cars. |
gang_cap |
list of 5 whole numbers, 0 to 20 | [0, 2, 3, 4, 4] | Per wanted level: most gang cars at once. |
heli_interval |
list of 5 numbers, 0.5 to 600 | [18, 10, 7, 4.5, 3.2] | Per wanted level: seconds between helicopters. |
tank_interval |
list of 5 numbers, 0.5 to 600 | [22, 22, 9, 5, 3.2] | Per wanted level: seconds between rocket tanks. |
tank_cap |
list of 5 whole numbers, 0 to 20 | [0, 0, 2, 3, 4] | Per wanted level: most rocket tanks at once. |
jet_interval |
list of 5 numbers, 0.5 to 600 | [22, 22, 10, 7, 5] | Per wanted level: seconds between fighter jet passes. |
troop_interval |
list of 5 numbers, 0.5 to 600 | [30, 30, 30, 9, 5] | Per wanted level: seconds between troop drops. |
troop_count |
list of 5 whole numbers, 0 to 40 | [8, 8, 8, 8, 12] | Per wanted level: soldiers per troop drop. |
gunship_interval |
list of 5 numbers, 0.5 to 600 | [24, 24, 24, 12, 7] | Per wanted level: seconds between gunships. |
ufo_interval |
list of 5 numbers, 0.5 to 600 | [24, 24, 24, 24, 24] | Per wanted level: seconds between UFOs. |
block_interval |
list of 5 numbers, 0.5 to 600 | [26, 24, 18, 16, 14] | Per wanted level: seconds between roadblocks. |
spike_interval |
list of 5 numbers, 0.5 to 600 | [26, 24, 22, 20, 18] | Per wanted level: seconds between spike strips. |
handling¶
The player car's baseline handling, before car factors, parts and cards. World units are pixels and seconds.
| Value | Type | Default | Meaning |
|---|---|---|---|
engine |
number, 10 to 400 | 76.5 | Engine thrust. |
top_speed |
number, 100 to 1000 | 387.429 | Top speed without NOS. |
reverse_speed |
number, 20 to 400 | 78 | Top speed in reverse. |
brakes |
number, 100 to 3000 | 630 | Braking force. |
nos_speed |
number, 100 to 1200 | 477 | Top speed while boosting. |
nos_force |
number, 10 to 1000 | 247.5 | Extra thrust while boosting. |
nos_capacity |
number, 0.1 to 5 | 0.75 | NOS tank size: a bigger tank boosts longer and takes longer to refill. |
nos_recharge |
number, 0 to 5 | 0.21 | How fast the NOS tank refills. |
nos_recharge_delay |
number, 0 to 10 | 0.5 | Seconds after boosting before the tank refills. |
steer_low |
number, 0.05 to 1.5 | 0.5 | Steering angle at low speed. |
steer_high |
number, 0.05 to 1.5 | 0.22 | Steering angle at high speed. |
grip |
number, 300 to 20000 | 3300 | Tire grip outside a drift. |
drift_grip |
number, 20 to 2000 | 210 | Tire grip while drifting. |
drift_yaw |
number, 0.5 to 10 | 2.6 | How fast a drift turns the car. |
handbrake_drag |
number, 10 to 1000 | 140 | Slowdown on the handbrake. |
exit_boost_duration |
number, 0 to 5 | 1.2 | Seconds of the speed boost when a drift ends. |
exit_boost_force |
number, 0 to 20 | 4 | Strength of the drift exit boost. |
enemies¶
Police health and the cash each pays when destroyed. Health is in the same units as content enemies' hp.
| Value | Type | Default | Meaning |
|---|---|---|---|
cop_car_hp |
number, 1 to 10000 | 6 | Cop car health. |
attack_bike_hp |
number, 1 to 10000 | 4 | Attack bike health. |
attack_bike_speed |
number, 40 to 900 | 500 | Attack bike top speed. |
attack_bike_gold |
whole number, 0 to 1000 | 8 | Cash from an attack bike. |
gang_hp |
number, 1 to 10000 | 18 | Gang car health. |
gang_speed |
number, 40 to 900 | 360 | Gang car top speed. |
gang_gold |
whole number, 0 to 1000 | 40 | Cash from a gang car. |
default_gold |
whole number, 0 to 1000 | 5 | Cash from any destroyed police unit without its own value, including cop cars. |
officer_hp |
number, 1 to 10000 | 4 | Officer on foot health. |
soldier_hp |
number, 1 to 10000 | 8 | Soldier health. |
tank_hp |
number, 1 to 10000 | 30 | Rocket tank health. |
tank_gold |
whole number, 0 to 10000 | 40 | Cash from a rocket tank. |
Weapon patterns¶
How a weapons row aims and fires. Every pattern's hits crit and credit the card like
the base weapon's. A new row on a pattern takes every field it leaves out from that
base weapon, except upgrades, so {"id": "neon.drone", "pattern": "drone", "damage": 4}
is a second drone rack that hits harder. A row may instead name a game.weapon and
fire with code of its own.
| Pattern | Like | How it fires | Traits |
|---|---|---|---|
turret |
machine gun | Aims at the nearest target it can see within range (the Collector first) and fires about one round per interval, in bursts of burst. Holding a target spins it up over spool seconds, to fire up to 1.5 times faster. |
|
rear |
exhaust gun | Fires a fan of rounds rounds behind the car every interval, spread degrees wide, whether or not anything is there. |
|
broadside |
side shotguns | A gun on each side of the car fires a fan of rounds pellets, spread degrees wide, when an enemy is alongside within range. |
linked: Both sides fire when either lines up. |
mortar |
roof mortar | Lobs rounds shells at the nearest target within range, heavy threats first, aiming where it will be. Each lands after flight seconds and blasts everything within radius for damage. |
airburst: Shells also hit aircraft. |
drone |
drone rack | count drones orbit the car. Every interval each one zaps up to rounds enemies it can see within range for damage, heavy threats first. |
hunter: Drones reach further for tanks and aircraft and prefer them. decoy: The first drone blocks one helicopter burst, UFO hit or Collector shot, then recharges. |
rockets |
homing rockets | Every interval, fires a burst of rounds homing rockets at the nearest target it can see within range. Starting NOS adds a burst. Rockets fly at speed, turn at turn radians per second and explode on contact: damage to what they hit and splash within radius. |
carpet: Starting NOS drops a line of carpet bombs (five more than rounds) instead of a burst. |
saws |
buzz saws | count saws orbit the car radius pixels out at spin radians per second, cutting each ground target they touch for damage, at most once per interval. |
carbide: Double damage to tanks and aircraft. rimsaw: While drifting the saws swing 60% wider and spin faster. |
fire_trail |
burning tires | Drifting leaves burning tracks that last life seconds and burn each ground target that touches them for damage. |
sticky: Burning slows pursuers for 1.5 seconds. detonator: Starting NOS sets the trail off in a ripple of blasts. shock: Contact burns deal 1 more damage. |
lightning |
pylon | Drifting charges a coil at charge per second, up to 100. When the drift ends it strikes the nearest target within range for damage, then hops jump pixels at a time, to up to rounds targets for a full charge. It recharges for interval. |
blackout: Each strike also spins out police cars near the car. |
ball |
wrecking ball | A ball on a range-pixel chain behind the car. Fast swings hit the ground targets they meet for damage, double on hard swings. |
demolition: Swings into walls blast craters. shockwave: Hard swings also blast around the ball. |
railgun |
railgun | Fires a slug radius pixels wide straight ahead when a ground target is on the line within range, piercing everything on it for damage. It recharges for interval. |
wide: The slug is twice as wide. ricochet: The slug bounces off the first wall. |
mines |
mine layer | Drops a mine behind the moving car every interval, up to cap on the road. A mine arms after half a second, lasts life seconds and blasts ground targets within radius for damage when one drives over it. |
chain: A blast sets off armed mines nearby. |
pulse |
subwoofer | When a ground target is near, sends out a ring radius pixels wide that hits each ground target once for damage and shoves it outward. It recharges for interval. |
stun: Pulses spin out the police cars they hit. echo: Every pulse is followed by a second. |
boomerang |
hubcaps | Every interval, throws rounds discs at the nearest ground target it can see. They fly out range pixels at speed and come back, cutting each ground target they pass once per leg for damage. |
spinner: Discs hover at the end of each throw, cutting all around. |
sentries |
sentry drop | While the car moves, drops a turret behind it every interval, up to cap standing. Each stands for life seconds and shoots the nearest target it can see within range for damage every fire seconds. |
scuttle: Sentries explode when they expire. |
ram |
reinforced bumper | Hitting an enemy fast (the car above 45 speed, closing at 70 or more) deals damage times the car's mass. Tanks, heavy vehicles, roadblocks and aircraft take it at most once per interval seconds; Reload does not shorten that. Each ram row owned adds its damage to every ram. |
momentum: Fast rams push through light vehicles without losing speed. padding: Losing health in a crash fills the NOS tank. |
An upgrade card in a row's upgrades adds this much per rank. Any other key must be
true and names a trait of the row's pattern, which the card switches on.
| Key | Type | Adds |
|---|---|---|
cap |
whole number, -24 to 24 | Mines or sentries added to cap. |
charge |
number, -0.9 to 10 | Share of charge added (0.2 charges 20% faster). |
count |
whole number, -4 to 8 | Drones or saws added. |
damage |
number, -100 to 1000 | Damage added to each hit. |
life |
number, -30 to 60 | Seconds added to life. |
radius |
number, -48 to 96 | Pixels added to radius. |
range |
number, -0.9 to 10 | Share of range added (0.2 reaches 20% further). |
rate |
number, -0.9 to 10 | Fires faster: interval and fire are divided by 1 plus the total (0.15 is 15% faster). |
reach |
number, -300 to 600 | Pixels added to range and jump. |
rounds |
whole number, -8 to 12 | Rounds, rockets, beams, discs or chain targets added, up to max_rounds. |
spool |
number, -0.9 to 10 | Spins up faster: spool is divided by 1 plus the total. |
turn |
number, -0.9 to 10 | Share of turn added (0.5 turns 50% faster). |
Safehouse stats¶
What a safehouse row's effects raise. Each stat starts at its neutral value and every
bought level of every line adds its amount; the sum stays inside the range however lines
stack. Runs read them as s.safehouse.
{"id": "neon.war_chest", "label": "WAR CHEST", "line": "+$40 AND 2% REACH PER LEVEL",
"max": 5, "base": 700, "effects": {"start_cash": 40, "magnet": 0.02}}
| Stat | Neutral | Range | Meaning |
|---|---|---|---|
start_cash |
0 | 0 to 5000 | Cash every run starts with, in dollars. |
upgrade_cost |
1 | 0.5 to 2 | Multiplier on laundromat upgrade prices: -0.02 a level is 2% cheaper. |
magnet |
1 | 0.5 to 3 | Multiplier on how far away pickups are pulled in. |
nos_duration |
1 | 0.5 to 3 | Multiplier on how long a full NOS tank lasts. |
payout |
1 | 0.5 to 3 | Multiplier on cash from cash vans and raids. |
first_star_delay |
0 | 0 to 120 | Seconds the first wanted star comes later. |
wrench_bonus |
0 | 0 to 60 | Extra health a wrench heals, in health units (game.HEART, 20, is one heart). |
bounty |
1 | 0.5 to 3 | Multiplier on the cash takedowns drop. |
interest |
1 | 0.5 to 3 | Multiplier on the cash a finished run banks. |
nos_recharge |
1 | 0.5 to 3 | Multiplier on how fast NOS refills. |
Counters¶
What a reward's counter can count. The game feeds these itself; a mod adds its own
counters rows and feeds them with game.count. Counters marked best keep each run's best
and no lifetime total.
| Counter | Shows as | Counts |
|---|---|---|
money_laundered |
LAUNDERED 3/10 | Dollars laundered. |
drift_seconds |
DRIFT 3/10 SEC | Seconds spent drifting. Keeps fractions. |
races_finished |
RAID HAULS 3/10 | Raids finished. |
races_won |
RAID HAULS 3/10 | Raids won. |
club_takings |
CLUB TAKINGS 3/10 | Club takings collected. |
street_caches |
STREET CACHES 3/10 | Street caches taken. |
high_wanted_seconds |
WANTED IV/V 3/10 SEC | Seconds spent at wanted level IV or V. Keeps fractions. |
escapes |
ESCAPES 3/10 | Escapes. |
police_takedowns |
COP CARS 3/10 | Cop cars taken down. |
bike_takedowns |
BIKES 3/10 | Attack bikes taken down. |
helicopter_takedowns |
HELICOPTERS 3/10 | Helicopters taken down. |
tank_takedowns |
TANKS 3/10 | Tanks taken down. |
seizure_takedowns |
TAX TRUCKS 3/10 | Tax trucks taken down. |
chain_best |
CHAIN 3/10 | Longest takedown chain in a run. Best only. |
wanted_reached |
WANTED 3/10 | Highest wanted level reached in a run. Best only. |
nos_seconds |
NOS 3/10 SEC | Seconds spent boosting. Keeps fractions. |
evolutions |
EVOLUTIONS 3/10 | Evolution cards owned in a run. Best only. |
clean_escapes |
CLEAN ESCAPES 3/10 | Escapes without a repair at a garage or a wrench. |
escape_bracket |
BEST ESCAPE: AUDIT ME PLENTY | Highest difficulty escaped at, as its number plus one. Best only. |
cars_escaped |
CARS 3/10 | Cars that have escaped at least once. |
cay_escapes |
CAY ESCAPES 3/10 | Escapes from the Cay. |
fisco_escapes |
MONTE FISCO ESCAPES 3/10 | Escapes from Monte Fisco. |
panopticon_escapes |
PANOPTICON BREAKOUTS 3/10 | Breakouts from the Panopticon. |
Announcer¶
The game's own lines and when it calls them. An announcer.json row with one of these
ids changes what it says, its face, its sound or its timing; mod code can call any of
them, or the mod's own, with game.say. A line with enemy introduces that enemy the
first time one comes close in a run.
[{"id": "helicopter", "sound": "army_radio_01"},
{"id": "neon.van", "lines": ["That van is rigged.", "Keep your distance."], "enemy": "neon.van", "priority": 3}]
| Line | Called when | Says |
|---|---|---|
start |
A run begins. | Keep your eyes on the road / and bring home the cash. |
start_fast_cops |
A run begins at a difficulty with faster police cars (cop_speed above 1), instead of start. |
They tuned the cruisers tonight. / Corners lose them, straights won't. |
wanted |
The wanted level rises, below five stars. | They're sending / more reinforcements. |
lost |
The police lose sight of the car. | Stay out of view / while they search for you. |
spotted |
The police spot the car again. | Move, they've / spotted you. |
tipoff |
Someone tips off the police while they search. | Someone called you in, / so they're closing the net. |
upgrade |
The player can afford a laundromat upgrade. | Take that cash to / a laundromat for an upgrade. |
critical |
The car is down to its last heart. | Find a garage before / that car falls apart. |
wrench |
A wrench is near a damaged car, once a run. | Get near that wrench / to fix one heart. |
nos_rocket |
A blue NOS pickup is near, once a run. | Grab that blue NOS / for double-strength boost. |
final |
The wanted level reaches five stars, on a map without a line of its own (its maps row's final). |
One minute at five stars, / then take the freeway exit. |
final_boss |
The wanted level reaches five stars on a City map whose maps row names a boss but no line. {boss} is the boss's title. |
One minute at five stars, / then face {boss}. |
final_city |
The wanted level reaches five stars in the City. | One minute at five stars, / then face the Collector. |
final_cay |
The wanted level reaches five stars on Grand Shell Cay. | One minute at five stars, / then the Liquidator comes ashore. |
final_fisco |
The wanted level reaches five stars in Monte Fisco. | One minute at five stars, / then the Motorcade rolls out. |
final_panopticon |
The wanted level reaches five stars in the Panopticon. | One minute at five stars, / then blind the Eye and break out. |
overtime |
Overtime starts, in the full game. | Each half minute you stay / pays 10% more, if you escape. |
final_seconds |
Ten seconds of the five-star minute are left. {time} is the time left. |
Keep that car alive / for {time} more. |
raid_incoming |
The police start tracking down one of the player's used-car lots. | The police are tracking down / one of your used-car lots. |
raid |
A raid on a lot begins. {cash} is the cash left there. |
I've marked the raid on your map, / so get there for the {cash} left. |
raid_urgent |
A quarter or less of the lot's cash is left. {cash} is what is left. |
Only {cash} left at the lot, / so get there before it's all gone. |
raid_won |
The player saves part of a lot's cash. {cash} is what they saved, {seized} what the police took. |
You saved {cash} from the raid, / but the police took {seized}. |
raid_won_all |
The player saves all of a lot's cash. {cash} is what they saved. |
You saved all {cash} at the lot, / so keep moving. |
raid_lost |
The police take all of a lot's cash. | The police took all the cash / from your used-car lot. |
helicopter |
The first helicopter comes close. |
That helicopter's here / for an aerial audit. |
tank |
The first tank comes close. |
When that tank's boosters spark, / turn off its line. |
fighter_jet |
The first fighter_jet comes close. |
That jet delivers / express repossessions. |
ufo |
The first ufo comes close. |
Meet the UFO, your / Universal Financial Officer. |
attack_bike |
The first attack_bike comes close. |
Those attack bikes / collect debts at gunpoint. |
gang |
The first gang comes close. |
Gang members. They'll ram you. / Wreck their cars for a fat payout. |
auditor |
An Auditor closes in, each one. | An auditor's on your tail. / Wreck that car for a repair. |
auditor_wrecked |
An Auditor is wrecked. | Auditor wrecked. Grab / the wrench and the cash. |
twin_rotor |
The first twin_rotor comes close. |
Shoot that transport / before it drops troops. |
gunship |
The first gunship comes close. |
Cut across that gunship's / line of fire. |
orbital |
An orbital strike is on its way. | The president has authorized / an orbital strike on you. |
escape_open |
The escape route opens. | Follow the cyan route / to the freeway exit. |
escape_run |
The car is on the last stretch to the city limit. | Floor it all the way / to the city limit. |
escape_blockade |
The escape reaches another blockade. | Follow the gold gap / through the next blockade. |
collector |
The Collector arrives. | He tears through buildings. / Hit his sides and rear. |
seizure |
The first seizure comes close. |
Wreck that truck to reclaim / the loose cash it's taking. |
getaway |
The car crosses the city limit and the run is won. It shows over the escape, without a queue: priority, cooldown, ttl and stamp do not apply. |
That's the city limit. / Their audit ends here. |
Translations¶
A language is a languages.json row. Its text is the text/<id>.json file of any mod: an
object of text keys to the text in that language. Language and text files are cosmetic.
The player picks the language under Settings > ACCESSIBILITY > LANGUAGE, and it applies
the next time the game starts (TAX_LOVE_LANGUAGE=fr overrides it). Keys a language leaves
out read in English.
{"settings.volume": "VOLUME PRINCIPAL", "cards.machine_gun.name": "MITRAILLEUSE", "neon.hello": "BONJOUR {name}"}
- The game's interface: the 580 keys in
game/data/content/base/text/en.json, with their English. Key names, the title logo and the maps' place names stay as they are. A translation keeps the English text's{name}tokens, and is up to 160 characters. - Content rows:
<kind>.<id>.<field>, for a game row or a mod's, such asdifficulties.standard.nameorenemies.warlord.warlord.boss.title. Each field keeps its limits from Content files. - A mod's own text: keys under the mod's id in its
text/en.json, read withgame.text. - Keys for rows or mods that are not loaded are kept, so one mod can translate others.
- Text everywhere may use the characters the game's fonts draw: ASCII, Latin-1, Latin Extended-A and Vietnamese. Greek, Cyrillic and CJK scripts are not drawn yet.
| Content file | Translatable fields |
|---|---|
cards.json |
description, name |
counters.json |
label, unit |
cars.json |
label, lines, requirement, short |
parts.json |
label, lines, requirement |
maps.json |
boss_goal, boss_next, label, requirement |
paints.json |
name, requirement |
safehouse.json |
label, line |
lockbox.json |
label |
enemies.json |
boss.intro, boss.title, label |
announcer.json |
lines |
difficulties.json |
name, numeral, rule, short |
modifiers.json |
description, name |
Content files¶
Each is a JSON list of rows in the mod folder, or rows passed to game.add and
game.change. A row with an existing id changes only the fields it gives; any other
row is new and its id starts with the mod id and a dot.
cards.json¶
Laundromat upgrade cards offered between waves.
New cards must be a part, specialist or gear. Each needs stats, an effect, or a row in the same mod's weapons that uses it (a gear card's own weapon, or an upgrade). A mod cannot change branch, branches, requires, tier on existing rows.
| Field | Type | Meaning |
|---|---|---|
id |
id | Card id. |
description (required) |
text, up to 160 | Rules text on the card. |
name (required) |
text, up to 40 | Title on the card. |
tier (required) |
one of evolution, gear, part, specialist |
part (a stat upgrade), gear (a weapon), specialist or evolution. New cards must be part, gear or specialist. |
branch |
text, up to 24 | The weapon family an evolution belongs to. |
branches |
list of up to 4 texts, 24 characters each | Weapon families a card counts toward. |
effect |
id of a game.effect |
Code that runs while the card is owned: the id of a game.effect. |
full |
true or false | True for full-game only cards. |
icon |
whole number, 0 to 255 | Icon number on the upgrade icon sheet (0 to 255). |
max |
whole number, 1 to 10 | Highest rank. |
min_heat |
whole number, 1 to 5 | Lowest wanted level at which it is offered. |
requires |
card id or list of up to 4 | Card id, or list of ids, that must be owned first. |
stats |
object of numbers (-1 to 1) with keys acceleration, drift, mass, nos_duration, nos_power, nos_recharge, nos_speed, speed, steering |
Per rank, a share of the base value added to a player stat: {"speed": 0.1} is +10% top speed per rank. |
weapons.json¶
Weapons, one row per gear card (the row's id is the card's). The pattern decides how the weapon aims and fires; the row sets its numbers. Every base weapon is a row. A new row on a base pattern takes every field it leaves out, except upgrades, from that pattern's base weapon, so {"id": "neon.drone", "pattern": "drone", "damage": 4} is a harder-hitting drone. See Weapon patterns.
A mod cannot change pattern on existing rows.
| Field | Type | Meaning |
|---|---|---|
id |
card id (gear) | The gear card this weapon belongs to. |
pattern (required) |
pattern name or id of a game.weapon |
How it aims and fires: a base pattern (see Weapon patterns) or the id of a game.weapon for code of its own. Cannot be changed on existing rows. |
burst |
whole number, 1 to 8 | turret: shots per burst. |
cap |
whole number, 1 to 48 | mines: most mines on the road; sentries: most sentries standing. |
charge |
number, 1 to 500 | lightning: charge gained per second of drifting, out of 100. |
color |
[r, g, b], 0 to 255 |
Tracer colour, [r, g, b]. Default gold. |
count |
whole number, 1 to 8 | drone: drones; saws: saws. |
crit_chance |
number, 0 to 1 | Chance a hit is critical, 0 to 1. Default 0.05 on a code pattern. |
crit_multiplier |
number, 1 to 5 | Damage multiplier of a critical hit. Default 2 on a code pattern. |
damage |
number, 0.1 to 1000 | Damage per hit (1 is a pistol round). |
fire |
number, 0.05 to 30 | sentries: seconds between a sentry's shots. |
flight |
number, 0.1 to 3 | mortar: seconds a shell flies. |
interval |
number, 0.05 to 30 | Seconds between shots, bursts, volleys, drops or throws. saws: before a saw can cut the same target again. Reload parts and haste shorten it. |
jump |
number, 10 to 600 | lightning: pixels each hop after the first may reach. |
life |
number, 0.1 to 60 | Seconds a burning track (fire_trail), mine or sentry lasts. |
max_rounds |
whole number, 1 to 24 | Most rounds upgrades can reach. |
mount |
sprite name | broadside: sprite drawn on each side of the car. Default the shotguns. |
radius |
number, 1 to 96 | Blast radius in pixels; saws: orbit radius; pulse: ring radius; railgun: slug width. |
range |
number, 10 to 600 | How far it reaches, in pixels (a car is about 12 long). ball: chain length. |
rounds |
whole number, 1 to 24 | Rounds per shot: pellets per side for broadside, shells per volley for mortar, rockets per burst, discs per throw, targets per zap for drone and per full charge for lightning. |
speed |
number, 40 to 1200 | Round, rocket or disc speed in pixels per second. |
spin |
number, 0.5 to 30 | saws: orbit speed in radians per second. |
splash |
number, 0 to 1000 | rockets: damage to everything else in radius. |
spool |
number, 0.05 to 10 | turret: seconds of holding a target to fire up to 1.5 times faster. Without it there is no spin-up. |
spread |
number, 0 to 360 | Width of the fan of rounds, in degrees. |
turn |
number, 0.5 to 30 | rockets: turning speed in radians per second. |
upgrades |
object of card ids to upgrades | What each upgrade card adds per rank, keyed by card id: damage, rounds, radius, count, cap, life and reach (pixels of range and jump) are added; range, charge and turn are shares (0.2 is +20%); rate is fire rate (0.15 is +15%) and spool spin-up speed. A pattern's trait set to true switches it on while the card is owned, including a trait a code mod adds to the pattern with game.trait. A patch adds cards or replaces them by id; the cards it leaves out stay. |
counters.json¶
Contract counters: the run statistics a reward's counter counts. The game feeds its own (see Counters); a mod adds a row here and feeds it from code with game.count. While a mod is missing, the save keeps its counters' progress.
A mod cannot change best, whole on existing rows.
| Field | Type | Meaning |
|---|---|---|
id |
id | Counter id. |
label (required) |
text, up to 24 | Name in contract progress: DRIFT with unit SEC reads "DRIFT 40/100 SEC". |
best |
true or false | True for a running best, such as the longest chain: it keeps each run's best and adds no lifetime total, so only "scope": "run" rewards can use it. Default false. |
unit |
text, up to 8 | Word after the numbers, like SEC. |
whole |
true or false | False keeps fractions, for counters such as seconds. Default true. |
cars.json¶
Player cars, their handling and how each unlocks.
| Field | Type | Meaning |
|---|---|---|
id |
id | Car id. |
factors (required) |
object of numbers (0.25 to 4) with keys acceleration, drift, exit_boost, grip, mass, nos_power, speed, steering |
Handling multipliers: {"speed": 1.1} is 10% faster. |
hearts (required) |
whole number, 1 to 12 | Starting hearts. |
label (required) |
text, up to 40 | Full name in the garage. |
lines (required) |
list of up to 6 texts, 40 characters each | Up to six short lines describing the car. |
short (required) |
text, up to 12 | Short name for badges. |
sprite (required) |
text, up to 48 | Body sprite: a game car (player_car, player_muscle, player_rally, player_van) or the mod's own (taxi.cab), with _paint and _invulnerable variants. |
counter |
counter id | The counters row the contract counts: one of the game's (see Counters) or a mod's. |
full |
true or false | True for full-game only content; the demo hides it. |
group |
one of COMBAT, DRIVING, HEISTS, SURVIVAL |
Contract group on the Unlocks page: DRIVING, HEISTS, SURVIVAL or COMBAT. With no unlock fields the item is open from the start. |
perk |
id of a game.perk |
The car's rule: a base perk (nos_ram, drift_nos, patrol_proof) or the id of a game.perk. |
requirement |
text, up to 160 | The contract as players read it, for example "Destroy 3 rocket tanks in one run". |
scope |
one of run, total |
total counts across all runs (the default); run needs it within one run. |
start |
card id (gear) | The gear card the car starts with. |
target |
number, 1 to 1000000000 | How much of counter unlocks it. |
parts.json¶
Garage tires, engines and chassis.
| Field | Type | Meaning |
|---|---|---|
id |
id | Part id. |
factors (required) |
object of numbers (0.25 to 4) with keys acceleration, drift, exit_boost, grip, mass, nos_power, speed, steering |
Handling multipliers, as for cars. |
label (required) |
text, up to 40 | Name in the garage. |
lines (required) |
list of up to 6 texts, 40 characters each | Up to six short lines describing the part. |
slot (required) |
one of chassis, engine, tires |
tires, engine or chassis. |
counter |
counter id | The counters row the contract counts: one of the game's (see Counters) or a mod's. |
full |
true or false | True for full-game only content; the demo hides it. |
group |
one of COMBAT, DRIVING, HEISTS, SURVIVAL |
Contract group on the Unlocks page: DRIVING, HEISTS, SURVIVAL or COMBAT. With no unlock fields the item is open from the start. |
hearts |
whole number, 1 to 12 | Hearts with this part (chassis). |
requirement |
text, up to 160 | The contract as players read it, for example "Destroy 3 rocket tanks in one run". |
scope |
one of run, total |
total counts across all runs (the default); run needs it within one run. |
target |
number, 1 to 1000000000 | How much of counter unlocks it. |
maps.json¶
The maps on the setup page: how each unlocks, and its name, sky, colours, traffic, boss and lines. A mod's new map builds on one of the game's (base) and takes its island, streets, landmark, mechanics, boss and finale, then changes what its row gives. A City map can lay an island of its own (island, land, features, landmark), and mechanics names a code mod's handlers for its objective, finale, route and damage (see Map handlers).
New maps need base. A mod cannot change base, escapes on existing rows.
| Field | Type | Meaning |
|---|---|---|
id |
id | Map id: the game's are city, shell_cay, monte_fisco and panopticon. |
label (required) |
text, up to 40 | Name on the map dial and the run's opening card. |
base |
map id | New maps: the game map it is built on. It plays on that map's streets, with its landmark, mechanics, boss and finale unless the row says otherwise. Cannot be changed on existing rows. |
boss |
text, up to 64 | City maps only: the fight after the five-star minute, in place of the Collector. The id of an enemies row with boss is fought there and then (it keeps its bar and music, and the freeway escape opens once it falls), and none opens the escape straight away. Without its own boss_next, boss_goal and final, the row gets lines that fit. On this map the boss comes only as that fight. The other maps keep their own boss and finale, which are code. |
boss_goal |
text, up to 40 | Second line of the objective panel before five stars, such as BEAT THE COLLECTOR / THEN ESCAPE. |
boss_next |
text, up to 40 | Second line of the objective panel during the five-star minute, such as THEN FACE THE COLLECTOR. |
colors |
object of [r, g, b] colours, 0 to 255 |
The tileset's colours, over the base map's: bed, clear, highway, mark, median, parking_lines, parking, planter, rim, road, shoulder. On a City map, keys left out keep the City's, and its park tree surrounds keep theirs. |
counter |
counter id | The counters row the contract counts: one of the game's (see Counters) or a mod's. |
escapes |
counter id | New maps: a mod's counters row the game adds 1 to on every escape from this map, for rewards such as the next map. Escapes still count toward escapes. |
features |
object: barrel_yards true or false; canal true or false; dealerships true or false; rails true or false; wires true or false |
City maps: true or false for each of canal (the canal row with its bridges), rails (main rail lines with trains), barrel_yards (explosive fuel-drum yards), wires (utility poles and overhead wires) and dealerships (used-car lots and their raids). The City has them all. |
final |
announcer id | The announcer line called at five stars. The game's maps have final_city, final_cay, final_fisco and final_panopticon. |
full |
true or false | True for full-game only content; the demo hides it. |
group |
one of COMBAT, DRIVING, HEISTS, SURVIVAL |
Contract group on the Unlocks page: DRIVING, HEISTS, SURVIVAL or COMBAT. With no unlock fields the item is open from the start. |
island |
object: height whole number, 4 to 12; width whole number, 3 to 12 |
City maps: the island's size in districts, {"width": 6, "height": 5}, from 3 to 12 across and 4 to 12 down. A district is a few blocks of streets; the City is 12 by 12. The run starts in the middle, and the freeway escape runs north. |
land |
object: airport whole number, 0 to 4; luxury whole number, 0 to 48; railyard whole number, 0 to 4; slum whole number, 0 to 72; suburbs whole number, 0 to 36 |
City maps: how many districts of each land use the island has: airport (a runway), railyard (a freight yard), suburbs (houses and lawns), slum (shacks and towers) and luxury (villas). Each one left out keeps the City's share for the island's size, and the rest are city blocks. They need room: four districts round the start are always city. |
landmark |
one of none, revenue_hq |
City maps: revenue_hq, the City's Revenue Service HQ, or none. The other landmarks belong to their maps' own islands. |
mechanics |
id of a game.mechanics |
The map's own code, registered with game.mechanics: events that run only on this map, its objective, its finale, a guidance route and damage rules. It runs before the base map's own mechanics. |
preview |
sprite name | A 208 by 144 sprite from the mod's sprites/ folder for the map dial. Without one the dial shows the base map's. |
requirement |
text, up to 160 | The contract as players read it, for example "Destroy 3 rocket tanks in one run". |
scope |
one of run, total |
total counts across all runs (the default); run needs it within one run. |
sky |
object: keys list of up to 8 objects, each object: ambient list of 3 numbers, 0 to 2; at number, 0 to 1; bearing number, 0 to 360; day number, 0 to 1; floor number, 0 to 64; haze number, 0 to 1; lamp number, 0 to 2; night true or false; reach number, 0 to 1000; shade list of 3 numbers, 0 to 2; strength number, 0 to 1; overcast number, 0 to 1; stages object: boss number, 0 to 1; exit number, 0 to 1; finale number, 0 to 1; five number, 0 to 1 |
Light over the run, as keyframes from the start (0) to the finale (1), each field repeating the last key's when left out: ambient (sunlit light, [r, g, b] where 1 keeps the art's colour), shade (shadow light as a share of ambient), strength (0 to 1: how much sun shadows show), bearing (degrees clockwise from east that shadows fall), floor and reach (shadow length per building floor and at most), lamp (street lamp and sign brightness), haze, day (how much a storm greys it) and night (true: the City night). stages sets the progress reached at five stars (five), the end of the minute (exit), the boss and the finale. A storm, where the base has one, stays. The City has no sky: without one a City map keeps its night. |
target |
number, 1 to 1000000000 | How much of counter unlocks it. |
traffic |
whole number, 0 to 4 | Most civilian cars on the side streets around the player at once. The City has 4 and the Panopticon, under curfew, 2. |
paints.json¶
Car paints in the garage.
New paints need rgb.
| Field | Type | Meaning |
|---|---|---|
id |
id | Paint id. |
name (required) |
text, up to 16 | Name in the paint picker. |
color |
whole number, 0 to 255 | Base paints only: palette slot. |
counter |
counter id | The counters row the contract counts: one of the game's (see Counters) or a mod's. |
full |
true or false | True for full-game only content; the demo hides it. |
group |
one of COMBAT, DRIVING, HEISTS, SURVIVAL |
Contract group on the Unlocks page: DRIVING, HEISTS, SURVIVAL or COMBAT. With no unlock fields the item is open from the start. |
requirement |
text, up to 160 | The contract as players read it, for example "Destroy 3 rocket tanks in one run". |
rgb |
[r, g, b], 0 to 255 |
Colour as [r, g, b], 0 to 255. New paints need it. |
scope |
one of run, total |
total counts across all runs (the default); run needs it within one run. |
target |
number, 1 to 1000000000 | How much of counter unlocks it. |
safehouse.json¶
Safehouse lines: permanent upgrades bought with banked cash between runs, full game only. Each level adds the line's effects to run stats and runs its effect code with the level as rank. While a mod is missing, the save keeps the levels bought on its lines.
New lines need effects or an effect. A mod cannot change lockbox on existing rows.
| Field | Type | Meaning |
|---|---|---|
id |
id | Line id. |
base (required) |
whole number, 1 to 1000000 | Price of the first level, in banked dollars. |
label (required) |
text, up to 24 | Name on the Safehouse page. |
line (required) |
text, up to 48 | What a level does, on the Safehouse page and the lockbox reveal. |
max (required) |
whole number, 1 to 20 | Highest level. |
effect |
id of a game.effect |
Code that runs in every run once the line has a level: the id of a game.effect, which gets the level as its rank. |
effects |
object of numbers (-1000 to 1000) with keys bounty, first_star_delay, interest, magnet, nos_duration, nos_recharge, payout, start_cash, upgrade_cost, wrench_bonus |
What one level adds to run stats: {"start_cash": 25} is $25 more starting cash per level. See Safehouse stats. |
growth |
number, 1 to 3 | Each level costs this much more than the one before: 1.3, the default, is 30% more. Prices round to $50, or $100 from $2,000. |
lockbox |
true or false | True for a line found in a lockbox before it goes on sale. A lockbox row with "unlocks": "safehouse" must offer it. |
lockbox.json¶
What a lockbox can contain: a weapon card, or a Safehouse line that goes on sale once found.
A mod cannot change type, unlocks on existing rows.
| Field | Type | Meaning |
|---|---|---|
id |
id | The card it unlocks, or the safehouse line for "unlocks": "safehouse". |
type (required) |
one of SAFEHOUSE, WEAPON |
WEAPON for a card, SAFEHOUSE for a Safehouse line. |
unlocks (required) |
one of card, safehouse |
card or safehouse. |
label |
text, up to 40 | Name on the reveal. Defaults to the card's or line's. |
rarity |
one of common, legendary, rare |
common, rare or legendary. |
enemies.json¶
New enemies built on an existing family, which they inherit driving, attacks, collisions and takedown rules from. A row with boss is a boss fight of its own.
| Field | Type | Meaning |
|---|---|---|
id |
id | Enemy id. |
base (required) |
one of attack_bike, gang, helicopter, officer, patrol, soldier, tank |
Family it inherits, with its driving, attacks and collisions: patrol (cop car), attack_bike (flanks and cuts in), gang (rams, with a name tag), helicopter (gun patterns from the air, drops troopers), officer or soldier (on foot, shooting; run them over), or tank (cannon and rocket boosts). |
behavior |
id of a game.enemy |
Code for it: the id of a game.enemy. |
boss |
object: intro text, up to 24; music music id; phases list of up to 4 objects, each object: at number, 0.01 to 0.99; speed number, 20 to 900; weapon object: every number, 0.3 to 60; lanes whole number, 1 to 9; range number, 20 to 400; speed number, 40 to 600; spread number, 0 to 60; title text, up to 24 |
Makes it a boss: title (up to 24 characters) on the boss bar, intro (a line centred on the bar while it arrives, before the title), music (a music row id that plays, looping, while it is alive) and phases (up to 4, from most health to least: at, the share of health left where the phase starts, plus an optional weapon and speed that replace the row's from then on). A boss arrives alone (count and max_alive don't apply) and once per run, by its spawn schedule or game.spawn, never while another boss is alive or once the map's own boss or escape has begun; its clock waits until then. It is never cleared off screen and has no floating health bar. One still up when the endgame begins fights on without its bar or music. |
gold |
whole number, 0 to 1000 | Cash paid on a kill. |
hp |
number, 1 to 100000 | Health. Base units: cop car 6, attack bike 4, gang car 18, helicopter 28, officer 4, soldier 8, tank 30. |
label |
text, up to 24 | Name tag (gang family). |
maps |
map id or list of up to 4 | The map id, or list of up to 4, where its spawn schedule sends it. Without it, every map. game.spawn can still place it anywhere. |
spawn |
object: count whole number, 1 to 6; every number, 2 to 600; heat whole number, 1 to 5; max_alive whole number, 1 to 12 |
When the director sends it: heat (lowest wanted level, default 1), every (seconds), count (per spawn, default 1), max_alive (default 4). It backs off while the player hides, like every enemy. |
speed |
number, 20 to 900 | Top speed in pixels per second. Helicopters and tanks keep their family's. |
sprite |
sprite name | Sprite to draw instead of the family's: a game sprite or the mod's own (modid.name from sprites/). |
tint |
[r, g, b], 0 to 255 |
Colour multiplied over the sprite, [r, g, b]. |
weapon |
object: every number, 0.3 to 60; lanes whole number, 1 to 9; range number, 20 to 400; speed number, 40 to 600; spread number, 0 to 60 |
A gun firing police rounds at the player: every (seconds), range (pixels, default 200), speed (default 160), lanes (rounds per shot), spread (degrees between lanes). |
announcer.json¶
The announcer's calls: the card in the top left with a portrait and two short lines. The game calls its own lines on its events (see Announcer); a mod changes what they say, how they sound and their timing. A new line plays when the enemy it names first comes close, or when code calls game.say.
A mod cannot change enemy on existing rows.
| Field | Type | Meaning |
|---|---|---|
id |
id | Line id. The game's are listed under Announcer. |
lines (required) |
list of up to 2 texts, 40 characters each | One or two lines of up to 40 characters. Some game lines fill in {cash}, {seized} or {time}. |
cooldown |
number, 0 to 600 | Seconds after it shows before it can be called again. Default 0. |
enemy |
text, up to 64 | Introduces an enemy the first time one comes close in a run: a game enemy (attack_bike, fighter_jet, gang, gunship, helicopter, officer, patrol, seizure, soldier, tank, twin_rotor, ufo) or an enemies row id. One line per enemy. An enemies row with no line of its own gets its family's. |
portrait |
portrait name | Face on the card: handler, the default, or the mod's own modid.name, drawn from its sprites name_idle and, while talking, name_talk_a and name_talk_b when they exist. Square, up to 64 pixels. |
priority |
number, 0 to 10 | Which call goes first when several wait; higher wins. A call at 3 or more skips the pause between calls and cuts in on a lower one. Default 1. |
sound |
sound name | Sound played as the card opens, instead of the radio blip: a game sound or the mod's modid.name. Use it for recorded speech. |
stamp |
true or false | True holds it until the new wanted star has landed. |
ttl |
number, 1 to 120 | Seconds it waits for its turn before it is dropped. Default 6. |
volume |
number, 0 to 1 | Volume of sound, 0 to 1, times the player's announcer volume. Default 1. |
difficulties.json¶
The difficulty ladder, lowest first. Each row states all of its rules; escaping at one difficulty unlocks the next. Mod difficulties join the top.
| Field | Type | Meaning |
|---|---|---|
id |
id | Difficulty id. Base ids: standard, more_cops, fewer_repairs, early_army, auditors, fast_cops. |
name (required) |
text, up to 24 | Name on the setup page. |
numeral (required) |
text, up to 4 | Badge numeral (base: 0 to V). |
payout (required) |
number, 0.1 to 10 | Multiplier on cash banked from a run. |
rule (required) |
text, up to 44 | One line saying what it changes. A mod difficulty shows it on the setup card. |
short (required) |
text, up to 16 | Short name for panels. |
army_shift |
whole number, 0 to 2 | Army units arrive this many stars sooner. |
auditors |
true or false | An elite Auditor hunts the player at every star from the second. |
cop_speed |
number, 0.5 to 1.6 | Police car speed limit multiplier (base 1.2 at V). |
crowd |
number, 0.5 to 3 | Police dispatch rate and crowd size multiplier (base 1.25 from I). |
effect |
id of a game.effect |
Code that runs in every run at this difficulty: the id of a game.effect (rank 1). |
fewer_repairs |
true or false | Half the wrenches, one garage per district. |
modifiers.json¶
Run modifiers: rules the player switches on for a run on the setup page, at any difficulty. Rules of several modifiers combine, and so do their payouts.
| Field | Type | Meaning |
|---|---|---|
id |
id | Modifier id. Base ids: one_heart, no_nos, double_cash. |
description (required) |
text, up to 40 | One line saying what it changes. |
name (required) |
text, up to 20 | Name on the toggle. |
payout (required) |
number, 0.1 to 10 | Multiplier on cash banked from a run: above 1 for a harder run, below 1 for an easier one. |
cash |
number, 0 to 10 | Multiplier on every dollar picked up in the run. |
crowd |
number, 0.5 to 3 | Police dispatch rate and crowd size multiplier, on top of the difficulty's. |
effect |
id of a game.effect |
Code that runs in every run with this modifier: the id of a game.effect (rank 1). |
hearts |
whole number, 1 to 12 | The car starts with this many hearts, whatever its chassis. Hull cards still add hearts. |
nos |
number, 0 to 3 | NOS refill rate multiplier. 0 means no NOS: the tank stays empty, whatever would refill it. |
start_cards |
card id or list of up to 4 | Gear card id, or list of up to four, the run starts with. Weapons still locked in lockboxes are skipped. |
balance.json¶
The game's tuning numbers, one row per system. A mod row gives only the values it changes; there are no new rows. See Balance for every value, its default and its range.
music.json¶
Soundtrack tracks. Mod tracks join the shuffle; set "enabled": false on a game track to drop it.
New tracks need a file in the mod's music/ folder.
| Field | Type | Meaning |
|---|---|---|
id |
id | Track id. |
artist (required) |
text, up to 40 | Artist on the tape player. |
title (required) |
text, up to 40 | Title on the tape player. |
album |
text, up to 40 | Album. |
attribution |
text, up to 200 | Credit line. |
boss |
true or false | True keeps the track out of the shuffle, for a boss that names it in boss.music. Any track can be boss music. |
duration |
number, 1 to 3600 | Length in seconds. Optional for mod tracks: the game measures the file. |
enabled |
true or false | False drops the track from the shuffle. |
file |
file name | The track's file in the mod's music/ folder. |
license |
text, up to 120 | License of the recording. |
source |
text, up to 200 | Where the recording comes from. |
languages.json¶
Languages on the LANGUAGE setting. A language's text is the text/<id>.json file of any mod, see Translations.
New languages need a text/<id>.json file in the mod.
| Field | Type | Meaning |
|---|---|---|
id |
id | A language code: two or three lowercase letters, with _ and a region for a variant, such as fr or pt_BR. The game's is en. Language ids have no mod prefix, so several mods can add text to one language. |
name (required) |
text, up to 24 | The language's name in itself, on the LANGUAGE setting, such as FRANCAIS. |