Welcome, Please Register or Login

Search Tags

  1. Fixing those cars that crash ValoCity
    Sections: Tutorials \ Street Legal Modding Tutorials
    Tags: Crash, Drive, Error, Fix, Java, Street, Tutorial, Valocity

    Since the start of the mods for this game (ah, the good old days of Xi) almost every player stop clicking "Go to the streets" button because of a single issue: the game crashes.

    In this tutorial i'm going to explain how to make a car safe to play on valocity, Roc races, etc, so you all can enjoy the original sense of the game. It is not a short tutorial, because the harm is huge, but when you got the idea, it takes less than 10 minutes to fix any car, so have patience, read it all, and you'll be able to hit the streets again in your favourite car, racing versus the cars you want.


    - First of all, you are going to need a program to edit the java files. I use "Edit Plus 3" but any version of it will do the job. Version 1 is on the downloads section. http://streetlegalmods.com/downloads/street-legal-racing-redline/tools/Class-Editers-

    - Then, you're going to need a grep. A grep is a tool that allows you to change a piece of text in multiple files at the same time. Since we're going to rename a lot of routes, you better get one of these: it makes the work easier, less time consuming, and free of errors, and almost all of them keep a backup just incase you write "Mazdar" instead of "Mazda". I use PowerGREP 4, but there are more like it. Windows Grep is a good free alternative.

    - In third place, we need the java pack of the game. Some authors don't release the javas they used with the mod (reasons unknown), but all those .class files you see in the "scripts" folder can be changed with any .java you rename with the same name, as long as you set it in the proper place.
    The javas were released long time ago by Activision, and you can find them in your preferred site: G.O.M. http://streetlegalmods.com/downloads/street-legal-racing-redline/tools/SLRR-221-Java-Pack-Complete


    - Any Hex editor. Just incase.

    - And finally, since we're going to edit the RPK of the car, we need the wonderful Resource Converter by Roltzy. you can find it here, in the downloads section. http://streetlegalmods.com/downloads/street-legal-racing-redline/tools/Resource-Converter


    Ok, now you have your shiny new tools, downloaded a rocket, and it crashes the game. Let's go for it.

    1: Identifying the source to apply the correct .javas.

    First of all, we need to know what car the modder used to create his mod. And with this, i mean that, more than probably, the modder took the javas of a car that was ingame, and used them as a base for his mod. We need to know what car it is. ¿How? easy.

    If the author released the .java files of his mod, they are stored in Cars\racers\nameofthecar\scripts\src. Always.

    If the .javas are there, just open the file named whateveritis_models.java with Edit plus. it will show you the models the car is using, and if it's crashing the game, more than probably it will look like this:

    The creator of this car used clearly the Duhen javas to make his mod, but didn't renamed the models, nor made it standalone, and your game crashes because it thinks "¡HEY MAN, THERE ARE MORE THAN ONE DUHEN HERE!¡WRONG!".

    Before cleaning the mess in this file, we better look for the models the modder created. Sometimes there are more than one version of a car in a mod, so we need to know how many of them are there. To do that, we'll look for the models of the car .javas. in this case, Sunstrip 1.5, 1.8, 2.0 and 2.2, and see what the modder used.

    In this case, the author (and i'm not gonna say who was, he'll instantly know) was kind enough to write "Dont use" in the cars he's not using, but in most cases you will have to look for the name of the car to know which ones are used.

    I found out the car being used for this mod is the Duhen Sunstrip 1.5 DVC, so i GET RID of the rest of the car javas and config files unused. This means i delete Duhen_Sunstrip_1_8_DVC.java, i go back a level (I'm in "scripts" folder now) and delete Duhen_Sunstrip_1_8_DVC.class, and _main_Duhen_Sunstrip_1_8_DVC.cfg, and do the same with the other two models of the original car, leaving only de 1.5, which is the one the author used for the mod.

    "ok, very instructional, but... What if the author didn't released the javas, smartie?"

    Good question. That's why we need the Hex editor ¿Remember?.
    Sice the .class files are encoded, and i don't know the code used, we will have to open the .class files with it. It will show sth like this:

    And if we scroll down a bit:

    And we found out what car he used.

    Ok, enough for the first time. Tomorrow We'll see how to clean the main .javas and rename the car, so it appears in the car list in the order you wish. If you find this useful, remember to vote on the poll ;)



    Now that we know what car(s) the modder used, we are going to start cleaning the mess. We already deleted what we don't need, so we are going to tell the program those things aren't there anymore, and that it is not what it thought, but a whole different car.

    In this case, since the car is a Honda CRX delSol, i'm going to rename the files with something more like it. Also, we'll rename the RPK and the folder so it shows this car in the list as we want it to. I have my cars ordered by brand, so the new name will be "Honda_CRX_DelSol.RPK" and "Honda_CRX_DelSol_data" for the folder. This will put it behind the Civic, but before the NSX (the list is ordered alphabetically based in the RPK names)


    Also, we'll rename the "Duhen_Sunstrip_1_5_DVC" files to something more like it. in this case it will be as simple as "CRX_DelSol". Now, our main files should be changed from this:

    To sth like this:

    (There are a lot more files on the folder, for the parts, but they've been ommited to make the idea clear, do not delete them)

    As you can see, there's the "src" folder in this car. If it isn't in the car you want to repair, now it's the time to create it. ¿What should you put inside? the main .javas of the car the modder used as a base, and you have in the Javapack. In this case they will be:


    It should look like this:

    And rename those files as the corresponding .class files, so they know what to modify:


    Now that we have the folder and the files renamed in working condition, and the source files created, we're going to create our standalone car. The first step is to open the XXXXXX_models.java file. in this case it is "CRX_DelSol_models.java": this is what the file looks like from scratch:

    And this is what it may look like once we edit it:

    As you can see, I've changed the fields so they fit my personal tastes, what means to be descriptive. You can assign the names you want, but you have to keep in mind what names you used in order to edit the rest of the files. For the MODELS line, it's important to know that you can use whatever number of fields you want, but you have to:

    1- use ALPHANUMERIC names. Numeric only names don't work
    2- Do not use special symbols

    In the next post we are going to rearrange the CRX_DelSol_VT to make the car appear in the different circumstances of the game without crashing when you enter ValoCity, Roc or the dealers.




    Ok, now we're going to take the car back to the city. The file what controls what goes in and out of the dealers, all the races and ValoCity is the XXXXXXX_VT.java, so let's open it with Edit plus.

    Underlined in red you can see the file's "name" (it's not just a name) is still the one for the original car, and the route (cars.racers.Duhen) is still aiming for the Duhen RPK. THIS is the main reason why the mods crash. Let's get everything in place:

    As before, we get rid of everything related to any car that is not the one the modder used, leaving only the code related with the Duhen 1.5, and set everything as we want it to look. We are not changing the vmd.stockQM because we still need a platform the program can recognize to create the car around it.

    And about the 0x00000006 number, we'll go into that later.

    Ok, now we have the connection stablished between the game and our car, it knows it's not one of the cars he used to know, and where to look for the right platform, now we're gonna tell the car all this.

    Let's open the main car's .java: CRX_DelSol.java

    Since we changed the name of the .javas and of the model in Step 2, we have to show the car what we have done, but, if you look down below, circled in red there are a lot of references aiming for the Duhen RPK. That means the original mod was looking for the parts in the duhen directory, and, since they are not compatible with this chassis, the car will simply appear without them every time. let's fix all this.

    Ok, that's it for today, and most of the job is done. Tomorrow we will tweak the .RPK and the routes, and the car will be roaming through ValoCity.


    Here, about the parts, you have to take notice about a thing:

    Every part has a unique id number (those numbers that look like 0x00000001) If the modder kept the original part numbers, you don't have to change them, but if he added parts, or changed those numbers, you will have to go part by part looking for the right number. The number appears in two files: the part's .cfg file and the main RPK. In the part's .cfg file it is the first number that appears on top of the file. like this

    Some mods i found had the original ID number in the cfg file, but the modder changed the part number in the RPK, so let's decode the RPK of the CRX DelSol to see what we must look for.

    To decode a RPK you must do the following:

    1 copy the RPK to the folder where you put Roltzy's Resource Converter
    2 Open Roltzy's Resource converter
    3 double click on the RPK (in the Resource converter)
    4 the tool will decode the RPK and put a copy in the same directory named "XXXXXX.RDB". you can open it with Notepad.
    5 et voila!

    This is the CRX DelSol RPK. Let's see if the F_bumper ID number is the same:

    If one of the numbers coincide, the odds are on the author of the mod kept all of them. Sometimes it doesn't work this way, and you have to look in the RPK for the right number for some parts.

    Well, now we have the right parts, the only thing left to do is to tell the RPK and the cfg files the new routes and names. For the RPK, we've changed the name of the folder, so he must know it. In notepad, go to the top of the file, press CTRL+H to use the tool "Replace", and reform the old route into the new one:

    Use "Replace them all". Then, find the old java files (Duhen_Sunstrip_1_5_DVC.class ¿Remember?), replace them with the new ones we gave to the car, and get rid of the unused cars. It should go from this:

    To sth like this:

    The lines in red are the ones i edited. The line in green is the last thing we must change in the .RPK. Since we want to make the car standalone, we have to change the alias of the model in the RPK. There are only five or six entries in the file which involve this, but i reccomend doing it one by one, since a lot of other entries may start with the same sentence ("alias Duhen_Sunstrip_1_5_DVC" and "alias Duhen" in this case), but have more content in the same line, and we only want to change the proper ones. If you don't dare to do this, you can only change the one marked in green, and leave the rest as they are.

    Ok, now we have a proper .RPK Save the changes, recode it with Roltzy's resource converter (you will have to delete the old RPK) and move it to the proper folder (cars\racers\). And let's chage the routes in the .CFG files. We'll have this nice CRX in ValoCity in no time.

    Open the Grep. I will be using PowerGrep 4, but you can use any other. Aim for the Honda_CRX_DelSol_data folder and select it. Include all files inside the folder in the search (You can use *.*) And select "Search and replace"

    We are looking for the old route, which was "DelSol_data" in this case, and we want to replace it with the new one we selected ("Honda_CRX_DelSol_data" in my case). With the changes we've made, the grep should look like this before the action:

    In this case, the author didn't even used his own route, so 0 results appeared. And so, i thought the routes must be the original ones for the Duhen car, and tried it that way.

    And there they are.

    Ok. Now we have the proper routes for the parts, the physics, etc. let's see if the car works.

    The game cranks, which is a good sign. If you've done something wrong or made a mistake, the game has en Error.log which tells you what went wrong, and where. Try the catalog, and look for all the car's parts. it should show them all. Maybe some are in the wrong place, but they must be there.

    Now let's try valoCity

    Ok, ok, the lights are wrongly scripted (and some parts too) and the driver is not seated in the proper place, but those things are not a result of the conversion. the original positions of those things are set in the Main Config and the RPK, so the modder simply didn't get them in the proper place. It's not your fault, but you can repair them. The fact is: Your car is working in ValoCity now.

    And that's it. It wasn't that hard uh? If you find this useful, vote on the poll, and enjoy the game!

  2. SLRR an iteration v2.0
    Sections: Downloads \ Street Legal Racing: Redline \ The Full Game
    Tags: Career, Mwm, Slrr, Valocity

    Slrr Iteration 2.0

    What is this?


    Names of cars in the game





    VS_Projects folder


    Further modding

    Provided as-is.
    I don't care what you do with the compilation.
    Pat the original authors of the mods included on the back.

    Blobshadow Remover:


  3. Realistic Shimutshibu Focer
    Sections: Downloads \ Street Legal Racing: Redline \ Car Mods
    Tags: Valocity, Realistic, Cars, Focer

    Dislike having your 600hp engine driving at over 230mph in the Shimutshibu Focer? then replace the Shimutshibu Focer with this

  4. Slrr Exhaustive
    Sections: Downloads \ Street Legal Racing: Redline \ The Full Game
    Tags: Career, Valocity, Tournaments, Stability, Graphics

    Slrr Exhaustive

    • -200 chassis models
    • -272 tyres
    • -2042 rims
    • -150 custom tournaments on 20 maps against racers from the Valocity ladder during career mode (random racers otherwise)
    • -232 pre-built engines available from the catalogue (any engine any car)
    • -Packed into a working(video footage provided) Slrr(all java sources provided where available, I even found the source for system classes)
    • -Responsive catalogue
    • -Properly working Valocity and dealers (custom paintjobs on dummy race cars in Valocity during career mode and custom random generated opponents during night races and in tournaments)
    • -Every racer chassis customizable with nicely aligned paintjobs and with extra parts (10 different wide chassis compatible with all 200 chassis types)
    • -Bigfoot wheels (working semi-properly with collision on the wheels)
    • -Advanced bugfixes to the Slrr.exe: (Ida .idb and Olly .udd data included)
      • -Decal projection (crashed slrr when trying to paint a car with a model with more than 32767 vertices)
      • -Flying traffic cars
      • -Lag on collision
      • -Lag on look back, and generally looking around
      • -AI racer cars could not accelerate on sideways slopes
      • -Forced resource unloading addressing memory consumption
      • -Lag on spatial boundary crossing with a car that has large textures(this is what is happening at the end of the 4th gameplay video and why it does not happen in the 5th)
    • -Reshade customized for Slrr(Resahde source code provided under the BSD 3-clause license (https://github.com/crosire/reshade/blob/master/LICENSE.md))
      • -DOF effect that does not affect the UI
      • -Velocity dependent radial blur
      • -Dynamic reflection map
      • -AmbientLight
      • -Bloom
      • -MXAO(behind particle effects)
      • -and anything that reshade can compile
    • -Variables customizable (on the fly) from in-game reshade dialog(when in customization mode under the dubious ReflectionSettings.fx):
      • -Reflection Strength overwrite
      • -Other vehicle-material properties overwrite(specular power, color, refelction color...)
      • -Part deformation strength
      • -Car deformation strength (loss of driveability)
      • -Part detachment damage(how much you have to beat a part for it to fall off)
      • -Flop disabling(doors and hood will not open on collision)
      • -(with the variables above you can make an old-NFS style indestructible car)
      • -Engine wear
      • -Tyre wear
      • -AI power slide ignore factor(how much sliding the AI ignores when deciding whether to accelerate along a spline)
      • -AI over-breaking
      • -AI over-steering
      • -(these ones below can solve a lot of lagging)
      • -Maximum texture reserved memory
      • -Maximum vertex data memory
      • -Maximum sound memory
      • -Maximum script instances
      • -Resource loadrate
      • -and others...
    • -Controls for the game(not customizable):
      • -P put the car back if it has flipped
      • -1,2,3 simulation-time manipulation
      • -O (not a zero)toggle checkpoint markers during tournaments
      • -Esc return to tournament garage during tournaments (while watching a race or to give up)
      • -ctrl+shift+F10 for reshade menu
      • -ctrl+shift+F11 to toggle reshade effects
      • -"Tune" the chassis in the garage to move the wheels(Big foot mode) the engine or to overwrite the engine sound

    In game pictures:


    Gamefootage(near-potato pc):


    All cars (and kind of a stress test):

    Download Slrr Exhaustive from Google Drive

    Technical part:

    I worked a lot to decode the data files (scx,rpk..) and I developed some proof-of-concept
    (they do not have, how should I put it, proper production code quality
    (if I would have done this at work, well let's just say code review would have been quite a shaming))
    little programs using the knowledge these can be found in the VS_Projects folder:

    • -Spl editor and map viewer (testing the concepts of RPK loading, and the spline .spl files define)
    • -Extra Part aligner (this includes putting together the car as Slrr would through slot attachments)
    • -UV editor (also, putting the car together properly so that the projected textures would line up)
    • -The map editor can load maps in POLY or PHYS editor mode which can be used to move around vertices in a map or its collision

    These programs are not made for general public use but I did not want to withhold anything
    they may come in handy for someone someday.
    The general model for the datafiles is usable the sourcecode gets problematic in the tools.
    This was done in (old)c# because well it was easier, also all the sources are provided
    (under the "Dont Be a Dick" Public License (https://www.dbad-license.org/)). xdlc00b1pxkf245zg.jpg37hd66yqrk3lgbfzg.jpg

    On this page I will provide the data file structures (as much as I found out) which was used to implement the tools (the c# source for datafile manipulation is understandable and serves as an example implementation (not all exceptions and common errors are listed here but the c# source is tested)).
    c# source for datafile manipulation

    • Scx files:
      • There are two versions that Slrr uses for storing 3D model data:
      • Scx v3 file structure (fields in order of appearance (in a valid file)):
      • ScxV3
      • {
        • char[4] Signature = "INVO"
        • int Version = 3
        • ModelDefV3[] models //as many as can be also there may
          • be an int at the end of the file that is 0
      • }
      • ModelDefV3
      • {
        • MaterialV3
        • int vertexCount
        • VertexDataV3 vertexData[vertexCount]
        • int faceCount //triangle count
        • int IndicesV3[faceCount*3]
      • }
      • MaterialV3
      • {
        • int size
        • float DiffuseColorR
        • float DiffuseColorG
        • float DiffuseColorB
        • float Opacity
        • float SpecularColorR
        • float SpecularColorG
        • float SpecularColorB
        • float SpecularColorWeight
        • float GlossinessWeight
        • int Flags
        • {
          • int flagAlphaOpacity = 0x00000001;
          • int flagDiffuseBlend = 0x00000100;
          • int flagVertexColorBlend = 0x00000002;
          • int flagLayer2VertexColorBlend = 0x00001000;
          • int flagLayer2BlendByAlpha = 0x00000040;
        • }
        • short diffuseMapIndex //Which texture corresponds to which
          • mapindex is set in the RenderRef definition part as a
          • list of texture typeIDs in a RPK file referencing the given scx file
        • short bumpMapIndex
        • short specularMapIndex
        • short reflectionMapIndex
        • short diffuseLayer2MapIndex
        • short unkownMapIndex2
        • short illuminationIndex
        • short unkownMapIndex3
        • int oneVertexSize //in the next VertexDataV3
        • int unkownInt1
        • short unkownShort1
        • short diffuseMixFirstMapChannel //Channel is the index of UV that should be used
        • short diffuseMixSecondMapChannel
        • short bumpMapChannel
        • short specularMapChanel
        • short unkownShort2
        • int unkownInt2
        • int unkownInt3
        • int unkownInt4
        • float illuminationColorR
        • float illuminationColorG
        • float illuminationColorB
        • char materialName[32]
      • }
      • VertexDataV3// the size of this part is set in the MaterialV3
      • and can differ depending on the fields defined but the order
      • of them is fixed so if an UV channel 3 should be
      • defined all the field above must be as well
      • {
        • float vertexCoordX
        • float vertexCoordY
        • float vertexCoordZ
        • float vertexNormalX
        • float vertexNormalY
        • float vertexNormalZ
        • float uVChannel1X
        • float uVChannel1Y
        • float uVChannel2X
        • float uVChannel2Y
        • byte vertexColorB
        • byte vertexColorG
        • byte vertexColorR
        • byte vertexColorA
        • int unkown1
        • int unkown2
        • float uVChannel3X
        • float uVChannel3Y
        • int unkown3
      • }
      • Scx v4 file structure (fields in order of appearance (in a valid file)):
      • ScxV4
      • {
        • char[4] Signature = "INVO"
        • int Version = 4
        • int headerEntriesCount
        • HeaderEntry headerEntries[headerEntriesCount] // the order of these
          • definitions implicitly declares the logical connection between
          • entries (a mesh can only have one material definition...)
        • byte data[] //header entries point into this
      • }
      • HeaderEntry
      • {
        • int entryType
        • {
          • FaceIndices = 5, //FaceDef
          • MaterialDef = 0, //MaterialV4
          • HardSurfaceVertexDefinition = 1, //HardSurfaceDef
          • VertexData = 4, //VertexDataV4
          • SparseBoneIndexList = 2, //BoneList
          • BoneIndexList = 3 //BoneList
        • }
        • int entryOffsetInFile
      • }
      • MaterialV4
      • {
        • int unkownZero = 0
        • int size //of block
        • int flags
        • int unkownZero2 = 0
        • int EntriesCount
        • MaterialEntry entries[EntriesCount]
      • }
      • MaterialEntry
      • {
        • ushort unknownFlag
        • ushort Type
        • byte data[DataSize]
        • //DataSize is dependant on the Type:
        • //Type == 2048 => DataSize = 32 (char[32])
        • //Type == 0 => DataSize = 4 (byte RGBA)
        • //Type == 256 => DataSize = 4 (float intensity)
        • //Type == 1536 => DataSize = 28 (MapDefinitionEntry)
        • //Type == 1280 => DataSize = 4 (int)
        • //You can also deduce semantic meaning
          • (for this I used the TypeSwaped = (ushort)((Type >> 8) | (Type << 8)))
        • //if (unknownFlag == 0 && TypeSwapped == 0)
        • // return "Diffuse Color";
        • //if (unknownFlag == 2 && TypeSwapped == 0)
        • // return "Illumination Color";
        • //if (unknownFlag == 1 && TypeSwapped == 0)
        • // return "Specular Color";
        • //if (unknownFlag == 0 && TypeSwapped == 1)
        • // return "Glossiness";
        • //if (unknownFlag == 1 && TypeSwapped == 1)
        • // return "Reflection Percent";
        • //if (unknownFlag == 2 && TypeSwapped == 1)
        • // return "Bump Percent";
        • //if (unknownFlag == 0 && TypeSwapped == 6)
        • // return "Diffuse Map";
        • //if (unknownFlag == 1 && TypeSwapped == 6)
        • // return "Diffuse Mix Second";
        • //if (unknownFlag == 2 && TypeSwapped == 6)
        • // return "Bump Map";
        • //if (unknownFlag == 3 && TypeSwapped == 6)
        • // return "Reflection Map";
        • //if (unknownFlag == 4 && TypeSwapped == 6)
        • // return "Illumination Map";
        • //if (unknownFlag == 0 && TypeSwapped == 8)
        • // return "Material Name";
      • }
      • MapDefinitionEntry
      • {
        • int textureIndex //this index is taken from the texture
          • TypeID list defined in a RPK that references the scx file
          • containing this map definition record
        • int mapChannel //UV used
        • int TillingFlags//3=UTileVTile 0=UMirrorVMirror
        • float TillingU
        • float TillingV
        • float OffsetU
        • float OffsetV
        • //if the next entry is a float intensity MaterailEntry it is the
        • weight of this Map (like reflection strength)
      • }
      • FaceDef
      • {
        • int type
        • int size //of block
        • int numOfShorts
        • ushort indices[numOfShorts]//I must point out that these are ushorts
          • meaning if there are more than 0xffff (65535) vertices in a given
          • vertexDataV4 indices can overflow which in turn
          • can lead to crashes because of the extreme triangles
          • well actually slrr even used these as shorts when projecting
          • decals onto parts (on collision or by painting) so there could only
          • be 0xffff/2 vertices in a mesh (a model is made out of meshes)
          • technically:
          • 004F2DA1 (offset in Slrr.exe): two loops looping through all indices
          • and hence all vertices this can calculate bad pointers...
          • the loop checks a triangle (3 offsets are calculated but MOVSX is
          • used to load EDI which is "singextend" meaning it is cast to a short
          • from a ushort.... this is very bad EDI can move backwards
          • (even before the base pointer) in the buffer if the index is greater
          • than MAX_USHORT/2 which can happen ... that's not that many
          • vertices, all 6 (3 in each loop) MOVSX instructions
          • should be MOVZX (zero extend))
      • }
      • VertexDataV4
      • {
        • int type
        • int size //of block
        • int numberOfVertices//will be indexed with ushorts in FaceDef
          • so it should not be > 0xffff
        • int vertexType//flags declaring which fields are defined in the VertexData
        • //PossibleFeatures: (in order of possible appearance)
        • //Position = 0x1, float[3] XYZ floats
        • //BoneWeightNumIs0 = 0x2, 0 weight-float written
          • (one is implicit 1-Sum(WrittenWeights) = 1)
        • //BoneWeightNumIs1 = 0x4, 1 weight-float written
          • (one is implicit 1-Sum(WrittenWeights))
        • //BoneWeightNumIs2 = 0x8, 2 weight-floats written
          • (one is implicit 1-Sum(WrittenWeights))
        • //BoneWeightNumIs3 = 0x10, 3 weight-floats written
          • (one is implicit 1-Sum(WrittenWeights))
        • //BoneIndRef = 0x20, byte[4] (four indices to the BoneIndexList
          • (from the BoneList entry) defined before the current VertexDataV4)
        • //Normal = 0x40, float[3] XYZ floats
        • //VertexIllumination = 0x80, byte[4] RGBA
        • //VertexColor = 0x100, byte[4] RGBA
        • //UV1 = 0x200, float[2] UV
        • //UV2 = 0x400, float[2] UV
        • //UV3 = 0x800, float[2] UV
        • //BumpMapNormal = 0x40000, float[3] XYZ floats
        • byte vertexData[(size - 16)] //vertex data defined in accordance
          • with the vertexType
      • }
      • HardSurfaceDef //if this entry is present the current mesh is a
        • hard surface mesh meaning there won"t be any bone
        • references in the vertexDatas
      • {
        • int type
        • int size
        • int unkownInt = 0
      • }
      • BoneList
      • {
        • int type
        • int size
        • int unkownInt = 0
        • int BoneIndexList[((size - (3 * 4)) / 4)]
      • }
    • Rpk files:
    • These files are used to define the relations between other data files
    • (telling a Part script which cfg to use and which scx to use with which textures...)
    • Rpk
    • {
      • Header header
      • ExternalReference extRefs[header.externalReferencesCount]
      • EntriesHeader entriesHeader[]
      • ResEntry resEntries[entriesHeader.entriesCount]
      • byte rsdData[]
    • }
    • Header
    • {
      • char signature[4] = "RPAK"
      • int version512 = 512
      • int externalReferencesCount
      • int externalReferencesUnkownZero = 0
    • }
    • ExternalReference
    • {
      • short unkownIndexZero = 0
      • short indexOfReference
      • char referenceString[60] //padded with 0-s (at the end)
    • }
    • EntriesHeader
    • {
      • int entriesSize//resEntries size in bytes
      • int entriesCount
      • int entriesType1Count // number of entries with typeOfEntry == 1
      • int entriesNonType1Count
    • }
    • ResEntry
    • {
      • int superID
      • int typeID// it is called Type ID because it only needs to be unique
        • in combination with the value of typeOfEntry
      • byte typeOfEntry
      • byte additionalType
      • float isParentCompatible
      • int fileOffsetOfRSD
      • int RSDLength
      • byte aliasLength
      • char alias[aliasLength] //despite the length defined this must
        • be zeroterminated (size includes the zero)
      • (//optional
      • float floatBounds[12]// it is present if additionalType & 1 != 0 this
        • is used in the spatial data structure used to define maps
      • )
    • }
    • RSDEntry
    • {
      • InnerRsdEntry innerEntries[]//as many as the corresponding RSDLength can hold
    • }
    • InnerRsdEntry can be one of; ICFGInnerEntry, XCFGInnerEntry,
    • RSDInnerEntry, StringInnerEntry, EXTPInnerEntry, NamedDataArray,
    • InnerPolyEntry, InnerPhysEntry
    • ICFGInnerEntry //Internal cfg entry: a cfg file defined directly in the rpk
    • {
      • char signature[4] = "ICFG"
      • int lengthOfData
      • char cfgData[lengthOfData]// \0 delimited list of strings (2 strings observed)
        • defining a common cfg with a key
    • }
    • XCFGInnerEntry //reference cfg
    • {
      • char signature[4] = "XCFG"
      • int lengthOfData
      • char cfgData[lengthOfData]// \0 delimited list of strings the first one
        • is usually empty the second one is a key, a whitespace and
        • than a file path relative to the slrr root directory to a cfg file
    • }
    • RSDInnerEntry
    • {
      • char signature[4] = "RSD\0"
      • int lengthOfData
      • char stringData[lengthOfData]// string data used mainly to
        • define map "entry points" //expect NamedDatas and the
        • spatial structure definition of a map (as in track not as in picture)
    • }
    • StringInnerEntry
    • {
      • char stringData[] //as much as the current RSD entry can
        • hold (ResEntry.RSDLength (or as much as is left of it))
    • }
    • EXTPInnerEntry
    • {
      • char signature[4] = "EXTP"
      • int lengthOfData = 4
      • int data//only 3 observed it is also the number of the root
        • NamedDataArrays defined but that can be coincidence
    • }
    • NamedDataArray
    • {
      • char signature[4] = "\0\0\0\0"
      • int numOfNamedDatas
      • NamedData namedDatas[numOfNamedDatas]//these represent the
        • spatial tree data structure (not a BSP, some axis aligned thing
        • not exactly an octree but definitely some bounding volume hierarchy)
    • }
    • NamedData
    • {
      • int TypeID
      • int SuperID
      • byte typeOfEntry
      • byte additionalType
      • float isParentCompatible
      • int offset//in file, references NamedDataArray, InnerPolyEntry
        • or InnerPhysEntry entries not always just one but uniquely;
        • only one NamedData references a given array or poly or phys
      • int sizeAtOffset
      • byte nameLength
      • char name[nameLength]//just as with the RES entries
      • float boundingBoxX//in range -50000 .. 50000 positioning the centre of the box
      • float boundingBoxY//in range -50000 .. 50000
      • float boundingBoxZ//in range -50000 .. 50000
      • float boundingBoxHalfWidthX//in range 0 .. 50000 generally small values
      • float boundingBoxHalfWidthY//in range 0 .. 50000 generally small values
      • float boundingBoxHalfWidthZ//in range 0 .. 50000 generally small values
      • float unkownData7// only 0 seen
      • float unkownData8// only 0 seen
      • float unkownData9// only 0 seen
      • float unkownData10// only 0 seen
      • float unkownData11// only 0 seen
      • float unkownData12// only 0 seen
    • }
    • InnerPolyEntry
    • {
      • char signature[4] = "POLY"
      • int size
      • int unkownCount1
      • int meshCount
      • Mesh meshes[meshCount]
    • }
    • Mesh
    • {
      • int textureIndex
      • int verticesCount
      • int triangleCount
      • VertexData vertexData[verticesCount]
      • int Indices[triangleCount*3]
    • }
    • VertexData
    • {
      • float coordX
      • float coordY
      • float coordZ
      • float normalX
      • float normalY
      • float normalZ
      • byte colorR
      • byte colorG
      • byte colorB
      • byte colorA
      • byte illuminationR
      • byte illuminationG
      • byte illuminationB
      • byte illuminationA
      • float uVChannel1U
      • float uVChannel1V
      • float uVChannel2U
      • float uVChannel2V
      • float uVChannel3U
      • float uVChannel3V
    • }
    • InnerPhysEntry
    • {
      • char signature[4] = "PHYS"
      • int size
      • int indexChunkCount
      • IndexChunk indexChunks[indexChunkCount]
      • int vertexChunkCount
      • VertexChunk vertexChunks[vertexChunkCount]
    • }
    • IndexChunk
    • {
      • int unkownInt1//probably the material...
      • int triIndices[3]
      • float normalX
      • float normalY
      • float normalZ
    • }
    • VertexChunk
    • {
      • float vertexX
      • float vertexY
      • float vertexZ
    • }
    • Class files:
    • The compiled script files of slrr this uses a custom java implementation it
    • was developed with Flex(,Bison) ... if someone wants a challenge
    • (to investigate the saved AST)
    • I only figured out the bare minimum that is needed to change the
    • rpk references, class and package names in the .class files without .java sources
    • Class
    • {
      • TUFA definedClasses[]//sequentially
    • }
    • TUFA
    • {
      • char signature[4] = "TUFA"
      • int unkownData1
      • int unkownData2
      • SignaturedSizedScriptEntry entries[]//as many as can be till the next TUFA
        • entry, can be SignaturedSizedScriptEntry or CONSEntry
    • }
    • SignaturedSizedScriptEntry
    • {
      • char signature[4]
      • int size;
      • byte data[size]
    • }
    • CONSEntry
    • {
      • char signature[4] = "CONS"
      • int size;
      • int entriesCount
      • ConstantEntry entries[entriesCount] //can be ConstantEntry, NameConstantEntry
        • or RpkRefConstant, the full class name(including the package) is the first
        • NameConstantEntry the full parent class name is the second
    • }
    • ConstantEntry
    • {
      • int ID
      • byte[] data// size is determined by the ID:
        • //ID == 0 => size = (the first int in data)+4
        • //ID == 4 => size = 4
        • //ID == 7 or 3 or 5 => size = 8
        • //data is generally an int[] referencing other ConstantEntries by their indices
        • in the given constant table if flatted out it will give a function reference or other string
    • }
    • NameConstantEntry
    • {
      • int ID = 0
      • int stringLength
      • char name[stringLength]
    • }
    • RpkRefConstant
    • {
      • int ID = 3
      • int RPKnameIndexInConstantTable//the index of a NameConstantEntry
        • in the current CONS that will be the rpk referenced (the file path)
      • int TypeIdInRPK
    • }

    Other assorted info about Slrr:

    • -In the cfgs for vehicles and parts stockpart 0x00000001 line means that when creating a dummy model try and attach the part with typeID 0x00000001 (this is used when creating the cars roaming the city)
      • -creating a dummy car:
      • -dummycar = new GameRef();
      • -dummycar.create_native( map, new GameRef(dummyID), "0,-10000,0,0,0,0", "dummycar" );
      • -// here stockpart references will be attached
    • -In the cfgs for vehicles and parts the texture 0x00000001 line means that the texture 0x00000001 (which should be in the textureID list of the corresponding renderRef definition) will be replaced when painting is applied (or the setTexture method) this can be used to create parts with paintable reflection or illumination textures which is quite cool.
    • -Slrr manages RenderRefs competently but scripts are difficult for it this is the reason why in the demonstration "modded almost to hell" version of Slrr I created all the RenderRef lookup tables(to delay the loading of the corresponding classes); once a script is loaded (meaning an instance of one of the defined classes is created) it can not be unloaded and this is why slrr will always crash eventually; it is a 32bit application so it can only address <4Gb memory which will easily run out because every part has a unique class, of course as demonstrated in the videos this can be pushed out significantly (using the renderRef lookups), and this is why all the ExtraParts use the same script.
    • -The silent crashes (ones that do not produce a line in the error.log) are (if you can rule out the obvious missing resource thing and class redefinition (which can be easily checked using the file type model)) almost always caused by the GC freeing up a script instance from under another script-thread, multi threading is very dangerous in Slrr (Miran's added little camera icon to the navigator (which is updated from a thread created by the Track class) was a frequent cause of crashes).
    • -The game uses standard fixed function pipeline directx9
    • -The .spl file spline row format (%LF is float %d is int) is:
      • -(%lf %lf %lf) (%lf %lf %lf) %lf %lf %d %lf %lf %d:
      • -(pos XYZ), (normal XYZ), splineWidth, targetVelocity, I do not know the rest
      • -the two ints are used as bools the list of first two vectors define a closed cubic Hermite spline.
    • -Slrr can not load more than 256 RPKs and there are at least 5 reserved slots that get filled by the exe itself and not by loading a library this modded version loads 248 (I think), and that is pretty much the maximum possible.

    All of the above and everything linked is provided as-is, feel free to extend but you know dont be a dick.


Several comma-separated tags will be considered as logical AND between them. You can also use semicolon for logical OR. AND has a priority over OR and you cannot use parentheses for logical grouping. Asterisk (*) within a tag will be regarded as a mask for "any string".