Number check

Creation, discussion, and balancing of game content such as techs, buildings, ship parts.

Moderators: Oberlus, Committer

Post Reply
Message
Author
User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 13603
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Number check

#1 Post by Geoff the Medio »

I was playing around with parsing of int and double constants, disabling parsing of one and casting to the other. When doing this, I got an error message from the parser, like so:

Code: Select all

2015-01-26 21:55:30,731 ERROR Server : C:\Users\Geoff\Desktop\FreeOrion_VS2010_SDK\FreeOrion\default\buildings.txt:1577:193: Parse error.  Expected integer function expression here:

        EffectsGroup
            scope = Source
            activation = Or [
                Not ContainedBy Contains And [ Monster Unowned ]
                Turn high =  ( ( 200 + (50 * (5 - GalaxyMaxAIAggression)) + (1000 * (If condition = ValueTest high = 2 testvalue = GalaxyMaxAIAggression))) * ((Max(1, 3 - GalaxyPlanetDensity))^0.5) * ((Max(1, GalaxySize / 200))^0.4))      // always remove lanes before spawn start turn
                                                                                                                                                                                                 ^
            ]
            effects = RemoveStarlanes endpoint = WithinStarlaneJumps jumps = 1 condition = Source

        EffectsGroup
            scope = Source
This makes me wonder if the 0.5 is actually being parsed and used as 0.5, or if it's being cast to int, and thus being truncated to 0. Someone might want to double-check that condition is working as intended...

User avatar
Dilvish
AI Lead and Programmer Emeritus
Posts: 4768
Joined: Sat Sep 22, 2012 6:25 pm

Re: Number check

#2 Post by Dilvish »

Hmm, yes, that is being cast to an int. Adding some logging to ValueRef.cpp I was seeing some suspicious in exponential logs like

Code: Select all

2015-01-26 14:08:59,495 DEBUG Server : ValueRef<int> exponential requested for 1 and 0 ; dump is max(1, 1) ^ 0
Changing that script 0.5 to a 2.5 and the 0.4 to a 3.4, I instead got

Code: Select all

2015-01-26 14:11:35,190 DEBUG Server : ValueRef<int> exponential requested for 1 and 2 ; dump is max(1, 1) ^ 2
2015-01-26 14:11:35,190 DEBUG Server : ValueRef<int> exponential requested for 2 and 3 ; dump is max(1, 1) ^ 3
On the other hand, an Evacuation appears to properly trigger a <double> exponential:

Code: Select all

2015-01-26 14:12:58,261 DEBUG Server : ValueRef<double> exponential requested for 89 and 2 ; dump is (101 + target's Target Population - 2.00 * previous value's ERROR: DESC_VAR_) ^ 2.00
2015-01-26 14:12:58,261 DEBUG Server : ValueRef<double> exponential requested for 9041 and 0.5 ; dump is max(0.00, 0.00) ^ 0.50
This persisted even if I tried changing all the numbers in the script to doubles to try to stop it from triggering the int handling. So, it suggests that instead of doing any automatic casts to ints perhaps we should an an explicit scripting int cast valueref and not otherwise do it, or at least not do it from a double to an int without an explicit cast.

In all these though, I am also puzzled by the mismatch between the numbers in the first part of the log line and those in the second part ('dump') of the log line. The code for generating these logs was

Code: Select all

                Logger().debugStream() << "ValueRef<double> exponential requested for "
                                       << m_operand1->Eval(context) << " and "
                                       << m_operand2->Eval(context) 
                                       << " ; dump is " << Description();
If I provided any code, scripts or other content here, it's released under GPL 2.0 and CC-BY-SA 3.0

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 13603
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: Number check

#3 Post by Geoff the Medio »

Dilvish wrote:This persisted even if I tried changing all the numbers in the script to doubles to try to stop it from triggering the int handling.
Problem is that it's expecting a ValueRef<int>, and that probably forces all the subsequent parsing to treat whatever it gets as a ValueRef<int>, which is allowed to be written as a double for constants... so writing "1.5" will be static_cast to int, then stored as a Constant<int> with internal value 1.
So, it suggests that instead of doing any automatic casts to ints perhaps we should an an explicit scripting int cast valueref and not otherwise do it, or at least not do it from a double to an int without an explicit cast.
There could be RoundUp(...) and RoundDown(...) casts, which convert ValueRef<double> to ValueRef<int>. There could also be a distinct operation type for square root, which would be scripted as sqrt(...) and would treat its operand as whatever type the main ValueRef is supposed to be, but wouldn't require a non-integer (0.5) to be written.
In all these though, I am also puzzled by the mismatch between the numbers in the first part of the log line and those in the second part ('dump') of the log line.
Do you mean "2" vs "2.00"? ValueRef<int>::Description uses DoubleToString to format its output.

User avatar
Dilvish
AI Lead and Programmer Emeritus
Posts: 4768
Joined: Sat Sep 22, 2012 6:25 pm

Re: Number check

#4 Post by Dilvish »

Geoff the Medio wrote:
Dilvish wrote:
In all these though, I am also puzzled by the mismatch between the numbers in the first part of the log line and those in the second part ('dump') of the log line.
Do you mean "2" vs "2.00"?
No, I mean seeing "2 and 3" instead of the "1 and 3" I would expect in the following:

Code: Select all

ValueRef<int> exponential requested for 2 and 3 ; dump is max(1, 1) ^ 3


or the "9041 and 0.5" instead of the "0.00 and 0.5" I would have expected in the following

Code: Select all

ValueRef<double> exponential requested for 9041 and 0.5 ; dump is max(0.00, 0.00) ^ 0.50
I mean, how does it get "9041" from "max(0.00, 0.00)"?
If I provided any code, scripts or other content here, it's released under GPL 2.0 and CC-BY-SA 3.0

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 13603
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: Number check

#5 Post by Geoff the Medio »

I think it's a problem with the description of multi-part operation ValueRefs... they use operand1 for both numbers in the description output for things like max(..,..) or min(..,..). Should be easy to fix.

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 13603
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: Number check

#6 Post by Geoff the Medio »

Geoff the Medio wrote:Should be easy to fix.
Should be fixed.

Post Reply