RRB files

Recommended Posts


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, it 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.

k_27    // Nodes

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 appearing as integers, floating points and bytes.


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 a single racer of a track. For example, the following files share the same floats in the .JAM archive (providing they are located in the same track folder): 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 floats 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, >this tutorial 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?

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). The values under k_2A and k_2B denote the finishing position of an AI racer, the point where it crosses the finish line after three laps.

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. The integer under k_2C denotes the total race time of a racer on a given track in milliseconds.


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 refer to the explanation given in the text below the code.

k_27    // Nodes
(f16)0             //value 1
(f16)0.02734375    //value 2
(f8)0              //value 3
(f8)0              //value 4
(f8)0              //value 5
(f8)10.4375        //value 6
(f8)5.625          //value 7
(f8)2.5            //value 8
(f8)2.5            //value 9
(byte)193          //value 10

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 [682] to [672]), 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 three values for?

Values 1 and 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:

  • value 1 = (new x-coördinate) - (startposition x-coördinate)
  • value 2 = (new y-coördinate) - (startposition y-coördinate)
  • value 3 = (new z-coördinate) - (startposition z-coördinate)

And for all subsequent nodes:

  • value 1 = (new x-coördinate) - (old x-coördinate)
  • value 2 = (new y-coördinate) - (old y-coördinate)
  • value 3 = (new z-coördinate) - (old z-coördinate)

However, for the z-position (value 3) it works a little different, since it is not adressed the same amount of space as the former two values. It ranges from 0 up to 16. All values (starting) from 0 up until 8 indicate an increase of z-position and all values (starting) from 8 up until 16 indicate a decrease in z-position. The change in z-position is, like values 1 and 2, also stored relative to the previous height, but since it is limited in adressing, the maximum increase or decrease z between two nodes is:

  • |z| < 8

Also, an increase of respectively z = 1 unit and z = 5.3 units is given by (f8)(f8)1 and (f8)(f8)5.3, whereas a decrease of respectively z = 1 unit and z = 5.3 units would be stored as (f8)(f8)15 and (f8)(f8)10.7 (thus 16 - z). No change in height is denoted by 0.



The other four values are the rotation stored as quaternions. Quaternions are a number system which are an extension of the complex numbers, which on itself are an extension of the real numbers (the system that generally everyone is familiar with). I have never studied any further than complex numbers, so my knowledge of how this rotation works lacks here.

  • Values 4 and 5 appear as 0 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.
  • Values 6 and 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'.
  • Values 8 and 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 value for?

At last, value 10. You could say that the speed (or absolute velocity) of an AI is determined by this value. The byte (an 8-bits number) appears as an integer with an absolute value ranging from 0 up until 256. If you open a random .RRB file, the bytes will mostly be integers of around 200. My guess is that the bytes are the times in milliseconds assigned to each node. I could sustain or reject this if I took the time to calculate the sum of all bytes for a path and compare this with the value under k_2C (total race time in milliseconds). The values most commonly seen are around 3, 129 and 200.

If my guess is correct, then the value has a great impact on the smoothness of the path. A large distance between two nodes with a relatively small byte value causes a great positive acceleration for the car, whereas the opposite will do a negative acceleration. It is this correlation that shows that you cannot just alter coördinates and expect the racer to run a smooth as it originally was, you'd need a good recorder to get the path right (one that records both coördinates and relative time elapse). If this measuring happens on constant intervals, then the byte value can be regarded as a contstant. The question that arises is the interval time at which to measure.

An .RRB file can only hold that much information, thus you cannot create intervals so small that you'd exceed the maximum amount of nodes. Then again, it is easy to surpass the condition for the third value of the node (relative z-position) on some tracks if you measure with intervals too big. It is this issue that has kept grappigegovert from completing his RRB recorder (the GHB recorder does not have to deal with this issue as it only uses rotation and absolute coördinates for each node, with lap times defined at the start of the file). A possible solution to this is to keep record of the potential overflow of this third value and add this to the next node's third value. Does overflow occur again, pass it forward to the next node. Continue this proces until your overflow record is at 0 again (the principle of a ripple-carry adder).

Edited by RobExplorien
  • Like 8

Share this post

Link to post
Share on other sites

This... This is very well done, Rob! Particularly the speed editing at the end. I certainly look forward to the inevitable difficulty-increase mod :P


Thank you for posting this, it's very helpful. A question (not just to you, to anyone) - you say that setting the speed to 0 makes the AI travel faster than warp speed, but it's only for that node. Does this mean that, perhaps, when a Warp Boost is activated, the integer of the relevant node is modified for the player to 1 or 2? That would explain the warping between nodes rather than set distances.

Share this post

Link to post
Share on other sites

- you say that setting the speed to 0 makes the AI travel faster than warp speed, but it's only for that node.

Yes, well, actually setting the byte to 0. The high-speed only works for those complete nodes with the byte set to 0, that's correct. But I only tested it with a few nodes, and do not know what the long term effects could be of a complete race with the byte set to 0.



Does this mean that, perhaps, when a Warp Boost is activated, the integer of the relevant node is modified for the player to 1 or 2? That would explain the warping between nodes rather than set distances.

The player, as in, the AI? For the human player, I don't know how and where the warping speed is defined. But for AIs, that might be how it is programmed. Though I neither know where power-up effects are coded and how they would connect to the .RRB files, an AI using the warp may set the byte to one of these values.


But does that mean a warp boost lasts a certain amount of nodes, or a certain amount of time (seconds)?

Share this post

Link to post
Share on other sites

The number is likely time to cover a distance from one node to the next, given its behavior.

Share this post

Link to post
Share on other sites

I was actually going to ask when you were going to post your documentation today. :P


Job well done! I can't read it all right now, but I'll try to soon. It looks like you worked on this really hard!

Share this post

Link to post
Share on other sites

Wow, looks like quite a lot has happened since I last stopped by here. Good job, Rob! Well done!

Share this post

Link to post
Share on other sites

This is quite an old thread but with the help of RobExplorien's descriptions I was able to create the following image:


In the background you can see the IGCOLLID.BVB from the RACE0R1 folder. The red line is the AI path from the file R1_F_0.RRB. There were all three rounds in one file.

I used only the stating position and the first three values from each k_27 structure. x and y are short divided by 256 and z is byte divided by 16.

  • Like 4

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now