The making of Don Matrelli’s Legacy
Part III: cars and opponents
The story so far: we have broken into the assets of Grand Prix Circuit (GPC) and built new raceways. It's now the time to design the men and machines that will drive on these tracks.
Trackbuilding was a marathon, but I have good news: tweaking cars and adversaries is much easier and faster. So fast, actually, that my fellow modder Ryoma has already used these investigations to build his own GPC variant, reproducing the 1988 season truthfully.
Scuderia Yourname
Technical parameters
If you do not need other customizations, there is a quick way to build a copy of Grand Prix Circuit with tuned cars: use CyclesMod. Download the utility, open the original GPEGA.EXE, adjust the vehicle parameters and save the modified copy of the game.
This screenshot tells you everything you need to know. The readme file of the project has more details – my only regret is that it does not reveal how the meaning of the parameters was discovered.
If you want more, you can go the expert route. In case you are implementing a mod by altering the memory, e.g. working with DML.ASM, it’s good to know that the vehicle parameters are stored as a buffer of 444 bytes, located at offset 0x75F2 in the data segment. In the GPEGA.EXE created by CyclesMod, the same buffer is stored at 0x180E2 (i.e. 0x75F2 plus the 0x10AF0 offset marking the start of the data segment in the modified .EXE).
Even if you are working in assembly, you can still use CyclesMod to generate a modified .EXE and transplant the modified vehicle data out of it. Alternatively, you can work with my gpc-vehicle-editor, which exports the vehicle data as set of db directives, and shows a correct torque curve.
gpc-vehicle-edit, showing the original McLaren and its abnormal boost at 9500 rpm.
Looks matter too
In addition to the technical data, you might want to customize your cars’ appearance. Unsurprisingly, the corresponding sprites are located in the .PES datafiles. Surprisingly, a couple of them are stored in differential format: there is a “base” image, out of which the variants for the three cars are created by xor’ing a mask.
gpc-vehicle-edit.
The pictures stored in differential format are:
- the car selection carousel (file
CARSEL.PES, spritesbase,car1,car2,car3) - the pit stop overhead view (file
PITSTUFF.PES, spritesbase,car1,car2,car3)
To create your own variant of these sprites, first draw them in conventional style and then create the XOR-diff with the base image. To calculate the diff you can use this script; PhotoShop and other tools should offer this functionality natively.
The cockpit views of the cars are stored in the files CAR1.PES, CAR2.PES and CAR3.PES. The sprite names bear some resemblances to those used in Stunts, documented in this page of the Stunts Wiki.
gbox contains the overlay displayed when shifting gears. If you customize your cockpit, remember to adjust these auxiliary sprites too.
Personal notes
In making the cars for Don Matrelli’s Legacy, I tried to stay away from the usual trope about mods always delivering overpowered assets. I wanted vehicles with a personality, and “personality” is usually synonym of “weak point”. Also, looking at the current GPC world records, I was surprised to find out that Ferrari is the best car on many tracks – I had always thought that McLaren was unbeatable everywhere.
With this in mind, I decided to build three cars, each emphasizing the traits of one of the originals. I would build a 5-speed car whose top speed was even lower than Ferrari’s, but could make that up by having excellent grip and acceleration (torque values at low engine speeds). Conversely, I’d build a “über-McLaren” that could reach unheard-of speeds but was hampered by bad aerodynamics. There remained Williams, a featureless car that does not hold any world record: since its main trait was uselessness, I thought fit to build a car that would be even less attractive.
Thus decided the technical attributes, it was time to think at the lore behind the new scuderias. They should resemble real-life existing teams, but with some twists.
- The slow-but-nimble car would get colors and backstory inspired by Red Bull. But in place of an Austrian identity, it would get a Swiss one, in honor of my host country. And the result of “Switzerland + soft drink” cannot be but “Rivella”.
- The car too fast for its own good would be named “Anglo-German” and mainly resemble Mercedes.
- Finally, the pitiful team replacing Williams would be a Franco-Italian constructor named “Gastón Martini”. I’d rather avoid charges of defamation, so I deny that name and nationality of this car are in any way inspired from the laughable performances of some Italian “garagisti” of the Nineties, nor from the disappointing track record of a certain French team in recent years, nor from the current terrible season of a constructor with dark green livery1.
Creating new sprites for these cars was out of question: I am unable to draw, and the rigid contraints on size and shape of the car pictures would have made it difficult to employ the methods I had used for the tracks. What I did was to create paint jobs, taking the images of the base game and remapping the colors to build my new scuderias. It worked better than I hoped.
Compared with the tracks, my custom cars are less boundary-pushing. There are no fancy experiments like 4- or 7-speed gearboxes, and the torque and grip values stay within plausible boundaries. I only took two licenses:
- For the Anglo-German, the peak of the torque curve is above the redline. This can result in a nasty surprise if one is trying to reach top speed.
- For the Martini, I altered the tyre performance after boxing. This feature is supported by GPC but unused in the base car set: indeed, why should the starting tyres be different than those mounted during a pit stop? However, since this customization point was available, it was almost a duty to try it out. I also crafted a solid in-universe justification, revealed in the mod manual.
Opponents
If cars are simple, opponents are trivial. Here they are:
00000170 00 00 00 00 00 00 00 00 38 38 00 00 00 00 00 00 |........88......|
00000180 54 72 61 76 69 73 20 44 61 79 65 00 00 00 00 00 |Travis Daye.....|
00000190 00 00 00 00 32 37 00 00 00 00 00 00 42 72 75 6e |....27......Brun|
000001a0 6f 20 47 6f 75 72 64 6f 00 00 00 00 00 00 00 00 |o Gourdo........|
000001b0 30 31 00 00 00 00 00 00 44 6f 6e 20 4d 61 74 72 |01......Don Matr|
000001c0 65 6c 6c 69 00 00 00 00 00 00 00 00 31 32 00 00 |elli........12..|
000001d0 00 00 00 00 54 6f 6e 69 20 42 6f 72 6c 69 6e 69 |....Toni Borlini|
000001e0 00 00 00 00 00 00 00 00 34 00 00 00 00 00 00 00 |........4.......|
000001f0 56 69 74 6f 20 47 69 75 66 66 72 65 00 00 00 00 |Vito Giuffre....|
00000200 00 00 00 00 32 00 00 00 00 00 00 00 50 65 74 65 |....2.......Pete|
00000210 72 20 4b 75 72 74 7a 00 00 00 00 00 00 00 00 00 |r Kurtz.........|
00000220 36 36 00 00 00 00 00 00 43 61 6c 20 54 79 72 6f |66......Cal Tyro|
00000230 6e 65 00 00 00 00 00 00 00 00 00 00 30 35 00 00 |ne..........05..|
00000240 00 00 00 00 54 73 65 20 53 61 6b 61 6d 6f 74 6f |....Tse Sakamoto|
00000250 00 00 00 00 00 00 00 00 30 39 00 00 00 00 00 00 |........09......|
00000260 4e 69 67 65 6c 20 4c 65 76 69 6e 73 00 00 00 00 |Nigel Levins....|
00000270 00 00 00 00 39 00 36 00 34 00 33 00 32 00 31 00 |....9.6.4.3.2.1.|
Each of the 9 adversaries is defined by his car number (8 bytes) and name (20 bytes). Their data array starts from offset 0x0178 in the data segment (i.e. 0x10C68 in the modified .EXE from CyclesMod). There is no explicit “strength” attribute, but the earlier the driver appears in the array, the better he will usually perform.
You can set names as long as 19 letters, but de facto you are limited to 15, since otherwise they won’t fit in the standings.
If you change the driver’s car numbers, you might want to adjust the in-game sprites as well. Each number appears in five different sizes in file XTRACKC.PES; which size is displayed depends on the distance between you and the back of the other car. What’s worse, the numbers are xor’ed onto the back of the car, which means you have to match the car color in the sprite just to obtain a black number while racing.
To convert between this master sheet and the individual sprites I used ImageMagick (tools
montage and convert -crop).
Not much else to say here, even for what concerns my mod. Every opponent in Don Matrelli’s Legacy is inspired by a driver of the 2025 Formula One championship, and his strength is based on the real-life results between 2025 and start of 2026. The ranking is coloured by my biases: surely I would not put Sainz’s counterpart above Hamilton’s if I were to create the mod today. But it’s not fun to be perfectly objective.
Customizing the numbers was a tedious work, and seemingly not worth the effort for just a few black pixels of difference. But it turned out to be necessary: if you know who #1 and #44 are in real life, seeing these numbers on the back of your adversaries’ cars hits differently than seeing some random digits.
End of Part III
That’s all for what concerns cars and opponents. Short as promised! Even if you found the part about circuits too overwhelming, I encourage you to try your hand with what you’ve learned in this chapter.
Our exploration of Grand Prix Circuit’s assets has concluded. Note that I have not shown all of them (e.g. one could customize the road signs by editing XTRACKA.PES). Actually, it’s impressive how much of GPC is revealed by just browsing the sprites; it’s almost as if the game were just a real-time collage machine, coupled with an audio player. To paraphrase Fred Brooks: “Show me your sprites, and I won’t usually need your code, it’ll be obvious”.
Now, this would be ungenerous to DSI’s programmers: the driving model, striking a sweet spot between arcade racing and realism, is also an important part of the game. But I hope to have shown how much can an adventurous modder do with the datafiles, even if the source code of the game has not been reconstructed yet.
For what concerns the story of my mod, most of the components have been now revealed: the last part will pick up the few loose ends.