Open source July 2026
Carmageddon Extractor

Carmageddon Extractor

Decrypts the data files of Carmageddon (Stainless Games, 1997) and dumps the car stats into a readable Markdown table.

The game stores its text data (cars, opponents, races, power-ups, pedestrians) encrypted on disk. These scripts turn them back into plain text, then extract every car's mass, top speed, gearbox, suspension, geometry, wheel positions and damage zones.

The story of working out the cipher, including the endianness bug and a silent one that returned wrong numbers without ever failing, is in Using Claude to decrypt Carmageddon.

Requirements: Node 18+. No dependencies.

Install

npm install -g carmageddon-extractor

That gives you carmageddon-extract, carmageddon-pack and carmageddon-table. Or run it without installing:

npx carmageddon-extractor "D:/Games/Carmageddon" ./out

It also works as a library:

import { decryptFile, decryptLine, encryptLine } from 'carmageddon-extractor';
import { readFields, applyEdits } from 'carmageddon-extractor/fields';

Extracting

carmageddon-extract <game folder> [output-folder]

carmageddon-extract "D:/Games/Carmageddon" ./out

The game folder can be the install root or the DATA folder itself: the /CARMA/DATA tail never varies, so there is no need to type it.

The one case it will not decide for you is a Max Pack, which installs two complete games side by side (CARMA and CARSPLAT), both holding 41 cars. There it lists both and asks which one you mean, rather than silently editing the wrong game.

Output:

out/cars/*.TXT       one decrypted file per car (41 in the Max Pack)
out/OPPONENT.TXT     drivers, levels, and which car each one drives
out/GENERAL.TXT      global tuning
out/RACES.TXT ...    races, power-ups, pedestrians, part shop
out/cars.md          the full stat table

Individual steps

node decrypt.mjs <file.TXT> [output.txt]
node decrypt.mjs --dir <folder> <destination>
node table.mjs <decrypted-data-folder> [output.md]
# decrypt one file, print the first lines
node decrypt.mjs "D:/Games/Carmageddon/CARMA/DATA/GENERAL.TXT"

# decrypt one file to disk
node decrypt.mjs "D:/Games/Carmageddon/CARMA/DATA/OPPONENT.TXT" ./out/OPPONENT.TXT

# decrypt a whole folder
node decrypt.mjs --dir "D:/Games/Carmageddon/CARMA/DATA/CARS" ./out/cars

# build the table from an already-decrypted folder
node table.mjs ./out cars.md

Editing values

carmageddon-pack is the inverse: it takes the files you edited and writes them back in the game's encrypted format.

carmageddon-extract "D:/Games/Carmageddon" ./out
# ...edit ./out/cars/BLKEAGLE.TXT, change a mass, a top speed...
carmageddon-pack ./out "D:/Games/Carmageddon" ./packed

It only touches what you changed. The packer walks your edited file and the original side by side. Any line you did not modify is copied straight from the original bytes, so it is never processed and cannot be corrupted.

That matters because these files are not uniform. KEYMAP*, OPTIONS, PASS and PEDPATHS are stored entirely in plaintext, and ZGRIMM.TXT has seven lines whose first byte simply is not @ even though the rest of the file is encrypted. Rebuilding whole files from scratch would mangle all of those.

Two safety rules, both enforced:

  • Every file is verified before being written. The result is decrypted again and compared against your edited text. Any mismatch aborts that file.
  • It never writes into the game folder. Output goes elsewhere and you copy it over yourself. Back up your originals first.

You cannot add or remove lines: the game expects a fixed layout, so the packer refuses a file whose line count changed.

The cipher

The algorithm comes from the dethrace decompilation, in src/DETHRACE/common/utility.c:100-180, function EncodeLine. It cannot be guessed by trial and error, so here it is in full.

A 16-byte key is walked with an index that starts at length % 16 and advances by +7 modulo 16:

seed = len % 16
for each character:
    c = ((key[seed] ^ (c - 32)) & 0x7F) + 32     // method 1
    seed = (seed + 7) % 16

Details that will bite you if you skip them:

  • Every line begins with a plain @ and ends with a plain \r\n. Only the middle is encrypted, and the length feeding the seed is that of the content, not of the whole line. Lines without @ are already plain.
  • TAB is remapped to 0x9f before the transform and restored afterwards, since the 7-bit mask would otherwise destroy it.
  • Once a // comment starts, a second key takes over for the rest of the line. The original decides this on the fly by inspecting bytes it has already transformed, which works in one direction only: decrypting sees the plaintext // and switches, encrypting never does, because those bytes are still ciphertext when it looks. The cipher is therefore not symmetric on any line carrying a comment, which is nearly every data line in a car file. To make it reversible, measure where the comment starts on whichever side holds the plaintext and pass that index in.
  • The key words are read big-endian. Little-endian produces garbage. The check is GENERAL.TXT, which per utility.c:125 must decrypt to 0.01.
  • There are two cipher methods. Method 1 is the Carmageddon 1 one and is the default here.

What the table tells you

  • Mass in tonnes, top speed in the game's internal unit (speed at the red line in the highest gear), acceleration in 6th gear in m/s², which the original calls "engine strength".
  • Suspension give, damping, ride height, traction multiplier, friction angles, rolling resistance, minimum turning radius.
  • Geometry: bounding box, centre of mass, and the four wheel positions.
  • Damage zones: Carmageddon defines damage per impact face and, within each face, per quadrant using normalised conditions (z<0.25&x<0.25 is the front-left corner). Each zone lists which systems it can break: engine, transmission, steering, driver, individual wheels and brakes.
  • Level (1-5) from OPPONENT.TXT. It does not affect physics: it feeds the AI aggression formula (opponent.c:2678) and gates whether the car can be stolen (crush.c:1214). Level does not correlate with how good the car is: Vlad is level 1 and drives the fastest car in the game.

Car files come in three format versions (v2, v3, v4) with different fields, so the table locates each value by its comment text, never positionally. Reading them positionally silently shifts values between columns.

Getting the game

You need your own copy of Carmageddon or the Carmageddon Max Pack.

The GOG release is the handiest for this: DRM-free, and it ships with DOSBox already configured, so the data files sit right there on disk.

Disclosure: the G2A link is an affiliate link. Steam and GOG are not.

Legal

These scripts read the data files from an installation you already own. Nothing is bundled here: no game assets, no game data, only the code that reads them.

The decrypted output stays yours to keep locally. Redistributing it is another matter, since that content belongs to Stainless Games.

built and maintained by Edu Lazaro · MIT license