Adding multiple new stations and the robo_data_slot parameter

  • I have a situation where I need more robos than the game allows (which I believe is a max of 8 - I can't recall the exact number, but I do remember the game crashing in the past if I added too many). I'd like to have the host stations of a couple of factions change forms depending on the level.

    My approach was to define the host station in the level itself and have it take a slot that wasn't being used by something else (I'm not using the Turantul I or Target Host Station so those would be good picks for removal).

    However, on closer inspection of the host stations in the robos.scr file, I noticed that the black sect and resistance station shares slot 0, and the Turantul I and Target station share slot 3, so now I'm a bit confused on what the parameter is for.

    I also had the thought of just writing over an already existing robo in the LDF file (e.g. making a new_vehicle 58) but I ran into issues where not all of my changes showed up correctly. It seemed to be a mixture of what I wrote and another station that wasn't even the one I was writing over.

    My questions are basically:

    - How many stations does the game support?

    - Does each station need a unique robo_data_slot parameter, and if not, what does it do?

    - Is there a better way to add more stations than the game allows than adding them in the ldf file for that level only? There's a certain group that will show up in multiple levels, but I also have a couple of factions that will have a different variant between levels.

    Thanks.

  • I'm sorry about the delayed reply. I'm currently on vacation and haven't been checking the internet for the time being. I will try to answer the questions in order.

    - How many stations does the game support?

    The maximum number of supported host stations in a level (via *.LDF file) is 8. Although I don't remember if there was also the maximum number of unique Robo type vehicles that can be parsed in the game (via *.SCR file) at runtime. I'm curious if this is what you are referring to.

    Regarding the level definition file parsing, this is a hardcoded limit that is present in the original game engine by design, considering the average computation power of the hardware at the time of game's release and since fully autonomous AI host stations are rather calculation-intensive.

    Since this is a hardcoded variable, the only way to circumvent this limit is through disassembly and reverse engineering of the game executable file. If necessary, I can personally look into this topic later.

    - Does each station need a unique robo_data_slot parameter, and if not, what does it do?

    To my knowledge, robo_data_slot parameter is an obsolete keyword that does not have any special function in the final version of the game.

    I presume it was initially designed to control the allocation of the total memory sizes for the Robo extension arrays, but apparently this feature is deprecated and therefore has no effect in the data scripts. So I believe it is safe to ignore this parameter for now.

    (If anyone has any extra information on this topic, feel free to share them here.)

    - Is there a better way to add more stations than the game allows than adding them in the ldf file for that level only? There's a certain group that will show up in multiple levels, but I also have a couple of factions that will have a different variant between levels.

    As mentioned earlier, the standard 8 maximum Robo limit inside the level definition file cannot be overridden normally. However, in the case of parsing unique Robo variant types (again, assuming there is a limit for this), I believe it may be possible to load separate Robo data from different script files based on the pre-processor directives used in the individual level files.

    This can be accomplished by saving extra Robo data definitions into a completely new standalone script file (e.g. Robo2.scr), and then create a new dedicated Startup file (e.g. Startup3.scr) that loads this new data script file accordingly inside the level definition files. The same method is generally applicable for other normal vehicles and weapons as well.

  • Thanks for your reply. I actually was asking about the number of robos that can be stored in a script, since I recall hitting a limit there as well (the game would crash when running the .exe). It's good to know the data_slot parameter doesn't play into it.

    Since the stations I want to make are one-offs, I'll probably change them on a level-by-level basis as I originally intended, but I'll keep your suggestion about making a new startup script in mind. That never occurs to me for some reason.

  • I was inspecting binaries today and noticed something. If I'm not mistaken, the maximum number of Robo definitions in scripts should be 16. This means the two extra Robo files containing the multiplayer variants of host stations (inetrobo.scr and net_robo.scr) will most likely count towards the total limit.

    Out of curiosity, have you tried removing these two files (assuming that they are present and not required for your mod) to check if it will allow adding more Robos into the original game engine without crashing?

  • That's an interesting suggestion. I have not but I'll give it a shot when I finish the rest of the designs. I suppose there's really no reason for the net robos to be in the game. I'll follow up later on this.

  • Thanks, although I have not investigated it in detail yet, I presume this could be an universal limit constant that takes all available parsed scripts from the default data scripts directory into account, which means it could potentially override the above method I suggested earlier about having separate Robo and Startup files.

    It is also worth mentioning that while OpenUA does have an increased maximum Robo limit in the level definition files (more than 8; but it did not pass the integrity and performance test yet, so this 'feature' should be considered experimental), I have not checked if it also supports an increased maximum limit for unique Robo types in the script files.

  • This appears to be a more subtle issue than I remember.

    I first tried setting all of the robo_data_slot parameters to 0 for every robo, and the game loaded fine. However I noticed that after doing so, the game ignored the robo camera that I set up on the Sulgogar Queen (which does not normally have one). After resetting the data_slot parameter to its usual value of 5, the camera returned. So it appears that the parameter has *some* function.

    I then tried adding new robos one by one (Turantul 3, 4, 5, ...) and got up to 14 with the game still loading (which would make around 18 total robos in that script) and also tried it with/without a modified net_ypa that didn't call the network scripts (instead calling the single player scripts) and the game still runs. I did not edit the actual net_robos script to remove the ones defined there.

    Just for reference, I'm usually starting the game from the Ua_xp.exe, but vanilla UA also loads fine.

    I'll update further if I manage to break it. ¯\_(ツ)_/¯

  • Interesting. After reading your post I have investigated a little further on this topic and so far I have noticed the following.

    About the 16 integer limit I mentioned earlier, it appears to be used in some kind of a modulo operation (i.e. 'variable' % 16). Although nothing is certain yet, for an array starting from 0 it could potentially allow some values up to 15. But what values?

    There is also a presence of another pointer reference which seems to take a variable that employs the above math and applies to what appears to be a set of principal diagonal of an identity matrix used for calculating 3D rotation matrix (i.e. m11/m22/m33).

    If we take some liberty and assume these matrix elements are used for calculating the orientations of Robo viewer/camera, then it may have some indirect effects on determining these data slot extensions. I should test this inside the game scripts directly.

  • Quick Update: I cannot seem to replicate the issue with Robo viewer camera when robo_data_slot value is set to 0. I have tried the following options:

    • Change all robo_data_slot values of all standard host stations in the default Robo.SCR file to 0.
    • Change all robo_data_slot values of all standard host stations inside a level definition file to 0 via modify_vehicle keyword.
    • Added new custom host stations in the default Robo.SCR file and changed all their robo_data_slot values to 0.
    • Added new custom host stations inside a level definition file with their robo_data_slot values set at 0 via new_vehicle keyword.
    • Created new custom Robo data files, copied all standard host stations from the Robo.SCR file, and set all rbo_data_slot values to 0.
    • Created new custom Robo data files, added new custom host station definitions there, and set all robo_data_slot values to 0.

    In all cases above, the Robo viewer cameras worked normally as per definitions. Perhaps there are something else I might be missing with my methods?

    ---

    EDIT: After additional experiments, I think I may have found some answers. But it is still not perfectly clear. I will explain them below.

    Apparently, the dividend variable for the modulo operation referenced in my earlier post was a pointer variable storing the vehicle ID numbers, which means that the game parses the vehicle IDs of Robo type entities into account, take the modulus of 16, and store the resultant remainder values for certain mathematical/algorithmic operations.

    In my experiment, changing robo_data_slot values did not seem to yield any difference in the test results. However, I noticed that when there are multiple host stations with vehicle ID numbers that result in congruent modulo 16 from the above modulo operation (e.g. 168 % 16 and 184 % 16), it appears to 'overwrite' (potential buffer overflow?) the Robo camera viewer data of the other host stations that also belong to congruent modulo 16.

    Although such instances appear to overwrite the camera data of the host stations, the actual host station vehicle IDs themselves in levels are the same vehicle numbers that are assigned inside the level definition files, and therefore remain unchanged. Also, the overwritten camera data seem to always originate from the vehicle IDs with higher numbers (e.g. Robo vehicle 200 Viewer data will overwrite the Robo vehicle 184 or 168 Viewer data).

    The standard host station vehicle number IDs in the original Robo data files were assigned in number orders that clearly avoid this condition from triggering which is most likely intended. I cannot confirm whether this behaviour is fully intentional and left out on purpose or simply a potential oversight legacy from the deprecated robo_data_slot routine yet, but it is still quite interesting nonetheless.

    Here is a list of the original single-player mode Robo vehicle number IDs and their operations so far:

    More information pending.

  • Wow. I did not know the vehicle numbering in UA was this nuanced. I guess it makes sense though, as 132 is a big leap away from 62, so perhaps it was not an arbitrary choice.

    There is also the viewangle parameter in the LDF which controls the in-plane orientation of the camera, so the matrix elements might be for something else.

  • Indeed, apparently this algorithm is determined by the model keyword taking the robo string as the argument value, and therefore applies to all host stations (with their own unique Robo Extension arrays).

    The detailed mechanism appears to first calculate and store the remainder values from the modulo operation from the vehicle ID numbers, and then assign the values as labels into the allocated memory of the Robo extension arrays of each Robo definition.

    At this point, I'm confident that this is an old part of the legacy protocol when the robo_data_slot was directly employed to define these behaviours, and so originally there was a support for maximum 16 functional host stations parsed from a single .SCR file; at least in theory.

    Also as you mentioned, the Robo Viewangle parameter in an .LDF file computes normalised eigenvectors for Y-axis rotation (yaw angle) in 3D rotation matrix transformations of the Robo Viewer. It is defined in degrees instead radians which is widely employed in the majority of the UA engine scripts (viewangle * pi / 180).

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!