Using Claude to decrypt Carmageddon

This is me

This is me

I used to play Carmageddon with a friend, so we decided to play it again now that the new one is coming this year.

We also tried to add new cars, and we wanted their numbers to sit in a sane range: mass, top speed, suspension, etc.

The 1997 original is the obvious reference. But there is one problem. Carmageddon stores all of that encrypted on disk. So for example CARS/BLKEAGLE.TXT is just encrypted garbage.

So at first I just asked Claude to work out the cipher, but it didn't work. We fed it encrypted files expecting frequency analysis, patterns, a simple XOR. Nothing worked.

There was a 16-byte key, an index starting at length % 16 and advancing by 7, tabs remapped to 0x9f, and a second key that kicks in as soon as a // comment appears. You don't guess that from staring at bytes. The thing is that when you ask an LLM to guess something that can only be known, it will hand you something wrong.

What worked

Found the repo dethrace, a decompilation of the game. The real code is in there. So I changed the question from "guess this" to "find this and explain it to me". So Claude located EncodeLine in src/DETHRACE/common/utility.c and translated the C logic to JavaScript.

But all attempts were bugged. It was the endianness of the key, and what settled it was a comment in utility.c:125 saying GENERAL.TXT must decrypt to 0.01. Big-endian produced that, little-endian didn't. Without a known value to check against, we'd still be picking between equally convincing variants.

Still struggling

With all 41 cars decrypted, we wrote an extractor that read fields by position: line 12 is the mass, line 15 is the gear count, etc. But the numbers came out absurd. A car with a top speed of 4 and 200 gears.

The files come in three format versions (v2, v3, v4) with different fields, so reading positionally shifts the columns in some files and not others. The worst part is that it doesn't fail. It just gives you numbers, and some of them even look reasonable. The fix was to locate each value by its comment text, which you more or less know in advance, since every line carries its // mass in tonnes, etc, and seems stable across versions.

And that's it

In general, it seems very useful in decryption to find a known value before writing the code, as that 0.01 was worth more than any amount of reasoning about endianness.

Here is the extractor in plain Node/JS.

There is also a tuner, a terminal UI to edit the car and opponent stats without hand-editing the encrypted files. It ships ready-made executables for Linux, macOS and Windows, so there is no Node to install.

And that's it 😊