How do I reference a Ship's age in EffectsGroup?

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

Moderators: Oberlus, Committer

Post Reply
Message
Author
Chriss
Dyson Forest
Posts: 231
Joined: Sun May 11, 2008 10:50 am

How do I reference a Ship's age in EffectsGroup?

#1 Post by Chriss »

I'd like to introduce young, mature and ancient dyson trees, similar to what other monsters do, but with the transition based on the age of the tree. That does not quite work. As soon as I reference Age in the Scope, the Conditions is invalid.

This is the whole Hull code, the relevant EffectsGroup is at the bottom.

Code: Select all

Hull
    name = "SH_YOUNG_TREE_BODY"
    description = "SH_YOUNG_TREE_BODY_DESC"
    speed = 0
    starlaneSpeed = 0
    fuel = 0
    stealth = 5
    structure = 50
    slots = Slot type = External position = (0.30, 0.15)
    buildCost = 1
    buildTime = 2
    Unproducible
    location = All
    effectsgroups = [
        [[EXCELLENT_VISION]]

        EffectsGroup    // remove self and recreate on first turn, so that trees start with age 0, and thus low initial health, instead of having thousands of structure at start of game
            scope = Source
            activation = Turn high = 2
            effects = [
                CreateShip "SM_YOUNG_TREE"
                Destroy
            ]

        EffectsGroup    // grow larger / stronger with age
            scope = Source
            effects = [
                SetMaxStructure Value + Source.Age*3
                SetStructure Value + 7
            ]

        EffectsGroup    // spawn floaters to reproduce
            scope = Source
            activation = Random probability = 0.03
            stackinggroup = "TREE_GROWTH"
            effects = CreateShip "SM_FLOATER"

        EffectsGroup
            scope = And [
                Object Source.FleetID
                Fleet
            ]
            effects = SetAggressive
        
        EffectsGroup    // mature into medium TREE
            scope = And [
                Source
                Turn low = 5 high = 9999 // Source.Age or Age does not work
            ]
            activation = Random probability = 1
            //stackinggroup = "KRILL_1_ACTION_STACK"
            effects = [
                CreateShip "SM_MATURE_TREE"
                Destroy
                /*
                GenerateSitRepMessage
                    message = "EFFECT_MONSTER_SPAWNING"
                    parameters = [
                        tag = "predefinedshipdesign" data = "SM_KRILL_2"
                        tag = "system" data = Source.SystemID
                    ]
                */
            ]

    ]
    icon = ""
    graphic = "icons/monsters/tree.png"
It works out so far, and with the turn based setting the tree matures. But if I try Source.Age or Age instead of Turn, freeoriond complains:

Code: Select all

2014-08-31 19:39:04,481 ERROR Server : [...]/default/ship_hulls.txt:3414:24: Parse error.  Expected Condition here:
                Object Source.FleetID
                Fleet
            ]
            effects = SetAggressive
        
        EffectsGroup    // mature into medium TREE
                        ^
            scope = And [
                Source
                Age low = 5 high = 9999
            ]
            activation = Random probability = 1
Any ideas how to make this work?
Attached patches are released under GPL 2.0 or later.

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

Re: How do I reference a Ship's age in EffectsGroup?

#2 Post by Geoff the Medio »

"Age" is not a condition. Something.Age is a property that returns an int-valued number.

What you need to do is write a condition that takes a property of an object as a parameter and tests it to select objects for the scope of the effect.

The most immediately reasonable choice seems to me to be the Turn condition, and to use "low = Source.CreationTurn + 5" or somesuch. This might be quirky as objects created at the start of the game might have unexpected creation turns, so wrapping in min() or max() might be helpful.

Alternatively, you could use "ValueTest low = 5 testvalue = Source.Age".

(Untested suggestions, but should be close to the right idea...)

Chriss
Dyson Forest
Posts: 231
Joined: Sun May 11, 2008 10:50 am

Re: How do I reference a Ship's age in EffectsGroup?

#3 Post by Chriss »

So how do I write a Condition? I thought low and high would do that? Or does that only work with Turn?

Or with other words: There is a "compare operator" Turn low = <int> high = <int> which return a boolenan? But no <int> low = <int> high = <int> return boolean operator? I either don't get the Effects wiki on that, or it does not apply to this question.

Or does a "Condition" always return a set of objects? Similar to a SQL Query? You probably work with ObjectIDs?

Edit: Turn low = Source.CreationTurn + 5 and so on seems to work...
Attached patches are released under GPL 2.0 or later.

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

Re: How do I reference a Ship's age in EffectsGroup?

#4 Post by Geoff the Medio »

Chriss wrote:So how do I write a Condition?
As in how do you put a condition in a script, or how do you add a new condition? The latter requires C++ coding. The former is done like all the other conditions... put its name and any necessary parameters.
I thought low and high would do that? Or does that only work with Turn?
Several conditions have low and high parameters, including Turn.
There is a "compare operator" Turn low = <int> high = <int> which return a boolenan? But no <int> low = <int> high = <int> return boolean operator? I either don't get the Effects wiki on that, or it does not apply to this question.
The question doesn't really make sense...
Or does a "Condition" always return a set of objects?
Yes. Conditions are used to select objects from the game universe. They can be combined with And, Or, and Not to refine the selection criteria.
You probably work with ObjectIDs?
Don't understand the question. Object ids are used in various places in the game, including as parameters to some conditions or effects...

Chriss
Dyson Forest
Posts: 231
Joined: Sun May 11, 2008 10:50 am

Re: How do I reference a Ship's age in EffectsGroup?

#5 Post by Chriss »

Well, I'm treating this as I would any programming language and am trying to grasp it's syntax, and how it's implemented. With the "compare operator" I mean something like a C++ style operator. But conceptually, I guess it is more like a SQL style select. I was thinking more along the lines of a Boolean Expression. Whatever yields true matches. Matlab has similar semantics where you can access subsets of an array based on a boolean expression or a boolean array. "Selector" would've probably been a more intuitive name for me than "Condition"... (Thinking aloud...)

With ObjectIDs I am trying to guess at the C++ implementation: Each Condition selects a number of Objects based on it's condition. An And is like a SQL (or set theory) Intersect on the ObjectIDs. An Or is a union. A not is a Minus... Does that fit?

Anyway. Is there a list of conditions? Is it easier to ask like I just did?

If the C++ Code for Conditions is in parser/ConditionParser<n>.cpp then I don't think I'm going to really understand it anytime soon...

In this case, the Turn Condition with Source.CreationTurn offset seems to do the trick. Otherwise I'll give ValueTest or Number a try...
Attached patches are released under GPL 2.0 or later.

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

Re: How do I reference a Ship's age in EffectsGroup?

#6 Post by Geoff the Medio »

Chriss wrote:With ObjectIDs I am trying to guess at the C++ implementation: Each Condition selects a number of Objects based on it's condition.
???... and ??? again.
Is there a list of conditions?
There is an incomplete list in the wiki. For a full list, you'd have to look at the parser files. The individual condition parsers generally start with something like "tok.OwnedBy_" which means you'd write "OwnedBy" in the script file to use the condition. Any parameter definitions follow, such as "parse::label(Empire_token)" which indicates a parameter with the name "empire". If it's wrapped in -() then it's optional.
If the C++ Code for Conditions is in parser/ConditionParser<n>.cpp then I don't think I'm going to really understand it anytime soon...
The parser files just contain, fittingly, the parsers, which is what recognizes what's written in the scripts and creates the C++ representation. The actual evaluation of conditions is in the Eval, Match, and SimpleMatch functions / struct in Condition.cpp.

Chriss
Dyson Forest
Posts: 231
Joined: Sun May 11, 2008 10:50 am

Re: How do I reference a Ship's age in EffectsGroup?

#7 Post by Chriss »

How much effort would it be to create an editor for those files? Since the documentation is incomplete, and the error messages are sometimes way off...

For example: I botch up the SR_WEAPON_1_1 tech, so its syntax is invalid. Freeorion fails to start with the Error message:

Code: Select all

[chris@chris-u38n-arch build]$ ./freeorion 
main() caught exception(std::runtime_error): ERROR: Tech "DEF_PLANET_CLOAK" requires a missing or malformed tech "SPY_STEALTH_3" as its prerequisite.
It is quite hard sometimes. Since the parser is already there, maybe it is not that much effort?

Btw: TechsParser.cpp does not compile with

Code: Select all

#define DEBUG_PARSERS 1
Attached patches are released under GPL 2.0 or later.

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

Re: How do I reference a Ship's age in EffectsGroup?

#8 Post by Geoff the Medio »

Chriss wrote: Since the documentation is incomplete, and the error messages are sometimes way off...

For example: I botch up the SR_WEAPON_1_1 tech, so its syntax is invalid. Freeorion fails to start with the Error message:

Code: Select all

[chris@chris-u38n-arch build]$ ./freeorion 
main() caught exception(std::runtime_error): ERROR: Tech "DEF_PLANET_CLOAK" requires a missing or malformed tech "SPY_STEALTH_3" as its prerequisite.
That command line output is just the reason FreeOrion crashed. The actual error output would be in the log files (freeorion.log or freeoriond.log).
How much effort would it be to create an editor for those files?
Could you be more specific? What sort of editor?

User avatar
MatGB
Creative Contributor
Posts: 3310
Joined: Fri Jun 28, 2013 11:45 pm

Re: How do I reference a Ship's age in EffectsGroup?

#9 Post by MatGB »

Chriss, the Effects page on the Wiki is what I went on when I started learning, I then went through code and reread stuff, it is however both out of date (some syntaxes have changed) and missing stuff (new stuff has been introduced, specifically due to be introduced soon in the actual scripts is a check for turns since an individual ship was in a fight that's completely undocumented except on here).

Now that I can edit the wiki, one of the things I want to do is get as much of the documentation as I understand up-to-date, that's something better done by people like us (that need to use it) than, for example, Geoff, who frankly I'd rather see creating new features for me to play with.

Specifically for what you're looking for, the Nanorobotic, Logistics Facilitator and, um, the last Cellular Growth Chamber organic line hull all have variants that check how old they are, as does the Dyson Forest, but as that destroys itself on the first turn it can look a bit strange.

If you find stuff in the wiki that's wrong, or not there that should be, let me know and I'll add it to the list of things that need updating. And I need to get into the habit of editing in bits I find useful or when I see someone has added a new bit.
Mat Bowles

Any code or patches in anything posted here is released under the CC and GPL licences in use for the FO project.

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

Re: How do I reference a Ship's age in EffectsGroup?

#10 Post by Dilvish »

Chriss wrote:How much effort would it be to create an editor for those files?
qsswin had started a custom language file for NotePad++ which should help (though it may be somewhat out of date now), I expect it is worth trying -- it can be found here.
If I provided any code, scripts or other content here, it's released under GPL 2.0 and CC-BY-SA 3.0

Chriss
Dyson Forest
Posts: 231
Joined: Sun May 11, 2008 10:50 am

Re: How do I reference a Ship's age in EffectsGroup?

#11 Post by Chriss »

Freeoriond.log was empty (old) in that case, and freeorion.log contained the same error, not more.

Code: Select all

[...]
2014-09-01 21:56:13,823 DEBUG Client : (Game Concepts) : Fleet Upkeep
2014-09-01 21:56:13,823 DEBUG Client : (Game Concepts) : AI Aggression Levels
2014-09-01 21:56:14,159 ERROR Client : ERROR: Tech "DEF_PLANET_CLOAK" requires a missing or malformed tech "SPY_STEALTH_3" as its prerequisite.
2014-09-01 21:56:14,160 ERROR Client : main() caught exception(std::runtime_error): ERROR: Tech "DEF_PLANET_CLOAK" requires a missing or malformed tech "SPY_STEALTH_3" as its prerequisite.
I am having further issues, any ideas?
I wanted to change dyson trees so they do mine damage to all ships in the system. The basic damage effect is working, but I can't get the siterep message effect and the destroy ships with low enough health effect to work.

Code: Select all

2014-09-01 21:48:11,725 ERROR Server : /home/chris/freeorion-workdir/freeorion-svn/freeorion/FreeOrion/build/default/ship_hulls.txt:3297:24: Parse error.  Expected Condition here:
                        tag = "system" data = Target.SystemID
                    ]
                    empire = Target.Owner
            ]*/

        EffectsGroup    // Destroy Ships with low health and create SiteRep Message
                        ^
            scope = And [
                Ship
                ContainedBy Source.SystemID
                Not Monster
                Structure high = 2
The Tree code is the following:

Code: Select all

    effectsgroups = [
        [[EXCELLENT_VISION]]

        EffectsGroup    // remove self and recreate on first turn, so that trees start with age 0, and thus low initial health, instead of having thousands of structure at start of game
            scope = Source
            activation = Turn high = 2
            effects = [
                CreateShip "SM_YOUNG_TREE"
                Destroy
            ]

        EffectsGroup    // grow larger / stronger with age
            scope = Source
            effects = [
                SetMaxStructure Value + Source.Age*3
                SetStructure Value + 7
            ]

        EffectsGroup    // spawn floaters to reproduce
            scope = Source
            activation = Random probability = 0.03
            stackinggroup = "TREE_GROWTH"
            effects = CreateShip "SM_FLOATER"

        EffectsGroup
            scope = And [
                Object Source.FleetID
                Fleet
            ]
            effects = SetAggressive
        
        EffectsGroup    // mature into medium TREE
            scope = And [
                Source
                Turn low = Source.CreationTurn + 30 high = 9999
                Turn low = 2 high = 9999
            ]
            activation = Random probability = 0.1
            //stackinggroup = "KRILL_1_ACTION_STACK"
            effects = [
                CreateShip "SM_MATURE_TREE"
                Destroy
                /*
                GenerateSitRepMessage
                    message = "EFFECT_MONSTER_SPAWNING"
                    parameters = [
                        tag = "predefinedshipdesign" data = "SM_KRILL_2"
                        tag = "system" data = Source.SystemID
                    ]
                */
            ]

        EffectsGroup    // Damage passing ships
            scope = And [
                    Ship
                    InSystem Source.SystemID
                    Not Monster
            ]
            effects = SetStructure Value - 2

/*        EffectsGroup    // Generate SiteRep Message for Tree Damage
            scope = And [
                Fleet
                ContainedBy System
            ]
            activation = Target.SystemID = Source.SystemID
            effects = [
                GenerateSitRepMessage
                    message = "EFFECT_MINES"
                    icon = "icons/sitrep/combat_damage.png"
                    parameters = [
                        tag = "empire" data = Target.Owner
                        tag = "fleet" data = Target.ID
                        tag = "rawtext" data = "2"
                        tag = "system" data = Target.SystemID
                    ]
                    empire = Target.Owner
            ]*/

        EffectsGroup    // Destroy Ships with low health and create SiteRep Message
            scope = And [
                Ship
                ContainedBy Source.SystemID
                Not Monster
                Structure high = 2
            ]
            effects = [
                GenerateSitRepMessage
                    message = "EFFECT_MINES_SHIP_DESTROYED"
                    icon = "icons/sitrep/combat_destroyed.png"
                    parameters = [
                        tag = "empire" data = Target.Owner
                        tag = "ship" data = Target.ID
                        tag = "system" data = Target.SystemID
                    ]
                    empire = Target.Owner
                Destroy
            ]

    ]
    icon = ""
    graphic = "icons/monsters/tree.png"
I tried adapting the code from mines with some ideas for conditions from Krill merge effects.

About the editor: A syntax highlighting File is definitely a good start. I was thinking more along the lines of a create-update-delete-gui based on the parser which displays all Objects with all allowed properties and lets you edit them. That is probably only feasible if it can be mostly generated from the Parser Syntax Definitions.
Attached patches are released under GPL 2.0 or later.

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

Re: How do I reference a Ship's age in EffectsGroup?

#12 Post by Geoff the Medio »

Chriss wrote:Freeoriond.log was empty (old) in that case, and freeorion.log contained the same error, not more.
You've only shown the last few lines. Is there not an error earlier in the file similar to the server error you posted below?

Code: Select all

ContainedBy Source.SystemID
ContainedBy takes another condition as a parameter, not an object id. You can make a condition that matches an object with a particular id using "Object Source.SystemID". It would probably be better to use "InSystem Source.SystemID" instead of the ContainedBy condition, though make sure that Source is always in a system (perhaps with an activation condition "InSystem" (with no parameters)) if doing that.
...displays all Objects with all allowed properties...
Displays all objects from what superset? The objects in a particular game universe?

Chriss
Dyson Forest
Posts: 231
Joined: Sun May 11, 2008 10:50 am

Re: How do I reference a Ship's age in EffectsGroup?

#13 Post by Chriss »

This is the whole freeorion.log. freeoriond.log does not exist. There's an ogre.log.
But I just noticed that the cause might be a missing ] that closes the effectsgroups block. At least that's the only way I can reproduce it right now.

Code: Select all

2014-09-02 09:15:47,936 DEBUG Client : Logger initialized
2014-09-02 09:15:47,936 DEBUG Client : v0.4.4+ [SVN 7688] CMake
2014-09-02 09:15:48,559 DEBUG Client : OpenAL initialized. Version 1.1 ALSOFT 1.16.0Renderer OpenAL SoftVendor OpenAL Community
Extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length

2014-09-02 09:15:48,800 DEBUG Client : (Category) Encyclopedia Articles:
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Peace
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Growth Focus
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Mining Focus
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Industry
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Research
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Happiness
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Infrastructure
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Defense
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Shields
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Troops
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Stealth
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Detection Strength
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Detection Range
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Organic Metabolism
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Lithic Metabolism
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Robotic Metabolism
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Phototrophic Metabolism
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Self-Sustaining Metabolism
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Telepathy
2014-09-02 09:15:48,800 DEBUG Client : (Game Concepts) : Xenophobic
2014-09-02 09:15:48,801 DEBUG Client : (Game Concepts) : Trade Focus
2014-09-02 09:15:48,801 DEBUG Client : (Game Concepts) : Protection Focus
2014-09-02 09:15:48,801 DEBUG Client : (Game Concepts) : Fuel
2014-09-02 09:15:48,801 DEBUG Client : (Game Concepts) : Supply
2014-09-02 09:15:48,801 DEBUG Client : (Game Concepts) : Outposts
2014-09-02 09:15:48,801 DEBUG Client : (Game Concepts) : Evacuation
2014-09-02 09:15:48,801 DEBUG Client : (Game Concepts) : Fleet Upkeep
2014-09-02 09:15:48,801 DEBUG Client : (Game Concepts) : AI Aggression Levels
2014-09-02 09:15:49,115 ERROR Client : ERROR: Tech "DEF_PLANET_CLOAK" requires a missing or malformed tech "SPY_STEALTH_3" as its prerequisite.
2014-09-02 09:15:49,116 ERROR Client : main() caught exception(std::runtime_error): ERROR: Tech "DEF_PLANET_CLOAK" requires a missing or malformed tech "SPY_STEALTH_3" as its prerequisite.
Geoff the Medio wrote:
...displays all Objects with all allowed properties...
Displays all objects from what superset? The objects in a particular game universe?
Everything that is defined in text files. Techs, Parts, Ship Hulls, Species, Fleets...
Attached patches are released under GPL 2.0 or later.

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

Re: How do I reference a Ship's age in EffectsGroup?

#14 Post by Geoff the Medio »

If you're seeing an error about a missing / malformed tech, it probably doesn't have anything to do with edits to ship_hulls.txt. Revert any techs.txt changes you've made.
Geoff the Medio wrote:
...displays all Objects with all allowed properties...
Displays all objects from what superset? The objects in a particular game universe?
Everything that is defined in text files. Techs, Parts, Ship Hulls, Species, Fleets...
Conditions don't match things in text files, they match objects in the game universe. But regardless, I don't understand how you want to "display" these scripted content bits or their properties, or how you would "edit" those properties.

Post Reply