Itās not the line of code itself that is the problem; itās something to do with the subsystemā¦
I changed that one line of code to SobGroup_CreateSubSystem(CustomGroup, "FighterProduction") just as a test, and it worked just fine.
Itās not the line of code itself that is the problem; itās something to do with the subsystemā¦
I changed that one line of code to SobGroup_CreateSubSystem(CustomGroup, "FighterProduction") just as a test, and it worked just fine.
Ha! Apparently if itās not a type string that the game recognizes (such as "FighterProduction", "Research", etc.), the subsystem name has to be in all caps ("VET_MOD_RANK1").
oO strange, to say the least !
Okay, nope, I lied⦠It does not have to be in all caps.
But!!! The ship building the subsystem has to have the line addAbility(NewShipType,"CanBuildShips",1,"","");, and the subsystem to be built has to be included in the raceās def_build.lua.
The downside is that now your build list is clutteredā¦
doesnāt explain why it worked when you changed to SobGroup_CreateSubSystem(CustomGroup, āFighterProductionā)
The need of the addAbility āCanBuildShipsā should exist in the two cases, no ?
[quote=āDwarfinator, post:43, topic:1245263ā]
The need of the addAbility āCanBuildShipsā should exist in the two cases, no ?
[/quote]I had that in there before. Itās when I started removing lines of debug code that I discovered that particular requirement.
ah ok, makes sense
Rank 1: Gains +15% health
Rank 2: Gains +15% speed
Rank 3: Gains hyperspace capability
Rank 4: Gains +15% damage, +15% accuracy
Rank 5: Gains cloak ability
Holy smokes! NICE.
I see that a good bit of extra stuff ended up being necessary⦠well done! This is really impressive, and it works fantastically over here: all upgrades applied and working on schedule. Absolutely beautiful.
So my intent now is to go ahead and add veterancy to all frigates and capital ships.
Will my previous tactic of using CFHodEd to quickly add hardpoints be sufficient? I notice that your testfrigate UI drawing looks different, so Iām thinking maybe you did something extra to the model?
What code needs to be added to .ship files ā same as before? The .ship file for the test frigate has āaddShieldā and āaddAbilityā lines that are new, and probably others Iām missing (and is arranged differently!), but Iām not sure if theyāre part of the testing process or absolutely necessary.
(And, just in case you didnāt see above, do you happen to have a Steam wishlist with anything on it?
)
Thanks!
I didnāt mess with the model you sent at all. Honestly, Iām a little hesitant to use the new CFHodEd, given @BitVenomās persistent insistence, and Iām still feeling my way around 3DSMax⦠But, thatās just me.
And no, I didnāt do anything with the UI.
The only necessary lines of code to add are:
addAbility(NewShipType,"CanBuildShips",1,"","");
addCustomCode(NewShipType,"data:scripts/lib/veteran.lua","","Create_VeteranShip","Update_VeteranShip","Destroy_VeteranShip","hgn_torpedofrigate_test",1);
StartShipHardPointConfig(NewShipType,"Veteran1","Hardpoint_Veteran1","System","Innate","Indestructible","","vet_mod_rank1","","","","","","","");
StartShipHardPointConfig(NewShipType,"Veteran2","Hardpoint_Veteran2","System","Innate","Indestructible","","vet_mod_rank2","","","","","","","");
StartShipHardPointConfig(NewShipType,"Veteran3","Hardpoint_Veteran3","System","Innate","Indestructible","","vet_mod_rank3","","","","","","","");
StartShipHardPointConfig(NewShipType,"Veteran4","Hardpoint_Veteran4","System","Innate","Indestructible","","vet_mod_rank4","","","","","","","");
StartShipHardPointConfig(NewShipType,"Veteran5","Hardpoint_Veteran5","System","Innate","Indestructible","","vet_mod_rank5","","","","","","","");
The only other line of code I added to the ship file was addAbility(NewShipType,"CloakAbility",0,2,0,4000,1,1,1,1000); since the final rank granted cloaking. (The addShield line was already present, it just got jumbled around in the midst of my code changes.)
Mind you, you donāt actually have to use the rank bonuses I did; those was just arbitrary choices on my part, just to fill the void.
I did see it, but⦠http://steamcommunity.com/profiles/76561198030787818/wishlist 
Edit: Well, it was empty when I posted the linkā¦
Thanks for the quick help!
I didnāt mess with the model you sent at all. Honestly, Iām a little hesitant to use the new CFHodEd, given @BitVenomās persistent insistence, and Iām still feeling my way around 3DSMaxā¦
Gotcha! Yeah, I saw him saying that CFHodEd is likely to foul up on you; but it seems to take quite a bit more effort to just add an empty hardpoint with 3DS or Blender, and my hope was that something so small would be okay.
(The thing I meant is the wireframe-ish drawing when selecting a unit ā looks different than default torpedo frigate, but maybe itās actually from when I edited the hardpoints ā no problem, Iād go without a UI at all if it got in veteran units!)
Mind you, you donāt actually have to use the rank bonuses I did; those was just arbitrary choices on my part, just to fill the void.
I like 'em! I actually wrote up a little explanation for each of them, either just for fun or possibly to be included in the āreadmeā, if youāre looking in that direction
: āRank 2: The crew learns to squeeze a little extra juice out of the engines. Rank 4: The gunners hone their craft and begin to target weak points. Rank 5: HQ presents your ship with a medal of honor⦠and a cloak generator.ā Etc!
I did see it, but⦠http://steamcommunity.com/profiles/76561198030787818/wishlist
Edit: Well, it was empty when I posted the linkā¦
Ah, wishlist goblins ā big problem over here too. But maybe another item can be scratched off soon⦠
Hmmm, I donāt see that at allā¦
Haha! 
You might want to dig in the Complex modās files to figure out they did ship experience without using āCanBuildShipsā
@Hell_Diguner: Thatās interesting; I didnāt know anyone else had ever managed it ā I asked around a few places and I was told it was impossible to add veterancy (but I thought Iād try it anyway, and then radar turned his genius to bear on it
). Thanks for the tip!
I donāt want to mess with trying a new system yet, since Iām really liking how this is so tunable and customizable, and Iām thinking that another way probably wonāt be as flexible (but maybe!), but itās definitely worth looking into sometime.
Right now, VetMod v. ā2.2ā is working excellently ā Iāve added veterancy to all frigate and capital Hiigaran ships (excepting shipyard and mothership) and no problems have appeared, knock on wood. The noble testfrigate has been removed (but never forgotten), and the ranks and exp levels tweaked a bit.
I felt the current exp progression is actually pretty close to perfect, so I just made it take a little longer to get to 1 and 2, and a little sooner to get to 3, 4, and 5. This is just based on how many ships make it to each level in the couple of skirmish games I played, and the āfeelā of when they start reaching them. (You could tell that the biggest gap was between 2 and 3, for example.)
However, weāll see if anyone makes it to 5 (or, conversely, if too many do) in future, more serious games. The modifiers given at each rank have also been Jormungandrized ā mainly just by switching the ordering around a bit:
Rank 1: Shipshape: The crew learns to hustle when itās time to do drills and maintenance. HP Regen +15%
Rank 2: Full Steam Ahead: Engineering gets to know their ship, and with a bit of tuning learns to squeeze a little extra juice out of the powerplant. Speed +10%
Rank 3: Benefit of Rank: HQ doesnāt want to loseveteranany servicemembers. The latest in reactive armor technology is installed. HP +15%
Rank 4: Just Donāt Lead 'Em As Much: The gunners know and love their weapons⦠and enemy weak points. Weapon Accuracy & Damage +15%
Rank 5: Form 126C.13-8a: For valor in combat, length of service, and being particularly hard to kill, HQ presents your ship with the last word in cloaking technology. Cloaking ability gained
Iām thinking of going to 20% for Rank 1 (regen), since 10% was basically imperceptible, but maybe thatās too high. Also not sure if Rank 5 should be cloaking or hyperspace, or even defense field. Thoughts welcome.
Iām about to go test the campaign with this mod; what I expect is that if a ship reaches rank 3, it will start the next mission with rank 3⦠but with 0 exp again. My hope and belief is that when that ship gets enough exp for a rank in the new mission, the game wonāt have any trouble when it goes to add that rankās subsystem and finds it already there.
The other thing is that someone might think āhey, my ship got to rank 3, it should start with that much exp!ā So Iām looking to see if itās possible to, e.g., check if a ship has rankN subsystem (and exp < exp-for-rankN), and then automatically set its exp to exp-for-rankNā¦
ā¦but Iām personally not too bothered if itās not possible. I mean, if your ships get into heavy combat, theyāll still get ranks, and theyāll still be āindividualizedā with their own histories. Thatās the main thing, to my mind⦠and this way, the ranks are balanced for both the campaign and skirmish maps (whereas if the campaign could be made cumulative, the exp for each rank would have to be increased lot, I think).
Anyway, this has already transformed my Homeworld experience ā I donāt know about yāall, but the spaceships are the main attraction for me, above and beyond the storyline, tactics, competition, and building⦠and Iām a naval history buff, so when I think āwarshipā I think giant, magnificent, almost-living machines that have names, histories, and accomplishments.
A fleet of interchangeable, assembly-line ships that could have been in a hundred battles or none, that show no sign of their noble and valorous past⦠well, itās just not the same. I better wrap it up before I get too poetic ;). so let me just say: three cheers for @radar3301, and a big thank-you to @Dom2, @pascal76680, and everyone else who has contributed!
Thatās easily fixable.
Maybe I should finish reading your post first, because thatās pretty much what I going to do.
Or maybe more ranks?
The nice thing about this system, is that it can be completely customized. I envisioned the above as just a template to start from. The possibility exists to customize each (type of) ship to have itās own exp curve, itās own bonuses, etc. I could even re-write the code to say that for this ship, you get this bonus, and for that ship, you get that bonus. In fact, I just might go do thatā¦
Update to version 3.5.
Version 3.5 contains the following changes:
-- ####################################
-- # data:scripts/lib/veteran.lua #
-- # by radar3301 #
-- # #
-- # Version: 3.5 - 20160307.0443 UTC #
-- # ##################################
-- ##############################
-- # BEGIN TUNABLES SECTION #
-- # THIS SECTION CAN BE EDITED #
-- # except as noted below #
-- ##############################
function Veteran_Init() -- DO NOT EDIT THIS LINE
AddVeteranRank("default", 70, "vet_healthregen")
AddVeteranRank("default", 160, "vet_speed")
AddVeteranRank("default", 280, "vet_health")
AddVeteranRank("default", 430, "vet_weaponaccdmg")
AddVeteranRank("default", 590, "vet_hyperspace")
-- NOTE: iRankNum is 1-based
-- ModifyVeteranRank(<sShipName>, <iRankNum>, <iExpNeeded>, <sBonus>)
-- ModifyVeteranExp(<sShipName>, <iRankNum>, <iExpNeeded>)
-- ModifyVeteranBonus(<sShipName>, <iRankNum>, <sBonus>)
ModifyVeteranExp("hgn_torpedofrigate_test", 3, 300)
ModifyVeteranRank("hgn_torpedofrigate_test", 4, 400, "vet_weaponacc")
ModifyVeteranBonus("hgn_torpedofrigate_test", 5, "vet_weapondmg")
-- AddVeteranRank("hgn_torpedofrigate_test", 750, "vet_hyperspace") -- needs a 6th hardpoint!
end -- DO NOT EDIT THIS LINE
-- How often the script updates
-- This number should be the same as the last argument
-- in the addCustomCode line of the ship file
UPDATE_FREQUENCY = 1
-- ##########################
-- # END TUNABLES SECTION #
-- ##########################
-- ############################
-- # BEGIN CODE SECTION #
-- # DO NOT EDIT THIS SECTION #
-- # unless you know what #
-- # you are doing #
-- ############################
dofilepath("data:scripts/lib/util.lua")
-- globals
vet_statics = {
default = { nRanks = 0 }
}
vet_ships = {}
-- helpers
function AddVeteranRank(_shipname, _exp, _bonus)
assertstring(_shipname, 1)
assertnumber(_exp, 2)
assertstring(_bonus, 3)
if (vet_statics[_shipname] == nil) then
vet_statics[_shipname] = { nRanks = 0 }
end
local static = vet_statics[_shipname]
local n = static.nRanks + 1
static["rank"..n] = { e = _exp, b = _bonus }
static.nRanks = n
end
function ModifyVeteranRank(_shipname, _rank, _exp, _bonus)
assertstring(_shipname, 1)
assertnumber(_rank, 2)
assertnumber(_exp, 3)
assertstring(_bonus, 4)
__ModifyVeteranRank(_shipname, _rank, _exp, _bonus)
end
function ModifyVeteranExp(_shipname, _rank, _exp)
assertstring(_shipname, 1)
assertnumber(_rank, 2)
assertnumber(_exp, 3)
__ModifyVeteranRank(_shipname, _rank, _exp, nil)
end
function ModifyVeteranBonus(_shipname, _rank, _bonus)
assertstring(_shipname, 1)
assertnumber(_rank, 2)
assertstring(_bonus, 3)
__ModifyVeteranRank(_shipname, _rank, nil, _bonus)
end
function __ModifyVeteranRank(_shipname, _rank, _exp, _bonus)
if (vet_statics[_shipname] == nil) then
vet_statics[_shipname] = deepcopy(vet_statics["default"])
end
local static = vet_statics[_shipname]
local rank = static["rank".._rank]
assertnotnil(rank, "rank".._rank.." does not exist for ".._shipname)
if (_exp ~= nil) then rank.e = _exp end
if (_bonus ~= nil) then rank.b = _bonus end
end
-- addCustomCode FUNCTIONS
function Create_VeteranShip(CustomGroup, playerIndex, shipID)
if (vet_ships[shipID] ~= nil) then
print("ERROR: shipID "..shipID.." already exists!")
end
vet_ships[shipID] = {
id = shipID,
name = "ship"..shipID,
timeCreated = Universe_GameTime(),
xp = 0,
rank = 0,
checked = 0
}
end
function Update_VeteranShip(CustomGroup, playerIndex, shipID)
local ship = vet_ships[shipID]
if (ship.checked == 0) then
local health1 = SobGroup_GetHardPointHealth(CustomGroup, "Veteran1")
local health2 = SobGroup_GetHardPointHealth(CustomGroup, "Veteran2")
local health3 = SobGroup_GetHardPointHealth(CustomGroup, "Veteran3")
local health4 = SobGroup_GetHardPointHealth(CustomGroup, "Veteran4")
local health5 = SobGroup_GetHardPointHealth(CustomGroup, "Veteran5")
ship.checked = 1
if (health5 > 1) then
ship.rank = 5
elseif (health4 > 1) then
ship.rank = 4
elseif (health3 > 1) then
ship.rank = 3
elseif (health2 > 1) then
ship.rank = 2
elseif (health1 > 1) then
ship.rank = 1
end
if (ship.rank > 0) then
ship.xp = vet_statics[CustomGroup]["rank"..ship.rank].e
end
end
if (SobGroup_UnderAttack(CustomGroup) == 1) then
ship.xp = ship.xp + UPDATE_FREQUENCY -- gain xp based on how long in combat
end
ship.xp = ship.xp + UPDATE_FREQUENCY * 0.1 / (ship.rank + 1) -- gain xp based on how long alive, less experience gained at higher ranks for being alive
local static = vet_statics[CustomGroup]
if (static == nil) then
static = vet_statics["default"]
if (static == nil) then
error("unable to find the default veteran static")
end
end
if (ship.rank < static.nRanks) then
local rank_stat = static["rank"..(ship.rank+1)];
if (ship.xp >= rank_stat.e) then
ship.rank = ship.rank + 1
SobGroup_CreateSubSystem(CustomGroup, rank_stat.b)
end
end
end
function Destroy_VeteranShip(CustomGroup, playerIndex, shipID)
vet_ships[shipID] = nil
end
-- INITIALIZATION
Veteran_Init()
By the way, Iām also planning for version 4. The major update for v4 will be moving non-standard veterancy award modifiers out of the core veteran file into a ship specific file. Also, I may introduce an experience curve function.
Fantastic stuff.
Seriously amazing. I canāt wait to replay the campaign with this! (I think the shorter variable names are what all of us have been most looking forward to, thoughā¦)
As I mentioned on Steam, Iāve reduced the exp numbers. Iām trying to fit them to my ārank theoryā (rank 3 --> elite, rank 4 --> special forces, and rank 5 only seen on 3-4 legendary ships in a long struggle). I just remembered that I was going to see if increasing CPU difficulty meant my games got long enough to make the new numbers too low, though.
I can upload my āplaytesting versionā, if youād like to experiment yourself ā itās nothing you couldnāt do, but at least you wonāt have to go through and edit all the ships, heh.
Edit: What is this util.lua reference I see? 
util.lua:
(updated)
-- deprecated
-- function checktype(var, _type)
-- if (type(var) ~= _type) then
-- error(_type.." expected, got "..type(var))
-- end
-- return 1
-- end
function asserttype(var, _type, argn)
if (type(var) ~= _type) then
if (argn == nil) then
error(_type.." expected", 2)
else
error("arg #"..argn.." expects a ".._type, 2)
end
end
end
function assertstring(var, argn)
asserttype(var, "string", argn)
end
function assertnumber(var, argn)
asserttype(var, "number", argn)
end
function asserttable(var, argn)
asserttype(var, "table", argn)
end
function assertnotnil(var, message)
if (var == nil) then
error(message)
end
return 1
end
function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in orig do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
This may or may not make it into the next versionā¦
Check the updated definition for āutil.luaā
Iām not yet sure what effect the 2.0 patch had on this mod, but if there is still some interest in this, I can look into reviving/working on it more.