Race construction questions

Hi guys!

Just going through moving STC to the new setup for the races, just had a couple of questions come up while going through it…

*For \scripts\races\ {race name} \props\default.lua:

  1. We had the hyperspace FX and audio blank in the original race.lua and had FTL handled by a script. Is this still ok to have blank?
  2. As we had previously used research branches to divide content between eras (ENT/TOS/TMP/TNG) there was more than one mothership, carrier and scout per race. Would leaving these def_ fields blank unduly affect the AI? Or can we define multiple ships which can fill the role? What relationship do the ships listed in crate_locate.lua have with these defs?

*For \scripts\races\ {race name} \scripts\ai_build.lua:

  1. Would a check for a research item completed by the starting fleet selection be detected here so as to set the kClass values depending on starting fleet choice? Or would we have to somehow loop the check and constantly recheck the kClass values as the game progressed?

*For \scripts\races\ {race name} \scripts\crate_ships.lua:

  1. Is this essentially replacing classdef.lua? I see that classdef.lua is still in the update *.big files though.
  2. What is the “prob” value? A build probability? One for the entire classification and one for the ship class?
1 Like

I’m going to write up a guide/info-dump this afternoon for much of this, I think it’ll be fairly clear. Stay tuned!


Thanks mate :slight_smile:

First and foremost, let me state that when this work was being done, we didn’t ‘rethink’ most of the systems connected to Race. We simply attempted to reach parity on behavior/features with the new, more modular system. Given the time (which we haven’t got right now due to larger demands) - I think we’re burn most of this down, and do it WAY better now that everything is discovery/data driven and modular. Indeed, that could happen before we are done. AI, in particular, is capable of insane stuff with some of the new systems (many you aren’t seeing yet) - and a new AI would benefit everyone.

So, that said, some questions have an answer of ‘I dunno’ - because I put it back together, I didn’t explicitly retrace every single script to understand it in a larger context (yet).

Also, excuse my abuse of terminology here, I don’t want to use any indicators from that IP - we don’t take part in making Mods with IP we don’t own. My advice is generic by design.

Should be, yes. Generally how stuff used to work, it still does - the data has simply been relocated.

Here’s one I am not sure about. I’d have to back-trace into the scripts/AI to see how those are handled. I hate that terrible crate code, so don’t even get me started on that. :wink: However, it seems like the def_ fields are used for no-rush awareness, etc… And nothing else? Since the code used to define the no-rush list isn’t multi-element aware (SobGroup_FillShipsByType) - you could add a string parse there to split it into a loop:

hgn_ms1,hgn_ms2 - split on the “,” (fairly easy - google it if need be), then call the sob group fill/append for each. Viola - now you can specify more than one ship for any of those. I’ll look into making that call (SG_FSBT) happy with multi-element strings.

BUT! Let me suggest something… because I know ‘the future’ :wink:

Was the need for era-research driven by Race limits? You most likely want to rebuild your races like this:

  • Human (era 1)
  • Human (era 2)
  • Alien (era 1)
  • etc

This will give you a ton more flexibility to make large sweeping adjustments… The only real downside is that you may consider loosing that choice post-game-launch a negative. And that may be. But the win is massive all around:

  • IF we add per-user starting fleet selection to Game setup (as an option), you’ll want those fleets defined by Era (I assume).
  • IF we add per-slot filters (must be human, can’t be 3rd era, etc) - you’ll need them broken down already.

Just consider a world where both of these IFs are true:

You’d have GR that (optionally) enforce player count and balance, but give tactical control over initial fleet… So now instead of just basics at start for balance you can do stuff like:

  • 3 players only - the starting fleets of the first 2 (human only) players are 10 units each, player 3 (alien, from the future) is 15 advanced units, but no MS (invasion force time travel mistake)…
  • 4 players - one slot for each era
  • x players - but each player has a starting fleet of X units, and NO ability to build more.

Stuff that wasn’t even remotely possible without hacks and insane tricks before.

You should be able to resolve everything in that case during setup. I mean at some point the GR knows it has seen everything that defines the initial state, and can more forward. Again, this isn’t my area of specialty - but I can’t see having to recheck over ad over - once you had the info, stop checking…?

At the head of AI build you can ask the game rule for the starting fleet decision, and then setup those kXXX values however you want. but they’re global for that AI, so you can change them anytime. If you need to wait for the first think, you can change them at that point, and never again, etc… ?

Ugh - I need to dig through some of this. I just found some really screwy logic that we missed when Race updating… CPU still has some Hgn/Vgr hard-coding. Blah.

I think classdef.lua is useless because adding those types to categories can now be done via Ship properties. So this may be broken for a bit, or easy to work around - I just have to poke at it a bit and get back to you. The way they set this up 10 years ago is insane.

Yup - how likely overall, then how likely in specific!

1 Like

If we created a bunch (probably over 100 between all of the different sections) of new classes in class def (Heavy_Corvette, Heavy_Frigate, etc, etc) and completely rewrote the enitre AI from scratch I would assume that I have to rewrite everything from scratch under the new system? :grin:

Yeah, if you build on that pile of bones - those bones have now been disturbed… :wink:

That said, MUCH of what was being done there is SO EASY now, without hard coding. I am trying to build an example to show the ‘right’ way to do it now using Ship Props… should have something tomorrow.


Also wondering if an interface has been added to randomize the attached subsystems when a ship is built. The intent being a game mode where freighters spawn between hyperspace waypoints with various cargo modules and when they are destroyed or removed (another script) they can return bounties, bonuses or tech.

I tried doing this in a ship lua but the previous function SobGroup_CreateSubSystem didn’t seem to work and failed on a null reference (excuse the verbose debugging)

function Create_Freight(CustomGroup, playerIndex, shipID)
slots = 4
–create a sobgroup to isolate just this ship
SobGroup_FillShipsByType(“AllShips”…tostring(shipID), “Player_Ships”…tostring(playerIndex), “frt_bulk_freighter” )
–locate the custom group and add it to the ThisShip group
position = SobGroup_GetPosition(CustomGroup)
Volume_AddSphere(“findship”…tostring(shipID)…“vol”, position, 5)
SobGroup_FillSobGroupInVolume(“ThisShip”…tostring(shipID), “AllShips”…tostring(shipID), “findship”…tostring(shipID)…“vol”)

–add us back to the custom group
SobGroup_SobGroupAdd(CustomGroup, “ThisShip”…tostring(shipID))
for i=1, slots, 1 do
local r = random(1,getn(freightList))
subsystem = freightList[r]
print(“Picked subsystem:”…subsystem)
print(“count of special sobgroup:”…SobGroup_Count(CustomGroup))
print(“What is a sobgroup look like?:”…tostring(CustomGroup))
–SobGroup_CreateSubSystem(“frt_bulk_freighter”, “frt_cont_d_blue”) – was ‘subsystem’


A few things before I go wash dishes and make dinner (like a good husband… ;))

Normally, doing something over and over will be optimized by a compiler. In the case of LUA though, that won’t happen (generally). So your scripts often say ‘tostring(shipID)’ - consider this variant instead:

local shipStr = tostring(shipID)
local thisShip = "ThisShip"..shipStr
local allShip = "AllShips"..shipStr

Now, all of those SobGroup calls can take pre-built strings. It is quite a bit faster. Additionally, I am going to create a new SobGroup function (side note, I hate that system with a vengeance) - SobGroup_UniqueCreate()

local groupName = SobGroup_UniqueCreate() -- name of 100% unique and empty group
-- blah blah SobGroupstuff

I’ll also probably make it so that the group will auto-nuke after it hasn’t been touched in a frame or two.

Now, as to your question - no, we didn’t make a new ‘random’ tool - we could, if that’d be useful. And you’re saying that SobGroup_CraeteSubSystem is failing in this case? And wasn’t before? I’ll see if anything changed…

1 Like

My team’s past testing has suggested that sob groups were already garbage collected, was that in error or are you thinking of something more aggressive than just cleaning up empty/unused ones? If so, might it be a viable idea to make that aggression optional, an extra parameter at creation perhaps?

I think for unique, I’ll leave it very aggressive - I mean it is a good suggestion - but the existing methods for making an SG at the very least leave the fault of blowing memory/performance with the Mod author.

But certainly, I may do that - allow it to be created as ‘nuke when empty’ or ‘die after x seconds idle’, etc.

I really don’t think SG are garbage collected - but I could be wrong. That whole system annoys the hell out of me. It’s slow, wasteful, ignores many things lua already has tools for, and people often use it to do stuff like ‘fill with type X’ - stuff that is TERRIBLE for speed. Literally brute-force string-check for every ship bad. There’s a better path, but probably not for this game’s lifetime.

Have you seen any of the brute force methods for trying to iterate over every ship in a sob group? If not they might give you a heart attack. :smiley:


I’m not sure it ever worked outside of vessels that had subsystem construction capability like the motherships, battlecruisers and carriers, which the ship doesn’t need (sorta like how minelayer is a prerequisite for targetting missiles and battlecruiser/carrier/mothership seem to have hard coded hyperspace)

In general it would be useful to have some level of randomization of subsystems for various classes of ships, my thoughts were “technicals” basically pirate and militia ships that get cobbled together with randomized weapons and subsystem abilities, alien design ships where visual randomness is desired, modular ships where tags and parameters could be used to change weapon loadouts

1 Like

I have - a MUCH faster and cooler system for that stuff is coming. Ya’ll are gonna die when you see it.

1 Like

Does this mean a Torque clip with a Maliwan Scope and Hyperion Barrel? Because honestly I wouldn’t mind :grinning:

I think random modular ships should have been possible even in HW2C, though the new stuff is obviously likely to make it easier to set up.

When I was working on the B5 mod, I managed to do that with a hack.
Create a ship with all the possible subsystems, and use a script which randomly destroy all but one of the subsystems, by using the SobGroup_SetHardPointHealth command.

I know, it’s crazy, but it was working. I wanted to use this for a nameplate system (subsystem model with different names on them ; named EA destroyers, here I come ^^), but never really finished it. I still have the code though, if anyone is interested

The SobGroup_CreateSubSystem command wasn’t working before, see my post above :wink:

Concerning the nameplate system I was talking before, do you think it would be possible to have something in the hod which could handle something like that ?
For example, some data defining a place on the ship where we could have a text displayed ? Just a technical question, I know it’s far from priority, and wouldn’t be easy I suppose.
See the following image for example (the text I refer to is “AGAMEMNON”) :

Not like that, no. There’s a way to do named badges - or a badge-like area… but it can be quite complex and without in-game shader edits on ships, it doesn’t do what you want. So down the road? Probably similar. Right now, no.

ok, thanks for the answer :slight_smile:

Can we randomly name ships in the ship script and ATI at least? Without having to make copies of .ship files?

1 Like