FreeOrion

Forums for the FreeOrion project
It is currently Sun May 27, 2018 7:25 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sat Jan 13, 2018 6:21 pm 
Online
Programming, Design, Admin
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 12197
Location: Munich
I'm not sure where to put this post, but given the SetVisibility Issues thread in this forum, perhaps this belongs here as well.

I've recently been working on moving standard per-turn meter growth / decay from C++ into FOCS: https://github.com/freeorion/freeorion/pull/1941 This would be nice, as it moves more game logic out of C++ and would allow more varied meter growth / decay systems to be tested or used.

This is basically working so far, except that it takes an extra turn for any changes in target or max meters to lead to changes in the associated active meters, when those active meter changes are dependent on the value of the target or max meter. For example, if one changes from research to industry focus, there will be an immediate decrease in research due to the focus-change penalty, which doesn't depend on what the value of the target meter is... the research meter is just decreased by 1 immediately. It takes an extra turn for the industry meter to start increasing, though.

This occurs because the script that calculates how much the industry meter should increase depends on the value of the target industry meter, and during the turn when a player is changing focus, any evaluation of "Target.TargetIndustry" will return the initial value of that meter on that turn, before the focus change happened.

This is implemented this way so that references to other meter values in scripts don't depend on the order of evaulation of effects that alter meters; the script evaluation always gets a consistent result from referencing a meter value, which is the value it had on the previous turn, but not the value on the current turn that is being calculated by numerous different effects adding modifications to meter values that sum together or multiply. This was more important before effects priorities were implemented, but still important to how meter calculations that depend on other meter values work.

For the case of changing meters after focus changes, this is a bit awkward though, in that on the turn of the focus change, any scripted meter increase or decrease will be evaluated using the target meter values at the start of the turn, rather than the target meter values after the focus change takes effect. This means it takes a full extra turn before an active meter will start growing after the player switches to that meter's focus.

In this post, I'm pondering what to do about this... as it would be preferable to have meters immediately respond to focus changes (other than the focus change penalty).

A possibility would be to have some new FOCS syntax for specifying that the current value of a meter, rather than the initial value from the start of the turn, is needed.

There is already a way to do this within SetMeter effects, but just for the meter being set: reference "Value". This lets one write "SetTargetIndustry value = Value + 5" instead of "SetTargetIndustry value = Target.TargetIndustry + 5". It also lets the meter accumulation actually work by combining multiple effects. If "Target.TargetIndustry" was referenced instead of "Value" within a SetTargetIndustry effect, it would always return the value at the start of the turn, and multiple different effects adding to a meter with SetMeter effects would overwrite rather than combine their results.

"value = Value + 5" works fine for referencing the value of the meter being set, but is limited to only that meter. There's no way to get the current value of any other meter in a script, besides the meter being set in SetMeter. All other meter references will return the initial value for that meter.

I'm not sure what syntax would work well for this for referencing current values of other meters, though.

Something like "value = Value + Source.TargetIndustry.ImmediateValue" could work, but is awkward to implement given how the ValueRef evaluation works, as it will currently treat "ImmediateValue" as the property, and "TargetIndustry" as a container object, like System in "Source.System.Stealth".

Alternatively, there could be two ways to reference each meter, one with and one without "ImmediateValue" at the end, like "value = Value + Target.TargetIndustryImmediateValue", where if this appeared in a SetTargetIndustry effect, it would be the same as "value = Value + Value" or "value = 2*Value".

It could also be implemented as a ComplexValueRef, so one would write something like "ImmediateTargetIndustry object = Target.ID".

Alternatively, there could be something built into effects priorities that would cause a meter backpropegation between some of the effects executions, so that the current / immediate values would become the initial values and thus be returned by the existing scripting format.

In the above, I think I prefer "Immediate" to "Current" as the latter has been used to refer to non-max non-target meters, or what I called the active paired meters.


Top
 Profile  
 
PostPosted: Sat Jan 13, 2018 8:23 pm 
Offline
Vacuum Dragon
User avatar

Joined: Mon Apr 10, 2017 4:25 pm
Posts: 539
Geoff the Medio wrote:
I think I prefer "Immediate" to "Current"
Maybe "Now" (and also Initial for the other meter, if ambiguity is not your friend)?. Target.TargetIndustryNow.


Top
 Profile  
 
PostPosted: Sun Jan 14, 2018 8:00 am 
Offline
Space Floater

Joined: Sat Jul 01, 2017 4:54 am
Posts: 35
So my understanding of this from what you have said:

For any given meter, there is the "value" that was computed by the next turn operations. There is a "second value" that is modified by FOCS. Which can be further modified by FOCS triggered by user (or AI). But this "second value" is not visible to FOCS that do not directly modify the "value".

Geoff the Medio wrote:
This lets one write "SetTargetIndustry value = Value + 5" instead of "SetTargetIndustry value = Target.TargetIndustry + 5". It also lets the meter accumulation actually work by combining multiple effects.


So you are saying if you just have 4 multiple EffectsGroup that are all active but each do
"SetTargetIndustry value = Target.TargetIndustry + 5"
next turn you will have +5 TargetIndustry not not +20 TargetIndustry?


You are looking to name this "second value"?
Geoff the Medio wrote:
It also lets the meter accumulation actually work by combining multiple effects


Target.TargetIndustry
Target.TargetIndustryAccumalator


Top
 Profile  
 
PostPosted: Sun Jan 14, 2018 11:43 am 
Offline
Release Manager, Design
User avatar

Joined: Wed Nov 16, 2011 12:56 pm
Posts: 4497
Location: Sol III
Geoff the Medio wrote:
I'm not sure where to put this post, but given the SetVisibility Issues thread in this forum, perhaps this belongs here as well.
For the reason you cited, and because it's probably a rather pressing issue, I think posting here is fine.
Quote:
Alternatively, there could be something built into effects priorities that would cause a meter backpropegation between some of the effects executions, so that the current / immediate values would become the initial values and thus be returned by the existing scripting format.
This.

I'd even go further and suggest to have several "phases" of effect execution during turn resolution ("end of old turn", "pre-combat", "post-combat", "begin of new turn", etc.). That would allow us to not only address this issue, but other limitations/ackwardnesses of the current effect execution implementation, like field or certain building effects always kicking in/expiring with a one turn delay.


Top
 Profile  
 
PostPosted: Sun Jan 14, 2018 3:26 pm 
Online
Programming, Design, Admin
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 12197
Location: Munich
Adding multiple stages of effect execution is a bit more involved than I want to spend time on now. And even if it is implemented, I'd guess that being able to reference the current / immediate vale of a meter would still be useful.

Another idea: "value = Value(Target.TargetIndusty)".

As now, just "Value" would be the immediate value of whatever is being modified by an effect. Wrapping another reference in "Value()" would get the immediate value of whatever it contains.


Top
 Profile  
 
PostPosted: Sun Jan 14, 2018 4:14 pm 
Offline
AI Lead, Programmer
User avatar

Joined: Sat Sep 22, 2012 6:25 pm
Posts: 4620
Geoff the Medio wrote:
Another idea: "value = Value(Target.TargetIndusty)".
That looks like a good idea to me.

_________________
If I provided any code, scripts or other content here, it's released under GPL 2.0 and CC-BY-SA 3.0


Top
 Profile  
 
PostPosted: Tue Jan 16, 2018 11:29 pm 
Online
Programming, Design, Admin
User avatar

Joined: Wed Oct 08, 2003 1:33 am
Posts: 12197
Location: Munich
Dilvish wrote:
Geoff the Medio wrote:
Another idea: "value = Value(Target.TargetIndusty)".
That looks like a good idea to me.

This is implemented in the branch. Most meter-modifications are also moved into scripted effects, excluding some ship resource meters that I'm not sure where to put in scripts. Some testing to see what this has broken would be helpful.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group