Can you find the Error?

Discussions about Coding and Scripting
User avatar
Barbie
Godlike
Posts: 2851
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Can you find the Error?

Post by Barbie »

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'

Code: Select all

class SpawnPointNotStatic extends SpawnPoint;

defaultproperties {
	bStatic=false
}

Code: Select all

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
User avatar
sektor2111
Godlike
Posts: 6424
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Can you find the Error?

Post by sektor2111 »

In such case I would write everything different... Somewhere the code would check

Code: Select all

if ( SpawnPointsCount < 30 )
	DoSomething();
instead of too much science... or maybe it's just me...
User avatar
Barbie
Godlike
Posts: 2851
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Can you find the Error?

Post by Barbie »

sektor2111 wrote: Sun Dec 11, 2022 4:31 pm

Code: Select all

if ( SpawnPointsCount < 30 )
	DoSomething();
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
User avatar
sektor2111
Godlike
Posts: 6424
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Can you find the Error?

Post by sektor2111 »

Said DoSomething() function is not for ALWAYS spawning. When I want random stuff I do...

Code: Select all

if ( FRand() < 0.4 ) //Whatever 0.3 0.25 0.5 etc
{
	Spawn(....);
	Etc++;
}

There are enough "random" samples in stock codes, it's not a big philosophy.
Eternity
Skilled
Posts: 177
Joined: Sat Nov 30, 2019 10:56 pm

Re: Can you find the Error?

Post by Eternity »

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.
User avatar
Barbie
Godlike
Posts: 2851
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Can you find the Error?

Post by Barbie »

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
Masterkent
Novice
Posts: 18
Joined: Mon Dec 12, 2022 3:19 pm

Re: Can you find the Error?

Post by Masterkent »

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)
Deaod
Average
Posts: 38
Joined: Fri Jul 10, 2020 9:22 am

Re: Can you find the Error?

Post by Deaod »

Barbie wrote: Mon Dec 12, 2022 12:25 pm
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.
Masterkent
Novice
Posts: 18
Joined: Mon Dec 12, 2022 3:19 pm

Re: Can you find the Error?

Post by Masterkent »

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.
Eternity
Skilled
Posts: 177
Joined: Sat Nov 30, 2019 10:56 pm

Re: Can you find the Error?

Post by Eternity »

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...