About the veterancy system
-
Note that having a combination of the options (e.g., an exception for the commander) will still introduce additional logic each time a unit receives damage or dies.
-
I did a quick couple of tests using my custom profiler that I developed originally for testing my AI, and found that in normal conditions the % of time spend in the two veterancy functions in question did not exceed ~0.2% of total sim compute time. This test was done in a 4v4 between my AIs, which are currently very land focussed.
In ASF vs ASF tests I was able to get it up to at most ~2% of total sim compute time, but during the periods of negative sim speed it was at most ~0.7%.
==
Overall my conclusion is that the rest of the sim scales worse than these veterancy functions, and they have a negligible effect most of the time. By all means feel free to change the vet system, but it probably doesn't need to be for performance reasons.
==
Cautionary note: this method for profiling may not give completely accurate results for many calls of a low cost function due to the error associated with getting system time and the precision of system time provided. If anyone wants to jump in and check how these errors might have affected it go right ahead
For completeness, a link to my profiling code and my hook of the Unit class for testing:
YeOldeUnitThingy = Unit local PROFILER = import('/mods/DilliDalli/lua/AI/DilliDalli/Profiler.lua').GetProfiler() Unit = Class(YeOldeUnitThingy) { VeterancyDispersal = function(self, suicide) local start = PROFILER:Now() YeOldeUnitThingy.VeterancyDispersal(self, suicide) PROFILER:Add("VeterancyDispersal",PROFILER:Now()-start) end, DoTakeDamage = function(self, instigator, amount, vector, damageType) local start = PROFILER:Now() YeOldeUnitThingy.DoTakeDamage(self, instigator, amount, vector, damageType) PROFILER:Add("DoTakeDamage",PROFILER:Now()-start) end, }
Some output from tests:
4v4 AI match, ~15 mins ~1k units on the map: info: Time per game second:0.32s, Top Costs: DoTakeDamage-0.16%, VeterancyDispersal-0.01%, info: Time per game second:0.34s, Top Costs: DoTakeDamage-0.14%, VeterancyDispersal-0.02%, info: Time per game second:0.31s, Top Costs: DoTakeDamage-0.15%, VeterancyDispersal-0.01%,
100 vs 100 ASF: INFO: Time per game second:0.17s, Top Costs: DoTakeDamage-0.65%, VeterancyDispersal-0.09%, INFO: Time per game second:0.17s, Top Costs: DoTakeDamage-0.97%, VeterancyDispersal-0.11%, INFO: Time per game second:0.17s, Top Costs: DoTakeDamage-0.75%, VeterancyDispersal-0.11%, INFO: Time per game second:0.17s, Top Costs: DoTakeDamage-0.58%, VeterancyDispersal-0.11%,
1000 vs 1000 ASF: INFO: Time per game second:17.49s, Top Costs: DoTakeDamage-0.14%, VeterancyDispersal-0.00%, INFO: Time per game second:4.23s, Top Costs: DoTakeDamage-0.24%, VeterancyDispersal-0.02%, INFO: Time per game second:2.60s, Top Costs: DoTakeDamage-0.47%, VeterancyDispersal-0.06%, INFO: Time per game second:1.98s, Top Costs: DoTakeDamage-0.71%, VeterancyDispersal-0.09%, INFO: Time per game second:1.26s, Top Costs: DoTakeDamage-1.17%, VeterancyDispersal-0.14%, INFO: Time per game second:0.92s, Top Costs: DoTakeDamage-1.07%, VeterancyDispersal-0.16%, INFO: Time per game second:0.59s, Top Costs: DoTakeDamage-2.25%, VeterancyDispersal-0.15%, INFO: Time per game second:0.44s, Top Costs: DoTakeDamage-1.25%, VeterancyDispersal-0.18%,
-
Veterancy is last I checked defined in Unit BP
-
As Softles posted, this topic was looked into a year ago or so and it was found that the vet system has some relevant impact in essentially massive 400 v 400 asf fights and likely resulted in an additional 1 or 2 decrease in sim speed there. The rest of the game didn’t really see much impact from it at all.
-
@jip said in About the veterancy system:
Note that having a combination of the options (e.g., an exception for the commander) will still introduce additional logic each time a unit receives damage or dies.
Can't you put it on the attacking unit? When you have few units that participate in veterancy. Could it be a weapon property that a weapon increases the attacking units veterancy mass score if it scores a kill?
-
I like option 2 the most.
Didn't see it listed so figured I'd throw out an alternative idea. Unit age = veterancy. As in a unit that lives 2:00 minutes gets it's first vet, and maybe 5:00 minutes is the second vet, and so on.... Seems computational simple and would encourage players to keep units alive.
-
Option 2 seems workable.
Though as FtXCommando mentioned, the impact of veterancy on gameplay in general is so small. A whole force of veterans will beat an equal force of recruits, but TBH that feels like it. That is outside the topic here though.
-
@kalethequick said in About the veterancy system:
Option 2 seems workable.
Though as FtXCommando mentioned, the impact of veterancy on gameplay in general is so small. A whole force of veterans will beat an equal force of recruits, but TBH that feels like it. That is outside the topic here though.
Ftx was referring to vet system's impact on sim speed, not gameplay.
-
After some further testing with 200 on 200, 300 on 300 and 400 on 400 ASFs fighting each other I can not reproduce my original results. Currently I have a reliable sim difference of at most 1 with 300 on 300 ASFs and beyond.
I've also tried to experiment with damage over time using T1 UEF bombers. In the test I had 100 bombers firing at a Megalith. that resulted in a sim computation difference of ~10.2ms at peak (without) to ~10.4ms at peak (with). Three runs for each. It isn't significant, quite minor. In both cases it aligns with what Ftx and Softles stated.
I'm updating the original post as I consider it misleading at this point. Not sure what happened when I tested before, maybe a background program (World Machine, hurr) interfered with it.
-
I designed the current system, and gotta say I like the sound of option 2. Wish I'd thought of that. It's not quite the same, as it means the distribution of damage from units which regen or get repaired shifts, but tbh that is so ridiculously uncommon I was wrong to take it into account. The cost of the table lookups probably isn't worth it.
xp = (damageDealt / MaxHP) * massCost should do the trick. Probably doable in about 20 minutes by anyone familiar with unit.lua.
-
So people would get vet just from popping shots on the enemy commander? Two ACUs trade shots for a while and they both vet?
-
You could tune down the mass cost of the commander to make that effect negligible
-
@icedreamer said in About the veterancy system:
I designed the current system, and gotta say I like the sound of option 2. Wish I'd thought of that. It's not quite the same, as it means the distribution of damage from units which regen or get repaired shifts, but tbh that is so ridiculously uncommon I was wrong to take it into account. The cost of the table lookups probably isn't worth it.
xp = (damageDealt / MaxHP) * massCost should do the trick. Probably doable in about 20 minutes by anyone familiar with unit.lua.
I'm still running investigations into those table allocations. As indeed, the scenario you describe is rare and it introduces a lot of allocates in some situations.
For now it is important to first finish up the profiler in a reasonable state, then we can start looking at what really makes the sim tick
-
@jip Oh, that's easy - The vast lion's share of the compute time is taken up by function calls across the C++/lua boundary. It's about two orders of magnitude slower than anything else. Potential areas for improvement would be to look for areas where the lua makes repeated, unneccessary calls to engine. I worked with a couple of guys to eliminate all the points in the exe which make stupid calls the other way, so that's already done.
Other than that, you can try using more local variables in hot code - Intel, collision detection, economy events.
-
@icedreamer said in About the veterancy system:
@jip Oh, that's easy - The vast lion's share of the compute time is taken up by function calls across the C++/lua boundary. It's about two orders of magnitude slower than anything else. Potential areas for improvement would be to look for areas where the lua makes repeated, unneccessary calls to engine. I worked with a couple of guys to eliminate all the points in the exe which make stupid calls the other way, so that's already done.
Other than that, you can try using more local variables in hot code - Intel, collision detection, economy events.
Yes - I've been looking into using locals. LOUD applies a similar pattern to optimize functions or to push them as an 'upvalue' which is still better than a global. A wikipedia entry that I've learned from quite a bit: https://springrts.com/wiki/Lua_Performance
Do you happen to know about how the garbage collector works in Lua? I've been trying to find informative examples, but came out short.
-
Oh - and while I have you - how did you found out about the boundary passing being expensive?
-
I profiled the game while it was running and produced a statistical output of how much time was spend in each function, both in engine, in lua, and the time at which the function call was registered.
-
Do you still have that profiler?
-
option 2
-
A few months later, there was something wrong with the implementation of the veterancy system: it could hoard megabytes of worth of tables into memory! Read all about it here: