Reverse Engineering Earth 2150, Part 3: Vehicle Data
After talking to the Earth 2150 community a bit more, I hit the proverbial jackpot. I was able to get hold of the source file the PAR file was compiled from. It has the names of all of the fields, and they match the order of those in the PAR file. That means I have a lot more information than I did last time.
So far, I’ve adequately worked out meanings for types 1, 2, 3, 4, 6, and 7. Types 5 and 8 are very complex and has a lot of subtypes that I haven’t started work on yet. Type 9 is some sort of listing, and type 10 seems to be miscellaneous parameters, again still pending some research.
As I suspected, the -1 following each string is meaningless. Best guess, it’s padding to prevent buffer overflows, but I will most likely never know what the designer’s intent was. I won’t be including it in tables, but I’ll maintain its effect on the array index offsets. That means the field number will increment by 2 after each string field.
So, to make use of this information, I’ve rewritten my Python script to make use of this new information and spit out the decoded data for those six types. Maybe don’t try running it yourself; it uses a hard coded file path and is not even remotely error-tolerant.
Nonetheless, here’s what I’ve got, at least as regards type 1.
Type 1: Vehicles
There are 5 classes of vehicle:
Class | Code | Fields | Description |
---|---|---|---|
MOVEABLE | 0x0101c000 | 49 | Base class that covers anything that doesn’t fit any of the below |
SUPPLYTRANSPORTER | 0x0101c001 | 54 | Flying ammo transports |
BUILDROBOT | 0x0101c002 | 81 | Gruz and Mammoth builders |
MININGROBOT | 0x0101c004 | 60 | UCS harvesters |
SAPPERROBOT | 0x0101c008 | 59 | Mine layers |
The names are new, but I’d already worked the numbers out, more or less, without the source file.
Common fields
All Vehicle classes have the following basic fields:
# | Field | Type | Description |
---|---|---|---|
0 | classID | int | Explained above |
1 | mesh | string | Reference to a type 5 model entity |
3 | shadowType | int | Reference to one of several predefined shadow shapes |
4 | viewParamsIndex | int | Still don’t know what this is |
5 | cost | int | Money cost to build |
6 | timeOfBuild | int | Time to build in 1/20s ticks |
7 | $soundPackID | string | Reference to a type 8 sound pack containing unit sound effects |
9 | $smokeID | string | Reference to a type 5 smoke effect to emit when damaged |
11 | $killExplosionID | string | Reference to a type 5 explosion effect to use when destroyed |
13 | $destructedID | string | Reference to a type 5 wreckage entity |
15 | hp | int | Unit hit points |
16 | regenerationHP | int | HP regenerated per tick |
17 | armour | int | % kinetic damage reduction |
18 | calorificCapacity | int | How much heat can be absorbed from laser weapons before exploding |
19 | disableResist | int | Electrical HP; damaged by ion and lightning guns, disabled when 0 |
20 | storeableFlags | int | Special effects that the unit can have applied, such as cloaking |
21 | standType | int | Not completely sure what this is, I think it refers to how closely the unit sticks to the center of the tile it’s in |
22 | sightRange | int | How many tiles the unit pushes back the fog of war |
23 | $talkPackID | string | Reference to a type 8 sound pack containing unit voice responses |
25 | $shieldGeneratorID | string | Reference to a type 7 shield generator class |
27 | maxShieldUpdate | int | Maximum shield generator level, -1 for no shield generator |
28 | slot1Type | bitmask | Equipment categories that can fit in slot 1 |
29 | slot2Type | bitmask | Same for slot 2 |
30 | slot3Type | bitmask | Same for slot 3 |
31 | slot4Type | bitmask | Same for slot 4 |
32 | soilSpeed | int | How many ticks it takes the unit to move into a tile with normal terrain |
33 | roadSpeed | int | Same but for road tiles, usually faster |
34 | sandSpeed | int | Same but for sand, usually slower |
35 | bankSpeed | int | Same but for slopes |
36 | waterSpeed | int | How many ticks it takes the unit to move into coastal water tiles |
37 | deepWaterSpeed | int | Same but for deep water |
38 | airSpeed | int | Still not sure about this one. I think it’s vertical speed for aircraft |
39 | objectType | int | Reference to a movement category. There’s one for tracks and wheels, one for helicopters, one for ships, and so on |
40 | $engineSmokeID | string | Reference to a type 5 smoke effect emitted when moving |
42 | $dustID | string | Reference to a type 5 dust effect emitted when moving |
44 | $billowID | string | Reference to a type 5 wake effect emitted when moving |
46 | $standBillowID | string | Reference to a type 5 ripple effect emitted when not moving |
48 | $trackID | string | Reference to a type 5 track effect left on the ground when moving |
A few of these deserve special note. Field 3 is particularly interesting, as I would probably never have worked out that it was shadow shape just by reading the output. I’m pretty sure these are hard-coded effects inside the engine itself rather than anything defined in the parameters file.
I was utterly wrong about 4. I’m not sure what it actually does, but it’s definitely not factory building assignment.
And finally, 39 is the “movement type” field I was trying to cram into 3 before.
Looking at it, it’s kind of surprising how many of these I got right.
Supply Transporters
# | Field | Type | Description |
---|---|---|---|
50 | ammoCapacity | int | How many rounds the transport can carry per trip |
51 | animSupplyDownStart | int | Animation timing information |
52 | animSupplyDownEnd | int | Animation timing information |
53 | animSupplyUpStart | int | Animation timing information |
54 | animSupplyUpEnd | int | Animation timing information |
Not really all that much extra here. These would have been hard to work out, as they’re all the same across units, and the animation timing stuff would have made no sense at all to me.
Builders
# | Field | Type | Description |
---|---|---|---|
50 | $wallD | string | Reference to a type 4 building that describes which wall type the unit makes |
52 | $bridgeID | string | Same but for bridges |
54 | tunnelNumber | int | Not completely sure, but I think it refers to the wall texture tunnels get when dug |
55 | roadBuildTime | int | How many ticks it takes to lay down a road |
56 | flatBuildTime | int | How many ticks it takes to flatten terrain |
57 | trenchBuildTime | int | How many ticks it takes to dig a trench |
58 | tunnelBuildTime | int | How many ticks it takes to dig a tunnel |
59 | buildObjectAnimationAngle | int | Which direction the unit should face relative to a site to start building there |
60 | digNormalAnimationAngle | int | Same for the tunnel digging animation |
61 | digLowAnimationAngle | int | Same for the trench digging animation |
62 | animBuildObjectStartStart | int | Animation timing information |
63 | animBuildObjectStartEnd | int | Animation timing information |
64 | animBuildObjectWorkStart | int | Animation timing information |
65 | animBuildObjectWorkEnd | int | Animation timing information |
66 | animBuildObjectEndStart | int | Animation timing information |
67 | animBuildObjectEndEnd | int | Animation timing information |
68 | animDigNormalStartStart | int | Animation timing information |
69 | animDigNormalStartEnd | int | Animation timing information |
70 | animDigNormalWorkStart | int | Animation timing information |
71 | animDigNormalWorkEnd | int | Animation timing information |
72 | animDigNormalEndStart | int | Animation timing information |
73 | animDigNormalEndEnd | int | Animation timing information |
74 | animDigLowStartStart | int | Animation timing information |
75 | animDigLowStartEnd | int | Animation timing information |
76 | animDigLowWorkStart | int | Animation timing information |
77 | animDigLowWorkEnd | int | Animation timing information |
78 | animDigLowEndStart | int | Animation timing information |
79 | animDigLowEndEnd | int | Animation timing information |
80 | $digSmokeID | string | Reference to a type 5 smoke entity that is emitted when digging |
The type references were clear enough, but again, I’d never have worked out the animation details.
Harvesters
# | Field | Type | Description |
---|---|---|---|
50 | containersCnt | int | How many containers worth of resources the harvester can carry |
51 | ticksPerContainer | int | How many ticks it takes to mine one container |
52 | putResourceAngle | int | Direction to face when dropping off at the refinery |
53 | animHarvestStartStart | int | Animation timing information |
54 | animHarvestStartEnd | int | Animation timing information |
55 | animHarvestWorkStart | int | Animation timing information |
56 | animHarvestWorkEnd | int | Animation timing information |
57 | animHarvestEndStart | int | Animation timing information |
58 | animHarvestEndEnd | int | Animation timing information |
59 | $harvestSmokeID | string | Reference to a type 5 smoke entity emitted when mining |
Minelayers
# | Field | Type | Description |
---|---|---|---|
50 | minesLookRange | int | Not entirely sure, but I think this is how far the minelayer will move to automatically sweep mines |
51 | $mineID | string | Reference to a type 5 mine entity that’s laid on the ground |
53 | maxMinesCount | int | Number of mines carried per reload |
54 | animDownStart | int | Animation timing information |
55 | animDownEnd | int | Animation timing information |
56 | animUpStart | int | Animation timing information |
57 | animUpEnd | int | Animation timing information |
58 | $putMineSmokeID | string | Reference to a type 5 smoke entity emitted when laying mines |
Wrapping up
And that’s it. With the exception of fields 4 and 38, that’s every part of type 1 explained. More importantly, I think I have enough information now to run the process in reverse, which means I can compile a new PAR file with modified units in it. Next step will be writing that compiler, I think! But I’m not quite done yet. There are several more entity types to get through, and I’ll probably write those up tomorrow.
Posts in this series:
{% for post in site.tags[‘Reverse Engineering Earth 2150’] reversed %}
- {{post.title}}{%endfor%}