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.
Excruciating FOCS doubts
Moderators: Oberlus, Committer
Re: Excruciating FOCS doubts
Re: Excruciating FOCS doubts
Not sure if that matters, but I'm with Oberlus there.
- Geoff the Medio
- Programming, Design, Admin
- Posts: 13603
- Joined: Wed Oct 08, 2003 1:33 am
- Location: Munich
Re: Excruciating FOCS doubts
I pondered making Terror Suppression more effective for ships with bombardment parts. Might be an alternative to using combat strength related calculations.
Re: Excruciating FOCS doubts
That also makes sense.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.
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
Is there a way to query for class of part or for tags (and count them)?
- Geoff the Medio
- Programming, Design, Admin
- Posts: 13603
- Joined: Wed Oct 08, 2003 1:33 am
- Location: Munich
Re: Excruciating FOCS doubts
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.Oberlus wrote: ↑Sun Jun 06, 2021 1:03 pmThere is that condition:that checks if a ship has a given part. Does it return true/false or the actual count of the queried part?Code: Select all
DesignHasPart low = 1 high = 999 name = part_name DesignHasPart name = part_name
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.Is there a way to query for class of part or for tags (and count them)?
Re: Excruciating FOCS doubts
Great, I think that shall suffice.
Re: Excruciating FOCS doubts
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 :
And the macros it calls do not affect ship cost ?
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"
Re: Excruciating FOCS doubts
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
]))
'''
Re: Excruciating FOCS doubts
+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!
Look, ma... four combat bouts!
Re: Excruciating FOCS doubts
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
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
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:
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
]
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"]
]
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
]
- Geoff the Medio
- Programming, Design, Admin
- Posts: 13603
- Joined: Wed Oct 08, 2003 1:33 am
- Location: Munich
Re: Excruciating FOCS doubts
It gets the resource supply connected groups for the specified empire, and checks that the objects are in the same connected group.
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.Here Source is a species, I think, and Source.Owner should be the empire that owns the species.
For techs and policies, Source is the capital of the empire that researched or adopted the tech or policy.Source is the policy, I think, and its owner is the empire that adopted it.
I think they are interchangable / equivalent in those uses.Why use LocalCandidate.Owner instead of Source.Owner for "empire" in Centralization?
Capital is a self-contained condition that matches just empire capitals, not regional admins.does Capital work as a macro for Or [ Capital Building = "BLD_REGIONAL_ADMIN"] or something?
It doesn't.I don't understand how the Centralization influence penalty from distance to Capital is considering regional centers
Re: Excruciating FOCS doubts
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 ?
Thanks in advance !
For example, to test if a ship is inside a field ?
Just
Code: Select all
scope
isinfield field name=meteorswarm
Thanks in advance !
Re: Excruciating FOCS doubts
Since apparently truepurple gets answer by repeating again and again the same questions :
Also :
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 :
Then the two others are 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" ] ]
Note the lack of "Activation = random probability = 0.n "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" ] ]
And the choice of Extinct Species is coded that way :
So, for Extinct Species, we have a 75% chance of getting any Extinct Species at all.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" ] ] ]
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 ?
Re: Excruciating FOCS doubts
Code: Select all
default/scripting/species/SP_NYMNMN.focs.txt: condition = Field name = [ "FLD_ION_STORM" "FLD_METEOR_BLIZZARD" "FLD_NANITE_SWARM" ]
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!
Look, ma... four combat bouts!
- Geoff the Medio
- Programming, Design, Admin
- Posts: 13603
- Joined: Wed Oct 08, 2003 1:33 am
- Location: Munich
Re: Excruciating FOCS doubts
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: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 syntaxCode: Select all
effects = ExactlyOneOfThese [ Event probability = 0.33 effects = [ ... ] // extinct Banforo Event probability = 0.33 effects = [ ... ] // extinct Kilandow DefaultEvent effects = [ ... ] // extinct Misiorla ]
-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.