LEGO Racers: The structure and values of AI path files
NOTE: The following information was generally obtained by testing with the .RRB file of one racer on Royal Knights Raceway. I'm not completely sure, but the information about to follow will apply to other .RRB files in the LEGO.JAM too. Values in code tags apply to the boss racer on Royal Knights Raceway. This topic is not (yet) a full documentation of the regarding files. Tools used to gather this information are JMMB's Jam Extractor and origamyguy's Binary File Editor.
I know that it is confirmed that .RRB files are the path files for an AI, but I have not found a good documentation of these files yet. I've been working a lot with these files last week, and would be glad to share the information I gained from working with these files. I will discuss the main values/structure of an .RRB file, and explain what value does what wherever I can. Some information that follows is already known by some or many, but I felt that I should include most, if not all, information of these files here. If I missed out information, or if you know more that adds to the understanding of these files, I'd be glad to hear from you then.
To start off with, where can these files be found?
Each track folder (RACEC*R*) in the LEGO.JAM contains a certain amount of .RRB files, mostly around 15 or so (adding up to about three for each AI). Only the TEST folder doesn't contain these files, because an actual race was never meant to be held on that track. Therefore, there aren't any path files there, or checkpoints and so forth.
How are these files named?
The .RRB files are named like this: Rx_y_z.RRB, where the red letters are variable for the file name.
- x is defined as 0, 1, 2, 3, 4 or 5. These numbers represent an AI, with 1 being the boss racer, 2 being Governor Broadside/Islander/Willa the Witch/Black Knight, 3 being Rob-'n-Hood/Royal King/Blackjack Hawkins/Admiral etc. The .RRB file with 0 is not found in all racetrack folders, as this file is the path for the demo, which is King Kahuka by default.
- y is defined as F, M, S. These letters might represent the speed of an AI's path, perhaps for reference to the designated AI, where F would be fast, S would be slow, and M would be, eh, Medium? These letters however do not have any influence on the speed of the path of an AI. Changing the letter in the file name won't do much to its path speed. Velocity is defined in the .RRB file itself, and I will discuss this later on, when we get to the contents of the .RRB file.
- z is defined as 0, 1, 2 or 3. These numbers probably represent a path number. Then it would mean that every AI has a minimum of 2 paths, and a maximum of 4 paths (I've seen racers with just two .RRB files, and racers with 4 .RRB files, and ofcourse others with 3 .RRB files).
What happens when I delete or replace .RRB files from a track folder?
Nothing really happens to an AI's path, when you remove certain .RRB files. Only when the first of all paths, being Rx_y_0.RRB, is deleted, the AI will not move from its startposition. Even pushing the AI won't work, he will be stuck at his startposition. When deleting the other paths for the AI (but leaving Rx_y_0 in the folder), it will move and continue following this remaining path. Thus, removing all .RRB files means that the AI is stuck at his startposition.
Adding, or rather replacing the .RRB files with those of another track simply makes the AI follow this replaced path. For example, replacing the boss's Knightmare-Athon path with the one from Magma Moon Marathon makes the boss follow the latter path on Knightmare-Athon. This path obviously isn't aligned with the Knightmare-Athon track, so you would see the red dot on the Knightmare-Athon map 'floating' around the actual track.
How is an .RRB file structured?
Elements of an .SPB file can be found in the .RRB files as well. These elements are the startpositions and their respective rotation. However, an .RRB file has many more code lines, and only applies to a single racer, an AI. The main structure of an .RRB file is shown below. The code lines are divided in seven groups. I left out the other 681 nodes, for an obvious reason.
What are the values for in an .RRB file?
The values in an .RRB file vary from defining the startposition of an AI, to the waypoints it has to follow in a race. These values are set in integer and decimal numbers.
How is a startposition set in an .RRB file?
The floats under k_29 and k_28 are the same for all path files of an AI on a track. So the following files share the same floatvalues in a random track folder in the .JAM archive: R2_M_0.RRB, R2_M_1.RRB and R2_M_2.RRB. But the files R3_S_1.RRB and R4_S_1.RRB in that same track folder do not share the same floatvalues for k_29 and k_28, because these two files do not apply to the same racer (different startpositions).
The floats under k_29 are relatively simple to understand. These floats define the startposition of an AI, and work the same as for the player (which are defined in an .SPB file).
- The first float under k_29 is for x-positioning. This means that the horizontal position (left/right) of an AI's vehicle is set with this float.
- The second float under k_29 is for y-positioning. This means that the horizontal position (up/down) of an AI's vehicle is set with this float.
- The third and last float under k_29 is for z-positioning. This means that the vertical position of an AI's vehicle is set with this float.
If you still like to know more about (editing) the startpositions,explains most of it.
How is rotation set in an .RRB file?
The floats under k_28 are for the rotation of the AI vehicle IN its startposition. This rotation is not for setting the direction of the path it has to follow, there is no connection between startposition rotation and path direction. That means, setting the rotation for the AI vehicle under k_28 to a different value may change the direction his/her vehicle faces, but at the moment the race starts, the AI will directly face its path direction. This can be clearly observed when setting the AI vehicle in reversed position (i.e. having its facing direction 180 degrees switched). At the moment the race starts, its vehicle will switch back 180 degrees to align instantly with the direction of its path again.
All floats under k_28 range from -1 to 1. This rotation is not based on radians, as far as I know, so that means rotation of an AI vehicle works different than that of a player.
- The first two floats under k_28 are for a 3D rotation of an AI vehicle in startposition, to call it that way. This also explains why the value of this float is always (close to) absolute zero, because in all tracks, the startposition is on a leveled surface. If this float is bigger or smaller than 0, the AI vehicle will align with the surface in an angled (see image) and somewhat twisted way, but not perpendicular at absolute 1 or -1 I believe.
- The last two floats under k_28 are for horizontal rotation of an AI vehicle in startposition.
What are the k_2A, k_2B, k_2C and k_2D groups standing for?
Frankly, I have no idea what these stand for. I tried changing the values, and removing them, but nothing extraordinary happened when I ran a race with an AI having these modified groups. Removing all these groups doesn't even seem to affect the AI path in any way, and the AI races fine without any errors showing up while racing. What I do know, is that the k_2A and k_2B groups share the same structure as the k_29 and k_28 groups, something you may have noticed already. The floatvalues under k_29 and k_28 are the same for all AI path files for a single track, whereas the floatvalues of the k_2A and k_2B groups are different for all AI path files for a single track. For example, the floatvalues under k_29 and k_28 are the same in these two files (from the same track folder): R1_F_0.RRB and R1_F_0.RRB. But the floatvalues under k_2A and k_2B are different in these two files (from the same track folder). It might be that the values under k_2A and k_2B denote the finishing position of an AI racer, the opposite of its startposition.
The values under k_2C and k_2D are always an integer. But these integers are different for all AI path files for a single track as well. They might contain the race times of the AI in some way.
What are the nodes (the k_27 group)?
Nodes are waypoints for an AI to follow during a race. Going through all nodes in a single .RRB file means that the AI completed three laps (thus one race). That means, that there are about three different paths for each AI on a track (one .RRB file representing one path). The nodes are the ones that really add up to the amount of code lines in the .RRB file, because one node only represents a small distance to race on the racetrack. Therefore a lot of nodes are used to fill a complete AI path. The amount of nodes can be 682, as seen in the code lines below (directly under k_27) for an AI path on Royal Knights Raceway, but the amount can also be over 1000 (which is for Rocket Racer Run AI paths).
Below follows the structure of the nodes again. Each node consists of 10 code lines. I also put additional comments next to the nodes. These comments (subnode may not be the correct term) refer to the explanation given in the text below the code.
What happens if I remove certain nodes?
If you remove a few nodes completely, and also define the new amount of nodes in the brackets (e.g. from  to ), the game won't give any errors when the AI uses this modification to its path file. The AI will simply skip the 'missing' nodes, and will eventually not be aligned with the track anymore because of this modified path.
If you remove parts of a node, like only removing the (f16) part, it does affect the AI path. At the moment the AI reaches this node (with the changed structure), it will be stuck at this waypoint. You cannot move it by pushing his/her vehicle, because the node structure is messed up, meaning that the game doesn't know where the AI has to go next in the waypoint list.
What are the first two subnodes for?
Subnode 1 and subnode 2 contain the relative coördinates in an AI path. You have to add or subtract these numbers from the former coördinates to get the new coördinates of the racer on its path. Basically you have to calculate the position of each node as following. For the first node of the path:
- subnode 1 = (new x-coördinate) - (startposition x-coördinate)
- subnode 2 = (new y-coördinate) - (startposition y-coördinate)
- subnode 3 = (new z-coördinate) - (startposition z-coördinate)
And for all subsequent nodes:
- subnode 1 = (new x-coördinate) - (old x-coördinate)
- subnode 2 = (new y-coördinate) - (old y-coördinate)
- subnode 3 = (new z-coördinate) - (old z-coördinate)
What are the subnodes at (f8) for?
- Subnode 3 is generally set at 0 in the first nodes of an AI's path. It has to do with vertical alignment with the track. It would be best for me to explain this node with an example: When setting this subnode to 1 in, let's say, the first ten nodes, something strange happens to the AI. Because this subnode is set to 1 in these first nodes, the AI will add up to his vertical position. You could take it as a counter function; as long as this subnode is set to 1, it will increase its z-coördinate. Then the game stumbles upon a node with a 0 at subnode 3. If that happens, the counter stops, and the z-coördinate stops increasing. The AI is obviously out of place with his/her increased z-coördinate, and will appear floating over the racetrack for as long as the race continues. Setting this subnode to -1 in the first ten nodes will do the exact opposite, decreasing the z-coördinate.
The other four subnodes are the rotation stored as quaternions.
- Subnode 4 and subnode 5 appear as 0 too most of the time. When it is set as 0, the AI vehicle is perfectly aligned to the surface. Tweaking or majorly changing the value causes the vehicle to appear 3-dimensionally rotated while using its path. That means you could have the AI make a wheelie for the whole race, when having the right value for these two subnodes.
- Subnode 6 and subnode 7 are values to express the direction the AI vehicle has to face. Meaning, that in combination with modified subnodes 1 and 2, you can have the vehicle drive the 'wrong way' AND face the 'wrong way'.
- Subnode 8 and subnode 9 are still unknown to me. I've seen that the value for these two subnodes is 2.5 in every .RRB file in LEGO Racers, but do not quite understand what they are for.
What is the last subnode for?
At last, subnode 10. This has to be one of my favorite subnodes, as the speed of an AI's path is determined by this byte. The byte is an integer with a value that cannot be set negative (you can, but it will give an error), and has to be smaller than 256. The default speed of an AI to go through waypoints is about 200. If you open a random .RRB file, the bytes will mostly be integers of around 200. I've seen default values of 3, 129 and 222 at some nodes, but do not quite know why they don't match with the other bytes of around 200. Also, I couldn't find any proof (in byte values) for the slow-down at the start for Pharaoh's Mummy on Magma Moon Marathon (A.K.A. the pre-recorded AI path discussion).
When you stumble upon the first 6 integers (being: 0, 1, 2, 3, 4 and 5), something noticeable happens. I was surprised too, but as the integer comes closer to absolute zero, the speed of an AI path will go up. You know, setting the byte to 0 in all nodes of an AI's path will make the AI travel faster than a warp boost through the whole race, completing a race in probably less than a second. If you set the byte to 0 in the first ten or twenty nodes, it will travel extremely fast, up until it stumbles upon a node with the default byte integer (around 200). By that time, the AI could have already covered a quarter lap in less than a second, and from that point on it will follow the path with the default velocity.
Despite the fact that you can define the speed an AI has to pass a waypoint, it doesn't work at all times. I cannot really name or describe such instances, but just setting a different integer in a node doesn't always (but mostly) have the desired output. Therefore I take it that some parts of an AI path seem to have a hardcoded velocity.
I can already imagine the possibilities on how to make the game even harder, when all racers have an advantage of a quarter lap (caused by high-speed travelling). This high-speed travelling might distort lap times, but won't affect the positions in-race. All checkpoints are 'checked', so the race would still work with overpowered AI's.