Skip to content

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

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.

game.change('cars', 'van', {hearts = 8})

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.perk('neon.battery', {
  nos_start = function(s) game.heal(s, 0.5) end,
  contact_proof = true,
})

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.

game.on('wrecked', function(s) game.log('run over at', s.time) end)

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.shoot(s, e, game.angle(e, s.player), 180, 3, 10)

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.

local e = game.target(s, w.stats.range)
if e then game.fire(s, w, game.angle(s.player, e)) end

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).

if game.map(s) == 'neon.night' then game.cash(s, 50) end

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.

local left, top, right, bottom = game.island(s)
local x, y = game.street(s, right - 600, top + 600)

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.

for _, id in ipairs(game.modifiers(s)) do if id == 'one_heart' then game.cash(s, 100) end end

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.sound(s, 'neon.zap', 0.4)

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.

game.enemy('neon.van', {
  death = function(s, e) game.count(s, 'neon.vans_wrecked') end,
})

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.

if game.setting('show_panel') then d.text('HELLO', 8, 150) end

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.

d.text(game.text('dashboard.speed', {kmh = math.floor(s.player.speed)}), 8, 150)

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.

[{"id": "fr", "name": "FRANÇAIS"}]
{"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 as difficulties.standard.name or enemies.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 with game.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.