Started by Vertu, July 07, 2022, 05:00:39 PM
# Build selected units#By Vertu. GetSelectedUnits ->unitsif(GetListCount(<-units) gt0) do(GetListCount(<-units) 0) ConstructUnit(<-units[I] 10000) SetUnitAmmo(<-units[I] GetUnitMaxAmmo(<-units[I])) SetUnitHealth(<-units[I] GetUnitMaxHealth(<-units[I])) loop ClearTraceLog Trace3("Fully built " GetListCount(<-units) " selected units.")else if(GetUnitUpdateCount lt(2)) Trace("No units where selected for building.") else if(GetUnitUpdateCount 10 % eq0) ClearTraceLog if(<-count eq0) Trace("Operating. |") 1 ->count else if(<-count eq(1)) Trace("Operating. /") 2 ->count else if(<-count eq(2)) Trace("Operating. -") 3 ->count else Trace("Operating. \") 0 ->count endif endif endif endif endifendif
Quote from: Karsten75 on July 08, 2022, 10:09:06 AMLooking at the log file, I'd love to know on what basis you characterize this as a "stack overflow" issue?
Quote from: knucracker on July 11, 2022, 10:49:45 AMOk, so this and the previous problem you posted about (with the v-rods) is likely the same thing. Both involve stack overflows. And in these cases it is the C#/mono/il2cpp/game's call stack we are talking about (not the 4rpl call stack). In short, inside :Destroyed you find nearby units and call DamageUnit on them. DamageUnit can in turn destroy the unit which causes its :Destroyed to get called, which will in turn find nearby units and call DamageUnit on them. There is no problem with a call loop. The game detects call loops and prevents call loops. The problem is just that the chain of unit calls gets so long that the call stack memory limit is exceeded. The chain is: DamagUnit -> :Destroyed -> DamageUnit -> :Destroyed ... with each :Destroyed being called on a new unit.In the attached map I reproduce it using your v-rod unit (what you reported on in your prior post). Now, unity will hard crash when the stack is blown (sometimes). That is talked about here and Unity isn't fixing it: https://issuetracker.unity3d.com/issues/unity-editor-crashes-after-using-circular-dependency . That's the explanation. Now, what to do about it.... I could attempt to lighten the stack memory used, but that just moves the problem from 25 units to 30 units, for instance. I could attempt to break the call chain, but that requires some special case work for how certain APIs, like DamageUnit, would work when being called from :Destroyed. In short, that's work that could break things and is a bridge too far for where the game is currently. It also isn't flexible as to what should actually happen... see below.But, you may be able to do something on your own... If you think about it, what you are trying to do is create a 'dust cloud explosion', or a 'chain reaction', or a 'Little Doctor' explosion from Ender's Game. One thing destroys another in a chain reaction. If you were to code that up in some other language on some other platform, you'd experience the same problem if the solution was done with functions that call each other in a chain. At N particles, you'd exceed some call stack limit.What you'd ultimately need to do instead (and there are several different types of solutions I think), is 'flatten' the call to destroy/damage and replace it with a loop. You could perhaps use a global table that tracks the damage done to units. So inside Destroyed, instead of calling DamageUnit on nearby units, you record the damage you want to do inside a table. Then you later go through the table in a loop and apply the actual damage. Breaking the chain means not calling DamageUnit from :Destroyed. You have to replace it with your own "MyDamageUnit" call that just tracks the damage, and then at some other point apply the damage. Whether you want to resolve all of that in one frame or across frames, depends on the explosion effect you would want.