How to add a variable to ships/parts?

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

Moderators: Oberlus, Committer

Message
Author
Telos
Space Squid
Posts: 50
Joined: Thu May 09, 2013 4:46 am

How to add a variable to ships/parts?

#1 Post by Telos »

I've been fiddling around with trying to script some of the organic ship changes I'd suggested in this old thread: https://freeorion.org/forum/viewtopic.p ... 69&p=87512

Currently, a ship's max structure is recalculated each turn from scratch, starting with hull structure, adding on effects of armor, reinforced hull tech, and, in the case of living organics, an organic growth bonus that is calculated by multiplying age by growth rate. Unfortunately, this doesn't allow much flexibility regarding how a ship's history might affect its growth, e.g., allowing higher structure for ships produced in a system with an appropriate building or star-color, faster growth for time spent near appropriately colored stars, or permanent injuries from heavy damage. It'd also be nice to have fairly similar functionality on a regenerative carapace ship-part, which ideally would gradually grow from scratch, be reduced by heavy ship damage, and would aid in rapid structure-regeneration just for damage to the carapace, but not to the rest of the ship.

The best way I can imagine to let a ship's history affect its max-structure in these ways is to store some information (e.g., a number representing the net impact of history on max-structure) with each ship, and/or with some part of it, as a variable that can be read and set. I've read through the scripting details guide, but haven't seen a way, within FOCS, to create arbitrary new variables or meters to have be stored with a ship or one of its parts. Is that possible?

In the case of parts, I could maybe kluge something that stores information in one of the part variables that is available to scripting, perhaps the "Capacity" variable used by armors. Am I right in thinking that armors' Capacity is *programmatically* added to max-structure? I can't find anywhere in the scripting files where this is explicitly added, in the way that Reinforced Hull and organic growth are both explicitly scripted to add to max-structure. To get this kluge to work, I'd need some variable whose value is retained from turn to turn (like a meter), and not some variable that reverts back to its default value every turn (like I fear Capacity may be).

In the case of ships, there is a readable variable Age. If this variable is modifiable, you could indirectly make a ship's history affect its max-structure by having it affect its Age: e.g., spending time around a yellow star might make an organic ship mature faster, or getting grievously injured could have the same effect as removing years of growth from its life. Is it possible to change a ship's "Age" in this way? (Probably not if Age is computed on demand by subtracting construction-turn from current-turn, unless construction-turn itself is over-writable.) And would overriding Age (or construction-turn) interfere with anything else that cares about it?

If I can't manually override a ship's Age, do ships have some other persisting variable that I could use to store relevant information instead?

Of course, if we can get this to work with parts, but not ships, then another kluge might be to force ships to have relevant parts, either by scripting addition of the relevant "part" to the ship (is that possible?) or else by practically forcing users to build some relevant part, e.g., an "organic heart" into relevant ships, so that part can then keep track of the fortunes and misfortunes that should cause lasting effects in a ship's size.

Ophiuchus
Programmer
Posts: 3427
Joined: Tue Sep 30, 2014 10:01 am
Location: Wall IV

Re: How to add a variable to ships/parts?

#2 Post by Ophiuchus »

From the top of my head i think you can add specials to a ship. And that one can have a capacity.

Also ship parts have two capacities which are used for the standard effects (armor +hp, weapons +shots/damage, bay launch capacity, hangar capacity, troop count). Maybe there is now even a third capacity.
Any code or patches in anything posted here is released under the CC and GPL licences in use for the FO project.

Look, ma... four combat bouts!

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

Re: How to add a variable to ships/parts?

#3 Post by Geoff the Medio »

As Ophiuchus suggests, it sounds like what you want to do could be accomplished by adding a special to the ship object, and tracking relevant info with the capacity of the special, and basing depending effects on that capacity. You'll need the SpecialCapacity complex-double-value-ref ( https://github.com/freeorion/freeorion/ ... r.cpp#L125 ) and the SetSpecialCapacity effect ( https://github.com/freeorion/freeorion/ ... 3.cpp#L107 ).

Capacity in various parts is used to generate effects that implement the basic function of that part type, unless NoDefaultCapacityEffect is specified in the part definition, eg. ( https://github.com/freeorion/freeorion/ ... ocs.txt#L6 ). The code that creates these effects is that is not specified is ( https://github.com/freeorion/freeorion/ ... n.cpp#L334 )

There is no SetAge effect.

Effects can't add parts to a design. Something weird with costs being calculated with a test for a part being in the design might work, but are not recommended.

Telos
Space Squid
Posts: 50
Joined: Thu May 09, 2013 4:46 am

Re: How to add a variable to ships/parts?

#4 Post by Telos »

Wow, I had no idea that ships even could have specials, nor that specials could have capacities. I don't think I've encountered either of those in-game. Is there an example of scripts doing this that I could look at?

When specials have capacities, are their values preserved from turn to turn, or do they reset to some default value each turn?

Lacking a good model to look at, I guess I'd need roughly the following steps to make organic ships grow more quickly in certain conditions?
  1. Add an effect to the relevant hulls that creates an "organic growth" special on the hull if it doesn't already have one, and sets the capacity of that special to 0.
  2. Add effects to the relevant hulls to detect various events that should make a ship grow more or less quickly (like being stationary near a yellow star), and make those cause changes in the special's capacity.
  3. Add an effect to the relevant hulls to add the special's capacity to the ship's max-structure in the recalculation of that max-structure each turn

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

Re: How to add a variable to ships/parts?

#5 Post by Geoff the Medio »

Telos wrote: Sat Jan 12, 2019 8:49 pmIs there an example of scripts doing this that I could look at?
I don't think so.
When specials have capacities, are their values preserved from turn to turn, or do they reset to some default value each turn?
If it's working as intended, yes. Might be buggy as the functionality isn't used much.
Add effects to the relevant hulls to detect various events
Or the special, depending how you want to organize things.

Jaumito
Space Kraken
Posts: 189
Joined: Tue May 16, 2017 3:42 am
Location: Catalonia, France, Europe, Earth, Sol, Orion Arm, Milky Way, Virgo Cluster

Re: How to add a variable to ships/parts?

#6 Post by Jaumito »

Something simple (I think) you might want to try to add flavor to the organic line: double their stealth rating (or add a flat bonus) when under 'Hide' orders.

Ophiuchus
Programmer
Posts: 3427
Joined: Tue Sep 30, 2014 10:01 am
Location: Wall IV

Re: How to add a variable to ships/parts?

#7 Post by Ophiuchus »

Also note that there is a PartCapacity condition to query the capacity of a part "design" (note this value is not ship dependent) - this allows for variants of parts with similar effect. E.g. in https://github.com/agrrr3/freeorion/blo ... S.focs.txt
Any code or patches in anything posted here is released under the CC and GPL licences in use for the FO project.

Look, ma... four combat bouts!

Ophiuchus
Programmer
Posts: 3427
Joined: Tue Sep 30, 2014 10:01 am
Location: Wall IV

Re: How to add a variable to ships/parts?

#8 Post by Ophiuchus »

Jaumito wrote: Sun Jan 13, 2019 3:31 pm Something simple (I think) you might want to try to add flavor to the organic line: double their stealth rating (or add a flat bonus) when under 'Hide' orders.
I am not sure if that is so easy to balance, but I definitly would like to have a variant of that for (at least some of) the monsters
Any code or patches in anything posted here is released under the CC and GPL licences in use for the FO project.

Look, ma... four combat bouts!

Telos
Space Squid
Posts: 50
Joined: Thu May 09, 2013 4:46 am

Re: How to add a variable to ships/parts?

#9 Post by Telos »

Ophiuchus wrote: Sun Jan 13, 2019 4:08 pm Also note that there is a PartCapacity condition to query the capacity of a part "design" (note this value is not ship dependent)
Yes, the non-ship-dependence is a problem I've been running into. I can (I think) change the capacity of a part I put on the ship, but I don't seem to be able to read the new value of that part's capacity the next turn, which I need to do. Is there a ship-specific way to query the capacity of a part *on*this*ship*?

Ophiuchus
Programmer
Posts: 3427
Joined: Tue Sep 30, 2014 10:01 am
Location: Wall IV

Re: How to add a variable to ships/parts?

#10 Post by Ophiuchus »

Telos wrote: Wed Jan 16, 2019 2:15 am
Ophiuchus wrote: Sun Jan 13, 2019 4:08 pm Also note that there is a PartCapacity condition to query the capacity of a part "design" (note this value is not ship dependent)
Yes, the non-ship-dependence is a problem I've been running into. I can (I think) change the capacity of a part I put on the ship, but I don't seem to be able to read the new value of that part's capacity the next turn, which I need to do. Is there a ship-specific way to query the capacity of a part *on*this*ship*?
There is no such thing as a capacity of a part *on*this*ship*. The PartCapacity belongs to the parts design not to the ship.

But like in my example you can make variants of a part with different capacities. This only makes sense if there is a small number of different fixed capacities.
In the example i linked i had supply parts in two different sizes.

PartCapacity is a constant for a part.

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

Look, ma... four combat bouts!

Telos
Space Squid
Posts: 50
Joined: Thu May 09, 2013 4:46 am

Re: How to add a variable to ships/parts?

#11 Post by Telos »

Ophiuchus wrote: Wed Jan 16, 2019 8:43 am There is no such thing as a capacity of a part *on*this*ship*. The PartCapacity belongs to the parts design not to the ship.
Well, it certainly *seems* like there is such a thing as a capacity for a part (or at least a part-type) on a particular ship. E.g., if you look in the FOCS for Solar Concentrator, it includes effects like the following:

Code: Select all

            effects = [
                SetMaxCapacity partname = "SR_WEAPON_2_1" value = Value + [[SOLAR_CONCENTRATOR_EFFECT]]
                SetCapacity partname = "SR_WEAPON_2_1" value = Value + [[SOLAR_CONCENTRATOR_EFFECT]]
            ]
This doesn't make sense if you read it as changing the Capacity for *all* lasers -- Solar Concentrators don't help every laser in existence! Instead it only makes sense if it affects the capacity of just the lasers on this one particular ship.

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

Re: How to add a variable to ships/parts?

#12 Post by Geoff the Medio »

Ships have meters for (unique) part types in their design. There are effects to set those meters, such capacity and max capacity (which are actually the same meters as damage and max damage), and secondary stat and max secondary stat.

https://github.com/freeorion/freeorion/ ... cs.txt#L54
https://github.com/freeorion/freeorion/ ... cs.txt#L45
https://github.com/freeorion/freeorion/ ... cs.txt#L26

Which meters a ship will have for a particular part depend on the type of that part... so weapons get a capacity/damage and secondary stat (shots per round of combat). Most other parts have nothing, or just have a capacity and max capacity meter. You can see what meters a ship has by right-clicking it in the objects list, and running the debug data dump, and then looking in the chat. At the end should be something like:

Code: Select all

part meters: SR_WEAPON_1_1 METER_MAX_CAPACITY: 4  SR_WEAPON_1_1 METER_MAX_SECONDARY_STAT: 1  SR_WEAPON_1_1 METER_CAPACITY: 4  SR_WEAPON_1_1 METER_SECONDARY_STAT: 1
The values of these meters are (more or less) determined by effects that set them, some of which originate in the corresponding ship part, based on the scripted part stats like capacity:
https://github.com/freeorion/freeorion/ ... n.cpp#L352

These meters generally already have a purpose related to the function of the corresponding part, though, so for a custom scripting situation that isn't consistent with standard part function for that class of part, using a special capacity might be a better approach.

Telos
Space Squid
Posts: 50
Joined: Thu May 09, 2013 4:46 am

Re: How to add a variable to ships/parts?

#13 Post by Telos »

It feels inefficient and needlessly convoluted to create a separate special to keep track of a changing capacity for a (type of) ship part on a particular ship, when (types of) ship parts already do have capacities and max-capacities for each ship. We can already use NoDefaultCapacityEffect to override the default effect, so there shouldn't need to be a problem with having a part that doesn't quite fit a standard function. It seems like most of this is there already. As far as I can tell, the biggest hurdle blocking scripters from making flexible use of part capacities is just that we don't have a ship-specific way of querying the current capacity of a part on that ship -- instead we just get whatever is defined as the default capacity for that part for all ships -- so if you use NoDefaultCapacityEffect, then there's no way to query the changing capacity to actually make it *do* anything. It would be awesome if there was something like CurrentCapacity partname = "FOO" ship = ID (where the optional ship parameter would default to either Target or to Source, if Target is not a ship).

If I do do the work-around with adding specials, what are the best practices for where I would script the specials? Do they need to be defined in their own file(s) in the Specials directory? Or could (and if so *should*) they be scripted in the very same file as the shippart for which they serve as a capacity?

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

Re: How to add a variable to ships/parts?

#14 Post by Geoff the Medio »

Telos wrote: Thu Jan 17, 2019 11:54 pmAs far as I can tell, the biggest hurdle blocking scripters from making flexible use of part capacities is just that we don't have a ship-specific way of querying the current capacity of a part on that ship...
The (apparent) lack of a way to access ship part meter values in FOCS is an oversight / unimplemented feature.

User avatar
Oberlus
Cosmic Dragon
Posts: 5704
Joined: Mon Apr 10, 2017 4:25 pm

Re: How to add a variable to ships/parts?

#15 Post by Oberlus »

Geoff the Medio wrote: Fri Jan 18, 2019 11:02 amThe (apparent) lack of a way to access ship part meter values in FOCS is an oversight / unimplemented feature.
I think that is more than understandable. Designs are never (can't be) perfect from the beginning.
Telos wrote: Thu Jan 17, 2019 11:54 pmAs far as I can tell, the biggest hurdle blocking scripters from making flexible use of part capacities is just that we don't have a ship-specific way of querying the current capacity of a part on that ship...
I think that is worth the effort to make a new step forward and make a complete design of this and other possible features that FOCS could benefit from and (at least) open a properly documented issue with the corresponding request on github, so that this can be tackled in the future by someone with the skills and time to improve the C++ code that would make it possible.
But we can't expect that current developers do it (the design and documentation) because they are already swamped in work, with many features still lacking that are more important/urgent/relevant to get to a version of FreeOrion closer to its intended final form (for example, improving the AI and implementing Government and Influence).

Post Reply