[SOLVED] Unit naming outside .ship

Question here for the crowd: I’m working on preliminary design for some other features to liven up the in-game maps, and I wonder if anyone knows a way to rename units in-game from custom code or such, for example to give ships from a same class different names without having to create one or two dozen different unit files and having them replace one another in the build list through code?

1 Like

Do you mean like is done in Complex? With the names appended to larger vessels?

This is the closest that we have, a request already with @bitvenom

What do you mean? I’ve just launched Complex with a battlecruiser in the starting fleet and there’s no particular name to it outside the standard unit name.

I have not tried the Remastered Version, but Complex 9.1 at least has a tag that is appended to each larger ship…a name chosen from a list along with a number. The name shows up in blue when you hover the cursor over the vessel. Here is the code in the Deathmatch.lua:

unitname = { "Hygor ", "Apollo ", "Valkyr ", "Neptune ", "Odyssey ", "Deep Seeker ", "Vega ", "Destulon ", "Star Crusher ", "Cluster ", "Leviathan ", "Martyrs of Kharak ", "Veil of Shadows ", "Blind Seer ", "Harvester of Souls "}

And here is the applied labeling code in the sobgroupfunctions.lua:

if HasName == 1 then
if SobGroup_OwnedBy(“temp”) == Universe_CurrentPlayer() then
if SobGroup_AreAnyOfTheseTypes(“temp”, “hgn_mothership”) == 1 then
Ping_LabelVisible(Ping_AddSobGroup(“Pride of Hiigara”, “name”, “temp”), 1)
elseif SobGroup_AreAnyOfTheseTypes(“temp”, “vgr_mothership”) == 1 then
Ping_LabelVisible(Ping_AddSobGroup(“Vaygr Leader”, “name”, “temp”), 1)
elseif SobGroup_AreAnyOfTheseTypes(“temp”, “hgn_shipyard”) == 1 then
name = unitname[casualizzatore[15]+1]
number = unitnumber[casualizzatore[15]+1]
Ping_LabelVisible(Ping_AddSobGroup(name … tostring(number) … “”, “name”, “temp”), 1)
unitnumber[casualizzatore[15]+1] = unitnumber[casualizzatore[15]+1] + 1

1 Like

I should point out that this last snippet of code works because it resides inside of the update class function (sobgroupfunctions.lua):

function SobGroup_UpdateClass(Group, LastGroup, Counter, HasExperience, HasRU, HasName)

1 Like

Huh, interesting… Thanks!

No problem :slight_smile:

1 Like

Yep, I’ll have to see if I can integrate something like that (though with a different display place and different unit classes)… At least, now I see there’s a different way of doing it.

Well good luck with it!

I also should mention the classes of ships he has set-up are initialized in the sobgroup.lua like so (as an example for battlecruisers):


SobGroup_SobGroupAdd(“battlecruisers”, “hgn_battlecruiser”…playerIndex)

nbc = SobGroup_UpdateClass(“battlecruisers”, “lastbattlecruisers”, nbc, 1, 0, 1)

And of course in the deathmatch.lua they start out as:


Yep, I’m seeing how it can be done that way. I checked Complex 10’s code yesterday to compare his fuel script to the one I’m using and I saw the way ships are automatically ordered in general sobgroups.

Ok perfect :slight_smile:

1 Like

OK, I’ve got something that works. For those interested, this code will allow all ships from a class to have a randomized name to be picked from a list when they spawn. It’s activated from the addCustomCode on that class, of course, and will display the specific name of the unit instead of its vanilla name.

First, the code checks whether the name list for this unit is defined. If it’s not, it defines it then shuffles it. After that, a name is defined using the unique shipID of the cruiser and is displayed in the place of the normal name. Feel free to use and improve the code if you want, everyone.

[code]function createFighterFuelBattlecruiserCfd(CustomGroup, playerID, shipID)

if unitname_cfd_cruiser==nil then
unitname_cfd_cruiser = { “Ajax”, “Talahassee”, “Des Moines”, “Baltimore”, “New Orleans”, “Pensacola”, “Kutuzov”, “Cleveland”, “Aoba”, “Furutaka”, “Myoko”, “Kongo”, “Atago”, “Takao”, “Ibuki”, “Mogami”, “Dimitri Donskoi”, “Kirov”, “Udaloi”, “Sovremenny”, “Konigsberg”, “Yorck”, “Hipper”, “Graf Spee”, “Prinz Eugen”, “Hindenburg”, “Leander”, “Belfast”, “St George”, “Drake”, “Achilles”, “Thames”, “Sappho”, “Hermione”, “Raleigh”, “Glorious”, “Courageous”, “Furious”, “Jeanne d’Arc”, “Gloire”, “Duquesne”, “Colbert”, “Tourville”, “Surcouf”, “Dunkerque”, “Suffren”, “Téméraire”, “Vigilant”, “Redoutable”, “Inflexible”}
–name = unitname[floor(random(1,50.9999))]

for i = 50, 2, -1 do
    j = random(1,i)
    unitname_cfd_cruiser[i], unitname_cfd_cruiser[j] = unitname_cfd_cruiser[j], unitname_cfd_cruiser[i]



function updateFighterFuelBattlecruiserCfd(CustomGroup, playerID, shipID)

name = unitname_cfd_cruiser[1+mod(shipID/16+25*playerID,49)]

if SobGroup_Selected(CustomGroup)==1 then
	UI_SetTextLabelText("NewTaskbar", "unitrole", "TCS "..name.." - Battlecruiser")



Just an FYI - all of this code is TERRIBLE for performance. Brute-force hammering during a unit’s LUA update state and potentially making UI changes is not cheap.

One of the biggest issues with rebuilding the game to use more than a single thread is just how poorly designed the LUA hooks into things were - you can’t split unit updates (active commands, lua, etc) into multiple parallel runs, because everything can affect everything.

Also, so that SobGroup_Selected logic work if more than a single unit is selected? Does it return false? Or does each unit try to change the role? Ultimately the role probably isn’t visible - so really it ends up nuking a ton of stuff over and over every frame for no visible effect…


I won’t deny it, I’m definitely not doing optimized stuff. TBH, every time I know you look at either my code or my methods, I wanna give you one of my plushies to hug, because I know I’m doing atrocious stuff for anyone who programs for a living.

Please, oh, pretty, pretty please… never, ever, EVER, take a look at my fuel or ammunition scripts. I doubt any hospital in the world could save you from that sight, and then I would have the rest of the modding community crowdfunding a hit on my head in retaliation.

Edit: yep, I saw that even with four affected units and a powerful computer, there’s a visible lag between selection and reactualization. Ouch.


I’m making a sort of RPG and am interested in naming the ships. I’m still not sure whether it’s not better (for my mod) to just create a new ship type when I need an NPC. (For instance Captain Soban.)

I would say it would be better to create new ships . The above code changes the ships role that is displayed ( eg “Capital Class - Ship Production” ) . While it may be possible to change the ships name with lua code, hovering the mouse over the target will still display it’s original name .

Yep, as indicated by our favourite dev’ and painfully verified experimentally by yours truly, the code I used is awful. For my SP missions, I’m simply using new ship types which, like special named ships in the original campaign, are referring to the standard ships for their .hod files and changing the name and role inside the .ship file itself.

Now, what MIGHT be done (the “might” requires even more emphasis) to achieve a dynamic name generation would be to create a bunch of such named ships that are identical variants of the vanilla ship, make them all buildable at the same priority spot in the build file for the faction in question and only then get a really good script in the rules that makes each ship available for construction once and removes all the others from availability so that when you click on the build icon for the ship, it actually builds a differently-named ship every time.


I have done something similair in the past. Though, instead I used a “dummy” ship that when built, would spawn one of the other ships then despawn itself. It would be mostly the same ship file, except the HOD would be small and it’s DockFamily would be Fighter.

If I remember the code correctly

AvailShips = { <Collection-Of-Ship-Names> }
function Update_( CustomGroup, player, shipId )
  local nextShip = -1
  SobGroup_CreateIfNotExist( "temp" )
  for x = 1, getn( AvailShips ) do
    SobGroup_FillShipsByType( "temp", "Player_Ships"..player, AvailShips[ x ])
    if( SobGroup_Count( "temp" )== 0 )then
      nextShip = x
  if( nextShip ~= -1 )then
    SobGroup_FillProximitySobGroup( "temp", "Player_Ships"..player, CustomGroup, 10 )
    SobGroup_FilterInclude( "temp", "temp", "Ability", "CanBuildShips" )
    SobGroup_CreateIfNotExist( "temp2" )
    SobGroup_Clear( "temp2" )
    Volume_AddSphere( "vol_Spawner", SobGroup_GetPosition( "temp" ))
    SobGroup_SpawnNewShipInSobGroup( player, AvailShips[ nextShip ], AvailShips[ nextShip ], "temp2",  "vol_Spawner" )
    SobGroup_ParadeSobGroup( "temp2", "temp", 0 )
    Volume_Delete( "vol_Spawner" )
  SobGroup_MakeDead( CustomGroup )

I could do something a bit better, but that should work in theory.

1 Like

This… is actually quite smart. Thanks! I will have to see if I can work something out in my mod. :slight_smile: