The task is to add some (none static) SpawnPoints in pipes with nitrogen. I chose the lights in there as spawn location and verified, that there is enough room to spawn SpawnPoints.
class'SpawnPointNotStatic'
foreach AllActors(class'Light', light) // #=405
if (light.Region.Zone.Tag == 'NitrogenZone') // #=194
if (fRand() < 30 / 194) // add not more than ~30 SpawnPoints
if (SpawnActor(LogLevel, SpawnPointNotStaticClass, , CF.Tag, light.Location) != None)
SpawnPointsCount++;
Sadly 0 SpawnPoints were added. Why not?
Solution
Show really?
Solution
In fact in the calculation of "30 / 194" both numbers are treated as integers and the result of the divison is 0 then instead of 0.15. Declaring one or both as float gives the correct result (e.g. "30.0 / 194").
Last edited by Barbie on Mon Dec 12, 2022 11:21 pm, edited 1 time in total.
"If Origin not in center it be not in center." --Buggie
But with this the SpawnPoints are spawned always at the same place and in the order the lights appear in the map. I'd like to have them spread over randomly.
"If Origin not in center it be not in center." --Buggie
Probably, some would have written it as a constant, doesn't matter how many symbols this float value takes - 3, 10 or whatever, and even if this is not a performance critical part at all.
There are reasons, not that hard to guess... Especially if way too often you have seen a very performance critical parts in mods written (or copypasted) not the way they normally should... In many cases it could be done using multiplication operator, or just a constant with no any operators at all, but they use division anyway...
If they don't read textbooks and tutorials, then maybe they will take an interest on why it has been written exactly this way, and not another way... If at least one will do this, then our hard efforts on executing "calc" command and getting a result of division was not for nothing.
Eternity wrote: ↑Mon Dec 12, 2022 8:55 amProbably, some would have written it as a constant
Usually I do that too, but sometimes it is helpful to see how the result was calculated. By "30 / 194" one (and me, years later^^) can see that the basic amount is 194 and the desired amount 30.
Such calculations should not be a performance issue, because (I guess hopefully) calculation is done at compile time.
"If Origin not in center it be not in center." --Buggie
30 / 194 evaluates to zero value of type int, because both operands of operator / are of type int here, hence this is an integer division. When a floating point arithmetics with a result of type float is needed, one or both operands should have type float:
int / int -> int (1 / 2 == 0)
float / int -> float (1. / 2 == 0.5)
int / float -> float (1 / 2. == 0.5)
float / float -> float (1. / 2. == 0.5)
Eternity wrote: ↑Mon Dec 12, 2022 8:55 amProbably, some would have written it as a constant
Usually I do that too, but sometimes it is helpful to see how the result was calculated. By "30 / 194" one (and me, years later^^) can see that the basic amount is 194 and the desired amount 30.
Such calculations should not be a performance issue, because (I guess hopefully) calculation is done at compile time.
The unrealscript compiler does not optimize anything. The best you get is constant-folding when you specifically use const, but other than that you can forget about any optimizations.
Yes, for modern compilers evaluating constant expressions is pretty basic stuff, but this one is a) old, and b) programmed by people that werent necessarily experts in compiler design.
The way the bytecode is structured also doesnt easily lend itself to implementing an optimization like compile-time evaluation of constant expressions, because the basic math operations (eg. int+int) are implemented just like other native functions.
Deaod wrote: ↑Mon Dec 12, 2022 4:42 pmThe way the bytecode is structured also doesnt easily lend itself to implementing an optimization like compile-time evaluation of constant expressions, because the basic math operations (eg. int+int) are implemented just like other native functions.
227j's UScript compiler already supports such optimizations. For example, in expression FRand() < 30. / 194, it replaces the devision with a computed constant (this may be checked e.g. with the UTPT decompiler). As far as I can see, 469c doesn't perform such a replacement - at least without possible special flags/options that I may be unaware of.
Unfortunately, this is a very basic compiler that unlike modern ones optimizes (almost?) nothing, even such simple constant expressions as written above.
We wouldn't care of it that much otherwise, but the practice has shown final performance is depended on the way the script is written in a very high extent.
Hopefully, future v469d probably may have at least some basic optimizations, if we raise this question and open an issue on Github some day...