Excruciating FOCS doubts

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

Moderators: Oberlus, Committer

Post Reply
Message
Author
User avatar
Oberlus
Cosmic Dragon
Posts: 5714
Joined: Mon Apr 10, 2017 4:25 pm

Re: Excruciating FOCS doubts

#91 Post by Oberlus »

Ophiuchus wrote: Sun Jun 06, 2021 10:15 am That would make terror suppression cheaper and cheaper as you upgrade weapon tech. Using old vessels for terror suppression sounds ok to me.
You're right, the difference in damage from tier 1 to tier 4 weapons is big (5x stronger), as well as the difference in weapons per ship. That would mean that good-research+bad-production empires could use less ships than bad-research+good-production empires. I kinda like it that military tech progress implies cheaper terror suppression. I also like not encouraging lots of small ships.

User avatar
LienRag
Cosmic Dragon
Posts: 2148
Joined: Fri May 17, 2019 5:03 pm

Re: Excruciating FOCS doubts

#92 Post by LienRag »

Not sure if that matters, but I'm with Oberlus there.

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

Re: Excruciating FOCS doubts

#93 Post by Geoff the Medio »

I pondered making Terror Suppression more effective for ships with bombardment parts. Might be an alternative to using combat strength related calculations.

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

Re: Excruciating FOCS doubts

#94 Post by Oberlus »

Geoff the Medio wrote: Sun Jun 06, 2021 12:33 pm I pondered making Terror Suppression more effective for ships with bombardment parts. Might be an alternative to using combat strength related calculations.
That also makes sense.
But if not considering damage strentgh, at least considering the count of weapon parts (again to not necesarily force suppression terror empires to have many small ships). Maybe 1*#Non-bombardment-weapons-in-system + 3*#bombardment-weapons-in-system.
This assuming there is already a way in FOCS to count weapon parts of such types, maybe counting parts with PC_BOMBARD_PEDIA tag for one and PC_DIRECT_DAMAGE or FT_BAY_1_DESC&&PC_PEDIA_FIGHTER_HANGAR for the other, or queryng the classes (Bombards, and ShortRange or FighterBay+FighterHangar).
There is that condition:

Code: Select all

DesignHasPart low = 1 high = 999 name = part_name
DesignHasPart name = part_name
that checks if a ship has a given part. Does it return true/false or the actual count of the queried part?
Is there a way to query for class of part or for tags (and count them)?

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

Re: Excruciating FOCS doubts

#95 Post by Geoff the Medio »

Oberlus wrote: Sun Jun 06, 2021 1:03 pmThere is that condition:

Code: Select all

DesignHasPart low = 1 high = 999 name = part_name
DesignHasPart name = part_name
that checks if a ship has a given part. Does it return true/false or the actual count of the queried part?
Conditions match objects (Ships, Planets, Systems, Buildings, Fleets, Fields). They don't return numbers or booleans. The Match functions of many conditions do return true/false, but those are a C++ implementation detail, not directly accessible to FOCS.
Is there a way to query for class of part or for tags (and count them)?
You can use the PartsInShipDesign ValueRef to get how many of a particular part are in a ship design (specified by design ID), or PartOfClassInShipDesign to do the same for parts of a specified part class.

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

Re: Excruciating FOCS doubts

#96 Post by Oberlus »

Great, I think that shall suffice.

User avatar
LienRag
Cosmic Dragon
Posts: 2148
Joined: Fri May 17, 2019 5:03 pm

Re: Excruciating FOCS doubts

#97 Post by LienRag »

I believe that I asked this question already (on another thread) but didn't get any answer : where is the code that makes Design Simplicity work ?

The FOCS file is nearly empty :

Code: Select all

Policy
    name = "PLC_DESIGN_SIMPLICITY"
    description = "PLC_DESIGN_SIMPLICITY_DESC"
    short_description = "PLC_DESIGN_SIMPLICITY_SHORT_DESC"
    category = "MILITARY_CATEGORY"
    adoptioncost = floor(5 + 0.25 * Statistic Sum value = LocalCandidate.Population condition = And [ Planet OwnedBy empire = Source.Owner ])
    effectsgroups = [
        [[SPECIES_LIKES_OR_DISLIKES_POLICY_STABILITY_EFFECTS]]
    ]
    graphic = "icons/policies/design_simplicity.png"

#include "/scripting/policies/policies.macros"
#include "/scripting/common/priorities.macros"
And the macros it calls do not affect ship cost ?

wobbly
Cosmic Dragon
Posts: 1876
Joined: Thu Oct 10, 2013 6:48 pm

Re: Excruciating FOCS doubts

#98 Post by wobbly »

LienRag wrote: Sun Jun 06, 2021 10:28 pm I believe that I asked this question already (on another thread) but didn't get any answer : where is the code that makes Design Simplicity work ?
Perhaps you need to learn how to use grep, "find in files" or whatever the command is in your text editor. Anyway, it's in upkeep.macros

Code: Select all

DESIGN_SIMPLICITY_POLICY_MULTIPLIER
'''(1 - 0.2*(Statistic If condition = And [
    EmpireHasAdoptedPolicy name = "PLC_DESIGN_SIMPLICITY"
    ((PartsInShipDesign design = UsedInDesignID) <= 6)  // Used in part or hull cost expressions, in which "UsedInDesignID" will contain the ID of the ship design in which the part is being used
]))
'''

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

Re: Excruciating FOCS doubts

#99 Post by Ophiuchus »

Oberlus wrote: Sun Jun 06, 2021 1:03 pmMaybe 1*#Non-bombardment-weapons-in-system + 3*#bombardment-weapons-in-system.
+1
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
Oberlus
Cosmic Dragon
Posts: 5714
Joined: Mon Apr 10, 2017 4:25 pm

Re: Excruciating FOCS doubts

#100 Post by Oberlus »

ResourceSupplyConnected empire = EMPIRE conditon = CONDITION

EMPIRE is for the owner of the supply lines to use in the connectivity check, right?


In happiness.macros we have

Code: Select all

        ResourceSupplyConnected empire = Source.Owner condition = And [
            Or [Capital Building name = "BLD_REGIONAL_ADMIN"]
            OwnedBy empire = Source.Owner
        ]
Here Source is a species, I think, and Source.Owner should be the empire that owns the species.

Then in CENTRALIZATION.focs.txt we have

Code: Select all

                Not ResourceSupplyConnected empire = LocalCandidate.Owner condition = And [
                    Planet
                    Or [Capital Building name = "BLD_REGIONAL_ADMIN"]
                ]
Source is the policy, I think, and its owner is the empire that adopted it. And this piece of code is in the scope. LocalCandidate are each of the objects to match, I think.
Why use LocalCandidate.Owner instead of Source.Owner for "empire" in Centralization?


Another doubt: does Capital work as a macro for Or [ Capital Building = "BLD_REGIONAL_ADMIN"] or something? I don't understand how the Centralization influence penalty from distance to Capital is considering regional centers if it doesn't check for BLD_REGIONAL_ADMIN:

Code: Select all

                ResourceSupplyConnected empire = LocalCandidate.Owner condition = And [
                    Planet
                    OwnedBy empire = Source.Owner
                    Capital
                ]

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

Re: Excruciating FOCS doubts

#101 Post by Geoff the Medio »

Oberlus wrote: Mon Jun 21, 2021 5:17 pm ResourceSupplyConnected empire = EMPIRE conditon = CONDITION

EMPIRE is for the owner of the supply lines to use in the connectivity check, right?
It gets the resource supply connected groups for the specified empire, and checks that the objects are in the same connected group.
Here Source is a species, I think, and Source.Owner should be the empire that owns the species.
Source is always an object, which might be a planet or a ship in the case of a Species definition. Each source object is an object (planet or ship) that has that species on it. Source.Owner is the empire that owns the object.
Source is the policy, I think, and its owner is the empire that adopted it.
For techs and policies, Source is the capital of the empire that researched or adopted the tech or policy.
Why use LocalCandidate.Owner instead of Source.Owner for "empire" in Centralization?
I think they are interchangable / equivalent in those uses.
does Capital work as a macro for Or [ Capital Building = "BLD_REGIONAL_ADMIN"] or something?
Capital is a self-contained condition that matches just empire capitals, not regional admins.
I don't understand how the Centralization influence penalty from distance to Capital is considering regional centers
It doesn't.

User avatar
LienRag
Cosmic Dragon
Posts: 2148
Joined: Fri May 17, 2019 5:03 pm

Re: Excruciating FOCS doubts

#102 Post by LienRag »

Geoff, thanks for making a new "field" condition, but could you please tell me how to actually use it ?

For example, to test if a ship is inside a field ?
Just

Code: Select all

scope 
isinfield field name=meteorswarm
?


Thanks in advance !

User avatar
LienRag
Cosmic Dragon
Posts: 2148
Joined: Fri May 17, 2019 5:03 pm

Re: Excruciating FOCS doubts

#103 Post by LienRag »

Since apparently truepurple gets answer by repeating again and again the same questions :
LienRag wrote: Fri Apr 30, 2021 7:26 pm I noticed that there is a "tag = monster" but apparently monsters do not have it ?

Also :
LienRag wrote: Wed May 26, 2021 5:41 pm I'm not sure to understand the FOCS code of the Ancient Ruins ?

The various possible results of Excavation are, for the first three, coded that way :

Code: Select all

        EffectsGroup
            scope = Source
            activation = And [
                Random probability = .2
                OwnerHasTech name = "LRN_XENOARCH"
            ]
            stackinggroup = "ANCIENT_RUINS_TECH_UNLOCK"
            effects = [
                CreateShip designname = "SD_DRAGON_TOOTH" empire = Source.Owner species = Source.Species
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_SHIP"
                    label = "EFFECT_ANCIENT_SHIP_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "planet" data = Source.ID
                        tag = "predefinedshipdesign" data = "SD_DRAGON_TOOTH"
                    ]
                    empire = Source.Owner
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_SHIP_RUMORS"
                    label = "EFFECT_ANCIENT_SHIP_RUMORS_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "predefinedshipdesign" data = "SD_DRAGON_TOOTH"
                    ]
            ]

        EffectsGroup
            scope = Source
            activation = And [
                Random probability = 0.25
                OwnerHasTech name = "LRN_XENOARCH"
            ]
            stackinggroup = "ANCIENT_RUINS_TECH_UNLOCK"
            effects = [
                CreateBuilding type = "BLD_NEUTRONIUM_SYNTH"
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_BUILDING"
                    label = "EFFECT_ANCIENT_BUILDING_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "planet" data = Source.ID
                        tag = "buildingtype" data = "BLD_NEUTRONIUM_SYNTH"
                    ]
                    empire = Source.Owner
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_BUILDING_RUMORS"
                    label = "EFFECT_ANCIENT_BUILDING_RUMORS_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "buildingtype" data = "BLD_NEUTRONIUM_SYNTH"
                    ]
            ]

        EffectsGroup
            scope = Source
            activation = And [
                Random probability = 0.50
                NotOwnerHasTech name = "SHP_WEAPON_4_1"
                OwnerHasTech name = "LRN_XENOARCH"
            ]
            stackinggroup = "ANCIENT_RUINS_TECH_UNLOCK"
            effects = [
                GiveEmpireTech name = "SHP_WEAPON_4_1" empire = Target.Owner
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_TECH"
                    label = "EFFECT_ANCIENT_TECH_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "planet" data = Source.ID
                        tag = "tech" data = "SHP_WEAPON_4_1"
                    ]
                    empire = Source.Owner
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_TECH_RUMORS"
                    label = "EFFECT_ANCIENT_TECH_RUMORS_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "tech" data = "SHP_WEAPON_4_1"
                    ]
            ]
Then the two others are coded that way :

Code: Select all

        EffectsGroup
            scope = Source
            activation = And [
                Not OwnerHasTech name = "SHP_MULTISPEC_SHIELD"
                OwnerHasTech name = "LRN_XENOARCH"
            ]
            stackinggroup = "ANCIENT_RUINS_TECH_UNLOCK"
            effects = [
                GiveEmpireTech name = "SHP_MULTISPEC_SHIELD" empire = Target.Owner
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_TECH"
                    label = "EFFECT_ANCIENT_TECH_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
	                    parameters = [
                        tag = "planet" data = Source.ID
                        tag = "tech" data = "SHP_MULTISPEC_SHIELD"
                    ]
                    empire = Source.Owner
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_TECH_RUMORS"
                    label = "EFFECT_ANCIENT_TECH_RUMORS_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "tech" data = "SHP_MULTISPEC_SHIELD"
                    ]
            ]

        EffectsGroup
            scope = Source
            activation = And [
                Not OwnerHasTech name = "SHP_KRILL_SPAWN"
                OwnerHasTech name = "LRN_XENOARCH"
            ]
            stackinggroup = "ANCIENT_RUINS_TECH_UNLOCK"
            effects = [
                GiveEmpireTech name = "SHP_KRILL_SPAWN" empire = Target.Owner
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_TECH"
                    label = "EFFECT_ANCIENT_TECH_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "planet" data = Source.ID
                        tag = "tech" data = "SHP_KRILL_SPAWN"
                    ]
                    empire = Source.Owner
                GenerateSitRepMessage
                    message = "EFFECT_ANCIENT_TECH_RUMORS"
                    label = "EFFECT_ANCIENT_TECH_RUMORS_LABEL"
                    icon = "icons/specials_huge/ancient_ruins_excavated.png"
                    parameters = [
                        tag = "tech" data = "SHP_KRILL_SPAWN"
                    ]
            ]
Note the lack of "Activation = random probability = 0.n "

And the choice of Extinct Species is coded that way :

Code: Select all

        // Find extinct species
        EffectsGroup
            scope = Source
            activation = And [
                Random probability = 0.75
                OwnerHasTech name = "LRN_XENOARCH"
            ]
            effects = [
                If condition = Random probability = 0.33
                    effects = [ 
                        AddSpecial name = "EXTINCT_BANFORO_SPECIAL"
                        GenerateSitRepMessage
                            message = "EFFECT_ANCIENT_EXTINCT_SPECIES"
                            label = "EFFECT_ANCIENT_EXTINCT_SPECIES_LABEL"
                            icon = "icons/specials_huge/extinct_banforo.png"
                            parameters = [
                                tag = "planet" data = Source.ID
                                tag = "species" data = "SP_BANFORO"
                            ]
                            empire = Source.Owner
                         GenerateSitRepMessage
                            message = "EFFECT_ANCIENT_EXTINCT_SPECIES_RUMORS"
                            label = "EFFECT_ANCIENT_EXTINCT_SPECIES_RUMORS_LABEL"
                            icon = "icons/specials_huge/extinct_banforo.png"
                            parameters = [
                                tag = "species" data = "SP_BANFORO"
                            ]
                    ]
                else = If condition = Random probability = 0.5
                    effects = [ 
                        AddSpecial name = "EXTINCT_KILANDOW_SPECIAL"
                        GenerateSitRepMessage
                            message = "EFFECT_ANCIENT_EXTINCT_SPECIES"
                            label = "EFFECT_ANCIENT_EXTINCT_SPECIES_LABEL"
                            icon = "icons/specials_huge/extinct_kilandow.png"
                            parameters = [
                                tag = "planet" data = Source.ID
                                tag = "species" data = "SP_KILANDOW"
                            ]
                            empire = Source.Owner
                         GenerateSitRepMessage
                            message = "EFFECT_ANCIENT_EXTINCT_SPECIES_RUMORS"
                            label = "EFFECT_ANCIENT_EXTINCT_SPECIES_RUMORS_LABEL"
                            icon = "icons/specials_huge/extinct_kilandow.png"
                            parameters = [
                                tag = "species" data = "SP_KILANDOW"
                            ]
                    ]
                    else = [
                        AddSpecial name = "EXTINCT_MISIORLA_SPECIAL"
                        GenerateSitRepMessage
                            message = "EFFECT_ANCIENT_EXTINCT_SPECIES"
                            label = "EFFECT_ANCIENT_EXTINCT_SPECIES_LABEL"
                            icon = "icons/specials_huge/extinct_misiorla.png"
                            parameters = [
                                tag = "planet" data = Source.ID
                                tag = "species" data = "SP_MISIORLA"
                            ]
                            empire = Source.Owner
                        GenerateSitRepMessage
                            message = "EFFECT_ANCIENT_EXTINCT_SPECIES_RUMORS"
                            label = "EFFECT_ANCIENT_EXTINCT_SPECIES_RUMORS_LABEL"
                            icon = "icons/specials_huge/extinct_misiorla.png"
                            parameters = [
                                tag = "species" data = "SP_MISIORLA"
                            ]
                     ]
            ]
So, for Extinct Species, we have a 75% chance of getting any Extinct Species at all.
Then depending on a "dice roll", we have a one on three chance to get Banforo. Then we have a coin toss that decides whether we get Kilandow or Misioria. Since we have a coin toss on the 67% probability left, it means the three Extinct Species are equiprobable.

Also, there are no conditions for these opportunities (except of course Xenoarcheology). Which means that a player can discover many times Banforo remains, for example.


For the other goodies, the choice between them is made differently.
If I understand correctly, the reason why the "if-else" structure is not necessary there is because of the stackinggroup "ANCIENT_RUINS_TECH_UNLOCK" ?

For these goodies, we have 20 % probability to get a Dragon Tooth.
Then a 25 % probability to get a Neutronium Synthetizer.
Then a 50 % probability to get Death Rays.
Then a 100 % probability to get Multi-Spectral Shields.
Then a 100 % probability to get a Krill Spawner.

In the FOCS scripting detail it's written that "Multiple effects scripted into the same item will be evaluated in the order in which they appear. "

So, for the first Ancient Ruin excavation, there is a 20 % chance to get a Dragon Tooth, a 20 % (0,25*0,80) chance to get Neutronium Synthetizer, a 30 % (0,5*0,6) chance to get Death Rays, a 30 % chance to get MSS, and 0% chance to get Krill Spawner.

Am I correct ?
Why allow Krill Spawners only if MSS has already been discovered ?
Also, I don't want to bother calculating the matrix of probabilities for second excavations depending on what has been discovered in the first one, but it's clear that DT chance doesn't change while MSS chances rise with each discovery.
Is that intended ? Why ?

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

Re: Excruciating FOCS doubts

#104 Post by Ophiuchus »

LienRag wrote: Wed Jul 14, 2021 12:50 pm Geoff, thanks for making a new "field" condition, but could you please tell me how to actually use it ?

Code: Select all

default/scripting/species/SP_NYMNMN.focs.txt:                condition = Field name = [ "FLD_ION_STORM" "FLD_METEOR_BLIZZARD" "FLD_NANITE_SWARM" ]
As for the ancient ruins I think you got it mostly right I think. The effectgroups are evaluated in order because they are in the same file (and same priority). stackinggroup prevents later effects to happen.

My guess is nobody knows why krill spawner comes after the multi-spectral shields.

If-else effects are probably newer feature than stacking groups and probably on the top level easier to reason about (e.g. in 3/4th of cases there will be a resurrected species). A kind of (probability based) switch statement would be more clear regarding the final probabilities.
But nobody implemented one. Maybe you can suggest a syntax

Code: Select all

effects = ExactlyOneOfThese [
  Event probability = 0.33 effects = [ ... ]  // extinct Banforo
  Event probability = 0.33 effects = [ ... ]  // extinct Kilandow
  DefaultEvent effects = [ ... ] // extinct Misiorla
]
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: 13587
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: Excruciating FOCS doubts

#105 Post by Geoff the Medio »

Ophiuchus wrote: Wed Jul 14, 2021 1:55 pmA kind of (probability based) switch statement would be more clear regarding the final probabilities.
But nobody implemented one. Maybe you can suggest a syntax

Code: Select all

effects = ExactlyOneOfThese [
  Event probability = 0.33 effects = [ ... ]  // extinct Banforo
  Event probability = 0.33 effects = [ ... ]  // extinct Kilandow
  DefaultEvent effects = [ ... ] // extinct Misiorla
]
There is already a chance condition, so you could probably already construct something like with If-Else and Chance. But the suggestion here is not clear at all, particularly:
-Are you assuming just a single target object? What happens if there are multiples? Does it apply the same effect to all, or independently decide for each?
-If it picks an effect for an object, but that effect doesn't really apply to that object, so that nothing actually happens, it will end up doing not exactly one but rather none of these.
-How are those probabilities evaluated? Summed an normalized to 1, or successive independent checks? So 50% + 50% + default means 50% of the first and 25% of the latter two, or 50% of the first two and 0% of the default last?

Also, for that specific example, you could probably just have a single effect for most of it, but with OneOf("SP_BANFORO", "SP_KILANDOW", "SP_MISIORLA") for the inner ValueRef that specifies what species to apply, as long as the effectsgroup just needs to pick what species to apply at a single location.

Post Reply