Difference between revisions of "FOCS Scripting Tutorial"

From FreeOrionWiki
Jump to: navigation, search
(Step 1: What is your tech?)
(Order of Events During the Turn: adding info about newly researched techs)
 
(51 intermediate revisions by 12 users not shown)
Line 1: Line 1:
Texas Drek’s Downhome Effects Tutorial
+
This tutorial covers how to modify FreeOrion Content Script (FOCS) files.  For details on all of the possible values, see [[FOCS Scripting Details]].
  
So you want to write up a technology/building/special for FO?  Yeehaw: you are about to embark on an exciting adventure, with chills and thrills to rival any Hollywood blockbuster.
+
=Getting Started=
 +
All FOCS files are plain text files, though some contain extended characters, especially the language files.<br />
 +
When editing them a somewhat more advanced editor is necessary.  For example, on Windows, the Notepad and Wordpad editors can cause trouble, but [http://notepad-plus-plus.org/ the third party NotePad++ editor] should be fine.  An added benefit of using NotePad++ is that one of our contributors has made an [http://www.freeorion.org/forum/viewtopic.php?f=15&t=7161&hilit=focs+notepad&start=0 add-on to help with the FOCS syntax].
  
Creating a building or a special is basically the same process as writing up a technology, so from here on out I’ll refer to all of the above as “techs”.
+
When a reference is made to the ''default/'' directory, this refers to the Resources Files directory.<br />
 +
This directory varies on different systems and can be manually changed.<br />
 +
If you are unsure where this directory is:<br />
 +
Start FreeOrion &rarr; ''Options'' &rarr; ''Directories'' (next to last) &rarr; ''Resource Files''.<br />
  
==Step 1:   What is your tech?==
+
==Creating a new entry==
 +
;Create a new file in the default/scripting/buildings/ directory, name it '''TUTORIAL_ONE.focs.txt'''
 +
<pre style="color: blue; display: block">
 +
BuildingType
 +
    name = "BLD_TUTORIAL_ONE"
 +
    description = "BLD_TUTORIAL_ONE_DESC"
 +
    buildcost = 15
 +
    buildtime = 1
 +
    icon = ""
  
Give your tech a name and description, and figure out what you want it to do.  Hint:  In the next step you’re going to have to describe in exacting detail precisely what your tech does in a way that FreeOrion can understand.  That means your tech needs to do something the actual FreeOrion program is capable of doing.
+
</pre>
 +
:It is good practice to make sure the file ends with a blank line.
 +
This creates a very basic building type that could be built anywhere but has no effect.
  
Hence you need to know how FreeOrion v.3 works.  To discover how FO plays, read the requirements document and the effects document.  (instead of the requirements, you might just peek at the cliff notes intead, but the effects document is a must.)  Read tzlaine’s faq on the forum.  If you don’t want to read the documentation because it’s long and boring then stop at this step: We don’t need your “help” designing techs.  Feel free to post stuff in brainstorming, or contribute art, or whatever….but you really do need to read the docs if you want to build techs that we can use the actual game.
+
No player would be able to build this building however, as their empire does not know how.<br />
 +
For now, we will just give the knowledge to everyone at the start of the game:
 +
;Edit '''default/scripting/starting_unlocks/items.inf'''
 +
:Add the following line at the top
 +
<pre style="color: blue; display: block">Item type = Building name = "BLD_TUTORIAL_ONE"</pre>
  
If you have any questions about requirements or effects doc, ask away on the forum. Someone will answer.
+
If you start the game now and select the production screen at your home planet, you will see:
 +
<pre style="color: blue; display: block">ERROR: BLD_TUTORIAL_ONE</pre>
 +
Hover over that and the tooltip shows:
 +
<pre style="color: blue; display: block">ERROR: BLD_TUTORIAL_ONE_DESC</pre>
 +
This is because we have not told the game what our building should be labelled as, just to use the key reference of BLD_TUTORIAL_ONE.<br />
 +
Just like the filename, key references could be named anything, regardless of what label we want to use.<br />
 +
The ''name'' entry in the definition needs to be unique, but ''description'' can be shared among other entries if needed.
  
Here’s the tech I’ve come up with, for the purposes of this tutorial:
+
The key references are looked up based on the language selected, in one of the stringtables.<br />
 +
If an entry is not found, the game will use the default lookup as a fallback.<br />
 +
The default table is english, so we will just edit that one for now.
 +
;Edit '''default/stringtables/en.txt'''
 +
:Search for ''BLD_COL_SUPER_TEST_DESC''
 +
:On the next blank line enter the following
 +
<pre style="color: blue; display: block">
  
[code]
+
BLD_TUTORIAL_ONE
Drek’s Effects Tutorial
+
A new building type from the scripting tutorial.
A marvelous, high tech tutorial that enlightens all who read it.
+
Effect: +2 Max Science to all friendly worlds set to the Science Focus
+
[/code]
+
  
==Step 2:  Copy and paste the correct XML template from the effects document.==
+
BLD_TUTORIAL_ONE_DESC
 +
This is a brand new building type we just created.
  
The templates are: tech, building, and special.  
+
</pre>
 +
:Make sure there are blank lines before and after these new entries.
 +
If you are planning to share these changes with others, always make sure any entries you create in other stringtables are included in the default stringtable.
  
You’ll need to fill out the “fields” in the form.   Since “Drek’s Effects Turorial” is a technology, I’ll be filling out the technology XML form:
+
You now have a very basic building in the game, though it has no purpose.
  
[code]
+
Keep in mind that this is just for demonstration. Building definitions should not be common structures built on every planet or more than once on any planet, in general. Structures like power plants or medical facilities would be covered by the infrastructure mechanic.
<Tech>
+
      <name>NAME</name>
+
      <description>DESCRIPTION</description>
+
      <type>TYPE</type>
+
      <category>CATEGORY</category>
+
      <research_cost>RESEARCH_COST</research_cost>
+
      <research_turns>RESEARCH_TURNS</research_turns>
+
      <prerequisites>
+
          NAME0
+
          NAME1
+
          ...
+
          NAMEN
+
      </prerequisites>
+
      <unlocked_items>
+
          ITEM0
+
          ITEM1
+
          ...
+
          ITEMN
+
      </unlocked_items>
+
      EFFECTS_GROUP [optional]
+
  </Tech>
+
[/code]
+
  
NAME:  this a placeholder for the name of your technology.  The actual name of your technology will go into a “string table”, so you should just type out, in all caps without using spaces, a pithy name.
+
==Entry Files==
[code]
+
All of the FOCS entry files have a double extension of '''.focs.txt'''.<br />
<Tech>
+
These files will be loaded regardless of the rest of their filename, or how deeply nested in the sub-directory they are.
  <name>LEARN_DREK_TUTORIAL</name>
+
[/code]
+
DESCRIPTION:  this is another placeholder, this time for the description of your technology. Type out the same pithy name you did in the previous field, but this time append the word “DESC”.   You’ll be writing out the actual description later.
+
[code]
+
  <description>LEARN_DREK_TUTORIAL_DESC</description>
+
[/code]
+
TYPE: This is the type of technology.  In FreeOrion, there are three different types of techs:
+
* TT_THEORY  A theory.  A theory contains applications, and generally should have little or no effects.
+
* TT_APPLICATION  An application.  An application is contained by a theory, and has some sort of minor effect and/or unlocks a building.
+
* TT_REFINEMENT  A refinement.  A refinement is contained by a theory, and often refines a building or shippart.  As of this writing, refinements are not possible, so don’t worry about them.
+
  
For the Type field, you’ll need to type in one of the above types. Most techs (esp. techs that actually do things) should be Applications.
+
Some special entry files have the extension '''.inf'''.<br />
 +
While most of these files can be freely edited, they can not be renamed or moved.
  
[code]
+
Any other file extension is not loaded into the game, unless an entry file specifically includes it.<br />
  <type>TT_APPLICATION</type>
+
The extension '''.macros''' is commonly used to denote scripting macros used in various entry files.<br />
[/code]
+
Entries that are not wanted in the game currently, but kept around for reference, are typically given the extension '''.disabled'''.
  
CATEGORY: There are five categories that “hold” techs in FreeOrion.  You need to assign your technology to one of them.  Note, that an application or refinement should be in the same category as it’s parent theory.
+
Entry files should never '''#include''' a file with another entry definition in it.
  
The categories you can use:
+
===Directory Structure===
 +
Entry files are categorized by their type and should remain within the directory for that type (nested sub-directories are ok).<br />
 +
For example Tech entries can be anywhere in ''default/scripting/techs/'', but should never be in ''default/scripting/fields/''.<br />
 +
This only applies to the actual definition files, those with the extension '''.focs.txt'''.
  
* LEARNING_CATEGORY  deals with the science meter, and fundamental technologies
+
The following directories within default/scripting are for '''.focs.txt''' entries:
* GROWTH_CATEGORY  deals with the health of a population, the size of a population, and growing food.
+
{|
* PRODUCTION_CATEGORY  deal with building stuff like ships and structures.  The mining and industry meters are governed here.
+
|alignments/ || Alignment entries
* CONSTRUCTION_CATEGORY  deals with developing your colonies.  The construction meter is handled here.
+
|-
* ECONOMICS_CATEGORY deals with the trade meter, money, etc.
+
|buildings/ || Building entries
 +
|-
 +
|empire_statistics/ || Empire_Stats|Empire statistics entries
 +
|-
 +
|encyclopedia/ || Encyclopedia topic entries
 +
|-
 +
|fields/ || Field entries
 +
|-
 +
|monster_designs/ || Ship loadout designs for space monsters
 +
|-
 +
|ship_designs/ || Ship loadout design entries
 +
|-
 +
|ship_hulls/ || Ship hull designs
 +
|-
 +
|ship_parts/ || Ship part entries
 +
|-
 +
|specials/ || Entries for specials
 +
|-
 +
|species/ || Species entries
 +
|-
 +
|techs/ || Tech entries
 +
|-
 +
|}
  
The technology I’m developing clearly falls into the Learning Category.
+
===Required files===
 +
These are relative to default/scripting/:
 +
{|
 +
|keymaps.inf || To Be Determined - Default keymap values
 +
|-
 +
|monster_fleets.inf || Entries for monster fleets
 +
|-
 +
|starting_unlocks/buildings.inf || Buildings pre-built on every starting homeworld.
 +
|-
 +
|starting_unlocks/fleets.inf || Entries for fleets every player starts the game with.
 +
|-
 +
|starting_unlocks/items.inf || Blueprints available at the start of the game to every player.  For techs this means they are completed, for other types it allows the player to produce them.
 +
|-
 +
|techs/Categories.inf || Categories that a tech must belong to.  For now these should not be changed or added to, aside from possibly the ''graphic'' or ''colour'' definitions.
 +
|-
 +
|}
 +
Additionally, definitions listed in any starting_unlocks/ file or monster_fleets.inf need to be avaiable.<br />
 +
The default AI may assume any or all of the default entries to exist.
  
[code]
+
==Macros==
  <category>LEARNING_CATEGORY</category>
+
A basic macro definition looks like this:
[/code]
+
<pre style="color: blue; display: block">FIRST_ONE
 +
'''2'''</pre>
 +
The three apostrophies denote preformatted text, meaning any newlines are part of the macro.<br />
 +
Macro names should be in all uppercase, with underscores in place of spaces.  They should also be uniquely named.
  
RESEARCH_COST:  The number of research points a player needs to spend each turn to research a tech.
+
References to a macro are done by adding double brackets:
RESEARCH_TURNS: The number of turns required to research a tech.
+
<pre style="color: blue; display: block">buildtime = [[FIRST_ONE]]</pre>
 +
The game will end up seeing this as '''buildtime = 2'''<br />
  
In FO, all techs cost X RP for Y Turns to research.  The numbers are still being decided as of this writing, for now assume a low level tech takes around 10 RP for 5 Turns to research.
+
Macros may also use arguments:
 +
<pre style="color: blue; display: block">NEW_MACRO
 +
 +
:Multiplies the first argument by the second.
 +
<pre style="color: blue; display: block">[[NEW_MACRO(2,3)]]</pre>
 +
:Results in 6 (2 * 3)
 +
You can pass other macros for the arguments:
 +
<pre style="color: blue; display: block">[[NEW_MACRO(FIRST_ONE,4)]]</pre>
 +
:Results in 8 (2 * 4)
  
[code]
+
Macros are mainly used to keep consistant values for multiple definitions.<br />
  <research_cost>10</research_cost>
+
When this is the case, it is best to have the macro definition in a file by itself, so other files can include it.<br />
  <research_turns>5</research_turns>
+
Sometimes macros are used for a complicated formula to help the readablity of the file.  There is no need for these macro definitions to be separated if they are never used in another definition.
[/code]
+
  
PREREQUISITES: The techs required before research can start. An application should always have its parent theory as a prerequisiteYou’ll need to read up on the forums to determine the current state of the tech tree in order to pick out some proper prerequisites for your tech.
+
==Including other files==
 +
Files are usually included for macro definitions.<br />
 +
You can include another file with the #include directive:
 +
<pre style="color: blue; display: block">
 +
#include "some_file.macros"</pre>
 +
:Includes the file named some_file.macros
 +
The directive should by on a line by itself, without any spaces before <nowiki>#include</nowiki>.<br />
 +
There is no restriction on what files are included, however you should not include files containing another FOCS entry in itThis would lead to a conflict when the entry is loaded twice.
  
The pithy name we gave the tech in the NAME field is its identification. All techs have such a name...it’s what you type into the prerequisites field.
+
Any path separators in the filename should use the forward slash ( / ) and not the backslash ( \ ).<br />
 +
If the filename begins with a path separator, it will refer to the Resource Directory, and not the file-system root.<br />
 +
The double-dot token ( .. ) will refer to the preceding directory, this should be used sparingly as it is hard to read (and easy to mistype) a filename like ''../../../../ship.macros''.<br />
  
Let’s say the Theory of Drek is the parent theory for my technology:
+
There is also special handling for a leading asterisk ( * ) in the name of the file, for wild-card matching.<br />
 +
This is useful for including a batch of files from a common place.<br />
 +
Placement of an asterisk outside of the first character, and the use of the single character wild-card ( ? ) are not supported.<br />
  
[/code]
+
Any specific file is only included once per file.  When editing a file, it should include any files it needs for macros and not depend on inclusion within other files.
  <prerequisites>
+
    LEARN_THEORY_OF_DREK
+
  </prerequisites>
+
[/code]
+
  
UNLOCKED_ITEMS: In the field, you’d type of the pithy names for all of the buildings your technology unlocks. An unlocked building can be constructed by a player on a planet.
+
====Examples====
 +
For the following examples, say we are editing a new file ''default/scripting/specials/TIMID_SHIP_AI.focs.txt'':
 +
<pre style="color:blue; display: block">#include "/scripting/abc.123"</pre> would point to ''default/scripting/abc.123''.
 +
<pre style="color:blue; display: block">#include "../common/abc.123"</pre> The above line would refer to ''default/scripting/common/abc.123''.
 +
<pre style="color:blue; display: block">#include "common/*_AI.macros"</pre> Will include all of the files in ''default/scripting/fields/common'' (and any sub-directories) that end with ''_AI.macros''.<br />
 +
This might include the imaginary files ''default/scripting/fields/common/SHIP_AI.macros'' and ''default/scripting/fields/common/BASE_AI.macros'', but not ''default/scripting/fields/common/SHIP.macros''.
  
If your tech doesn’t unlock any buildings, then just delete this field.
+
==Troubleshooting==
 +
Always check your log files when working with FOCS files.
  
My tech doesn’t unlock a building, so *poof* I pressed delete and got rid of that section.  But let’s say you did want to unlock a couple of buildings, the Tower of Babel and the Great Pyramids, for example:
+
Typically if there is a problem with the game parsing an entry, it will show the error in the console window.<br />
 +
The error will also be in the log file ''freeorion.log'', which is located in your user directory (Options > Directories > Save files (parent directory))
  
[code]
+
If there are no errors shown, you can make sure the file is loading by setting the log level to TRACE by either:
  <unlocked_items>
+
* editing the [[config.xml]] file in your user directory and change <log-level>'''VALUE'''</log-level> to <log-level>'''TRACE'''</log-level>
    <Item>
+
* launching the game with the '''--log-level TRACE''' argument.
      <type>UIT_BUILDING</type>
+
The client log file (freeorion.log) will now show each file as it was loaded in, as well as any files that were skipped.
      <name>BUILDING_TOWER_BABEL</name>
+
    </Item>
+
    <Item>
+
      <type>UIT_BUILDING</type>
+
      <name>BUILDING_GREAT_PRYAMIDS</type>
+
    </Item>
+
  </unlocked_items>
+
[/code]
+
  
Notice how each item to unlock has its own little item XML markups.  You’d then have to define these two buildings, in much the same way techs are defined.
+
If the issue is just with the name or description of the entry (it shows as '''ERROR: ENTRY_NAME''' in-game), make sure the entry is correct in the english stringtable (''default/stringtables/en.txt'').
  
So far my tech looks like this:
+
If you need further help, post a question in the [http://www.freeorion.org/forum/ forums], attaching your log file will probably speed up any response.
  
[code]
+
=Adding New Content=
<Tech>
+
==Linking a Tech and a Building==
      <name>LEARN_DREK_TUTORIAL</name>
+
Create a new file in ''default/scripting/techs/''<br />
      <description>LEARN_DREK_TUTORIAL_DESC</description>
+
We will save this file as TUTORIAL_ONE.focs.txt
      <type>TT_APPLICATION </type>
+
<pre style="color: blue; display:block">
      <category>LEARNING_CATEGORY</category>
+
Tech
      <research_cost>10</research_cost>
+
    name = "TECH_TUTORIAL_ONE"
      <research_turns>5 </research_turns>
+
    description = "TECH_TUTORIAL_ONE_DESC"
      <prerequisites>
+
    short_description = "BUILDING_UNLOCK_SHORT_DESC"
          LEARN_THEORY_OF_DREK
+
    category = "DEFENSE_CATEGORY"
      </prerequisites>
+
    researchcost = 4 * [[TECH_COST_MULTIPLIER]]
      EFFECTS_GROUP [optional]
+
    researchturns = 1
  </Tech>
+
    prerequisites = "DEF_ROOT_DEFENSE"
[/code]
+
    unlock = Item type = Building name = "BLD_TUTORIAL_TWO"
 +
    effectsgroups =
 +
        EffectsGroup
 +
            scope = And [
 +
                Planet
 +
                OwnedBy empire = Source.Owner
 +
                [[CANDIDATE_BATTLE_CHECK]]
 +
            ]
 +
            effects = SetTroops value = Value + 1
 +
    graphic = ""
  
=Step 3: The Defining the Effects Groups=
+
#include "techs.macros"
  
This is the hard part. Defining an effects group is a little like writing a simple computer program. You’ll want to read the Effects document, print it out, read it again, and keep it around for reference.  The Effects engine is versatile, it can a lot stuff.  The trade off is complexity: it’s not as trivial as just filling out fields in a form.
+
#include "../common/shared.macros"
  
You can have as many Effects Groups as you need to define what a tech does. My effect...
+
</pre>
 +
This tech:
 +
* Requires DEF_ROOT_DEFENSE to be researched first (which every player starts with)
 +
* Allows a player to build BLD_TUTORIAL_TWO (we have not created this yet)
 +
* Increases the speed of new troop recruitment on the planet by an additional 1 per turn, as long as combat is not occurring.
 +
The short description is for the hover text on the tech screen, as well as the brief description at the top of the 'pedia entry.<br />
 +
Techs all belong to one tech category, these are defined in [https://github.com/freeorion/freeorion/blob/master/default/scripting/techs/Categories.inf Categories.inf].  It is recommended to use one of the existing categories.
  
+2 Max Science to all friendly worlds set to Primary/Secondary Science Focus
+
Notice ''researchcost'' uses the macro TECH_COST_MULTIPLIER, which is defined in default/scripting/common/shared.macros  So we also <nowiki>#include</nowiki> that file at the bottom.<br />
 +
The ../ means to go back one directory, in this case to default/scripting (because our file is in default/scripting/techs).<br />
 +
This definition also uses the CANDIDATE_BATTLE_CHECK macro, so the techs.macros file is needed for that.
  
...requires just one Effects Group.
+
For the first building, we will reuse the earlier [[#Creating_a_new_entry|BLD_TUTORIAL_ONE]]
  
Just like techs, Effects Groups have an XML form that you need to fill outHere it is:
+
For this next building, we will be showing alternate ways to reach a desired effectIf you just want a workable version without the back and forth, scroll to the end of this section.
  
[code]
+
Let's go ahead and add the second building in, create the file '''default/scripting/buildings/TUTORIAL_TWO.focs.txt'''
<EffectsGroup>
+
<pre style="color: blue; display: block">BuildingType
      <scope>SCOPE</scope>
+
    name = "BLD_TUTORIAL_TWO"
      <activation>ACTIVATION</activation>
+
    description = "BLD_TUTORIAL_TWO_DESC"
      <stacking_group>STACKING_GROUP</stacking_group>
+
    buildcost = 20
      <effects>
+
    buildtime = 3
          EFFECT0
+
    location = And [
          EFFECT1
+
        Planet
          ...
+
        Not Contains Building name = "BLD_TUTORIAL_TWO"
          EFFENTN
+
        OwnedBy empire = Source.Owner
      </effects>
+
        TargetPopulation low = 1
</EffectsGroup>
+
    ]
[/code]
+
    EnqueueLocation = [[ENQUEUE_BUILD_ONE_PER_PLANET]]
 +
    effectsgroups = [
 +
        EffectsGroup
 +
            scope = And [
 +
                Planet
 +
                Object id = Source.PlanetID
 +
            ]
 +
            effects = SetMaxTroops value = Value + 3
 +
        EffectsGroup
 +
            scope = And [
 +
                Planet
 +
                Ownedby empire = Source.Owner
 +
                Contains Building name = "BLD_TUTORIAL_TWO"
 +
                Contains Building name = "BLD_TUTORIAL_ONE"
 +
            ]
 +
            effects = SetMaxDefense value = Value + 5
 +
    ]
 +
    icon = ""
  
SCOPE  This field defines what objects in the game are influenced by your technology.   My tech operates on “all friendly worlds set to Primary/Secondary Science Focus”.   Most techs should constrain their effects to worlds set to a particular focus, or environment, or whatever.
+
#include "../common/shared.macros"
  
First off, we need to pick out all friendly worlds. We can do that with the EmpireAffiliation condition:
+
</pre>
 +
This building can only be built on a planet with at least 1 population, and is limited to one per planet.<br />
 +
It also has a couple of effects, the first allows an additional 3 troops on the planet<br />
 +
The second allows an extra defense of 5, but only if there is also a BLD_TUTORIAL_ONE on the planet.
  
[code]
+
''location'' tells the game where this building can be constructed.
  <Condition::EmpireAffiliation>
+
* check all of the planets
      <empire_id>Source.Owner</empire_id>
+
* for each planet that is without a BLD_TUTORIAL_TWO
      <affiliation>AFFIL_SELF</affiliation>
+
* that is also owned by the player
      <exclusive>1</exclusive>
+
* that also has a population of at least 1
  </Condition::EmpireAffiliation>
+
[/code]
+
  
Notice I filled out empire_id with source.owner.  This is a variables...there are many variables you can access, listed in the Effects document.
+
''EnqueueLocation'' restricts when a building can be placed into the production queue.
  
I filled out the affiliation field with an “enumeration”. You can find the enumerations here.  Certain fields require certain enumerations: it’s mostly self explanatory.  For example, the condition PlanetType requires PlanetType enumerations.
+
The ''effectsgroups'' contains any effects and the conditions of when and where to apply them.<br />
 +
There are a number of different ways to construct these, so we will show two different methods.
  
Exclusive is a Boolean value, which just means true (the number 1) or false (the number 0).  For this particular field, safe bet is just to enter “1” when dealing with planets.
+
Looking at the first ''EffectsGroup'', the ''scope'' defines the ''Target'' of our effect:
 +
* check all of the planets
 +
* for each one that has an ID that is the same as the sources(this building) planet IDID is a unique identifier, so this will only match one result.
  
When FreeOrion executes this empire affiliation condition, it will pick out all of the objects in the game owned by your empire.  This includes space ships and buildings...but we are only concerned with the planets.  So, I need to add another condition to the mix—the Type condition.
+
For the second ''EffectsGroup'':
 +
* check all of the planets
 +
* for each one with the same owner as the sources(this building) owner.
 +
* that has a completed BLD_TUTORIAL_TWO
 +
* and also has a completed BLD_TUTORIAL_ONE
  
[code]
+
''effects'' define what effects apply.  The ''Target'' variable can be used here if needed, but it can not be used in scope or activation because they define what the target is.
  <Condition::Type>OBJ_POP_CENTER</Condition::Type>
+
[/code]
+
  
This is yet another enumeration form here.  Now, all population centers will be selected, including any future space based colonies that are not on planets.
+
For a more in-depth look at all of the possible attributes and descriptions of each, see [[Effects]]
  
We need to glue these two conditions together.  For that, we use the And condition:
+
Remember to add in the stringtable entries for the new tech and building:
 +
<pre style="color: blue; display: block">TECH_TUTORIAL_ONE
 +
Tutorial tech 1
  
[code]
+
TECH_TUTORIAL_ONE_DESC
  <Condition::And>
+
The first tutorial tech.
    <Condition::EmpireAffiliation>
+
        <empire_id>Source.Owner</empire_id>
+
        <affiliation>AFFIL_SELF</affiliation>
+
        <exclusive>1</exclusive>
+
    </Condition::EmpireAffiliation>
+
    <Condition::Type>OBJ_POP_CENTER</Condition::Type>
+
  </Condition::And>
+
[/code]
+
  
Pretty cool, huh?  By sticking our conditions into an And XML field, we are saying that we want FreeOrion to pick out everything that’s both owned by our empire and a population center. 
+
BLD_TUTORIAL_TWO
 +
Tutorial building 2
  
We need a couple more conditions to make things work...remember that that we only want worlds that are set to the Primary or Secondary Science focus.  Notice the word “or”.
+
BLD_TUTORIAL_TWO_DESC
 +
Second tutorial building, adds troops and defense.
  
First, let’s select all worlds that have the primary science focus, using the focustype condition:
+
</pre>
  
[code]
+
Start a new single player game with 1 AI player and Planet Density set to High.
<Condition::Focus>
+
      <primary>1</primary>
+
      <FocusType>FOCUS_RESEARCH</FocusType>
+
</Condition::FocusType>
+
[/code]
+
  
I filled out the primary field with a 1, meaning “true”. This will select all worlds with a Primary focus in science. Note that it really will select ALL worlds, including those of enemy empires.
+
If you play with this building for awhile, once you have it on multiple planets you may notice an issue.<br />
 +
Wherever we have both buildings constructed, it increases the defense effect for the buildings on all of our planets.<br />
 +
That might be a good feature for some other building, but it is not really what we intend here.
  
FocusType is yet another enumeration.
+
Once you have these two buildings on a couple of planets, save the game and exit before we make further changes.<br />
 +
The game will load the FOCS files into memory, so changes made will not neccesarily take effect until restarted.
  
We need to do the same thing to select all worlds with Secondary focus in science, only this time the primary field would be 0.
+
One way to try and solve this is by adding a stacking group to the effect.<br />
 +
Change the effectsgroups of BLD_TUTORIAL_TWO so it looks like this:
 +
<pre style="color: blue; display: block">    effectsgroups = [
 +
        EffectsGroup
 +
            scope = And [
 +
                Planet
 +
                Object id = Source.PlanetID
 +
            ]
 +
            effects = SetMaxTroops value = Value + 3
 +
        EffectsGroup
 +
            scope = And [
 +
                Planet
 +
                Ownedby empire = Source.Owner
 +
                Contains Building name = "BLD_TUTORIAL_TWO"
 +
                Contains Building name = "BLD_TUTORIAL_ONE"
 +
            ]
 +
            stackinggroup = "STACKING_TUTORIAL_TWO_DEFENSE"
 +
            effects = SetMaxDefense value = Value + 5
 +
    ]
 +
</pre>
 +
''stackinggroup'' only allows the first instance of tha effect to apply, ignoring any others.  You might create a new building or tech with the same ''stackinggroup'' name, and only the first one would apply.
  
Now the two statements need to be glued together.  Since the effect works on Secondary *or* Primary focus, use the condition Or:
+
If we gave both effects the same stackinggroup, only the troop effect would apply.<br />
  
[code]
+
After saving the changes, load the previous game and click on next turn.<br />
<Condition::Or>
+
The game state is loaded as we left it, once we start a new turn everything is reprocessed.
  <Condition::Focus>
+
      <primary>1</primary>
+
      <FocusType>FOCUS_RESEARCH</FocusType>
+
  </Condition::FocusType>
+
  <Condition::Focus>
+
      <primary>1</primary>
+
      <FocusType>FOCUS_RESEARCH</FocusType>
+
  </Condition::FocusType>
+
</Condition::Or>
+
[/code]
+
  
Finally, to complete our scope field, we need to glue both pieces togetherJust insert the Or condition into the And condition:
+
Now you will see only one defense effect at each planetWhile this functionally works how we want, if you hover over a couple of planets they show the effect all coming from the same planet (if they have a supply connection).<br />
 +
What we really want is for the effect to only apply to the planet it is built at.
  
[code]
+
Our first effect works fine for this.  We could combine the effects onto one effect group, saving us from doing the same scope check twice:
<scope
+
<pre style="color: blue; display: block">effects = [
  <Condition::And>
+
    SetMaxTroops value = Value + 3
    <Condition::EmpireAffiliation>
+
    SetMaxDefense value = Value + (5 * (If condition = ContainedBy Contains Building name = "BLD_TUTORIAL_ONE"))
        <empire_id>Source.Owner</empire_id>
+
]</pre>
        <affiliation>AFFIL_SELF</affiliation>
+
''If'' returns either a 1 when true, otherwise is returns a 0.<br />
        <exclusive>1</exclusive>
+
This would show a bonus of 0 for defense when we do not have a BLD_TUTORIAL_ONE constructed.  If everything showed a notice for not having an effect, the user interface would be very cluttered.
    </Condition::EmpireAffiliation>
+
    <Condition::Type>OBJ_POP_CENTER</Condition::Type>
+
    <Condition::Or>
+
      <Condition::Focus>
+
        <primary>1</primary>
+
        <FocusType>FOCUS_RESEARCH</FocusType>
+
      </Condition::FocusType>
+
      <Condition::Focus>
+
        <primary>1</primary>
+
        <FocusType>FOCUS_RESEARCH</FocusType>
+
      </Condition::FocusType>
+
    </Condition::Or>
+
  </Condition::And>
+
</scope>
+
[/code]
+
  
Notice, you can nest And/Or conditions. We are saying:
+
Instead of showing useless information, we will just modify a copy of the first ''EffectGroup''.<br />
 +
'''default/scripting/buildings/TUTORIAL_TWO.focs.txt'''
 +
<pre style-"color: blue; display: block">BuildingType
 +
    name = "BLD_TUTORIAL_TWO"
 +
    description = "BLD_TUTORIAL_TWO_DESC"
 +
    buildcost = 20
 +
    buildtime = 3
 +
    location = And [
 +
        Planet
 +
        Not Contains Building name = "BLD_TUTORIAL_TWO"
 +
        OwnedBy empire = Source.Owner
 +
        TargetPopulation low = 1
 +
    ]
 +
    effectsgroups = [
 +
        EffectsGroup
 +
            scope = And [
 +
                Planet
 +
                Object id = Source.PlanetID
 +
            ]
 +
            effects = SetMaxTroops value = Value + 3
 +
        EffectsGroup
 +
            scope = And [
 +
                Planet
 +
                Object id = Source.PlanetID
 +
                Contains Building name = "BLD_TUTORIAL_ONE"
 +
            ]
 +
            effects = SetMaxDefense value = Value + 5
 +
    ]
 +
    icon = ""
  
If the object is owned by our empire AND the object is a population center AND (the object is set to Primary Science Focus OR the object is set to Secondary Science Focus) THEN do something funky to the object.
+
#include "../common/shared.macros"
  
*whew*  Seems like a lot of work spelled out like that, but it’s easier once you get the hang of it.
+
</pre>
  
Notice that everything above is contained by the scope XML field of the Effects Group.  Now, we need to fill out the activation field.
+
Everything should be working as we had before.  When you are testing your changes you can destroy a building by right clicking on the icon for it, on the planet side screen.
  
[code]
+
We have left the ''icon'' blank in all of our examples, letting the game decide the default icon to use.  Where mentioned, ''icon'' or ''graphic'' are required fields and wll be relative to the art directory (default/data/art/).  If sharing these wih others, you might pick the icon or graphic asset that best suits the entry.
  <activation>
+
    <Condition::Self/>
+
  <activeation>
+
[/code]
+
  
The activation field is a universe that consists only of the object’s owner.  You use the same conditions as the scope field—if any object is selected by the condition, then the effect fires.  This is useful is you don’t want an effects group to fire under certain conditions.  For example, for a building we could test it’s planet’s environment.  We could set up a condition to test if the planet is Barren, or whatever.
+
==Ships==
 +
Any single ship is constructed from a [[ship_design|ship design]], which is a combination of a ship hull and zero or more ship parts.
  
It’s safe just to enter the Self condition, which ensures the effect always fires.
+
The previous section introduced a number of errors to show ways to troubleshoot them.  The remaining sections will concentrate more on anything specific to them.  Stringtable entries will be ommitted to keep the sections briefer, feel free to add them as appropriate.
  
Next, the stacking group:
+
===Ship Parts===
 +
{| class="wikitable" style="float: right; margin-left: 10px; font-size: 9px;"
 +
|+Ship Part Class
 +
|-
 +
| ShortRange
 +
|-
 +
| FighterBay
 +
|-
 +
| FighterHanger
 +
|-
 +
| Shield
 +
|-
 +
| Armour
 +
|-
 +
| Troops
 +
|-
 +
| Detection
 +
|-
 +
| Stealth
 +
|-
 +
| Fuel
 +
|-
 +
| Colony
 +
|-
 +
| Speed
 +
|-
 +
| General
 +
|-
 +
| Bombard
 +
|-
 +
| Research
 +
|-
 +
| Industry
 +
|-
 +
| Trade
 +
|-
 +
| ProductionLocation
 +
|-
 +
|}Keep in mind, these parts will not be available to an empire until they unlock them either by researching a tech, getting them at the start of the game, or through some other means.<br />
 +
You can see what parts are in the game, but not yet unlocked by your empire, by going to the ship design screen and selecting ''Unavailable'' in the parts filter.
  
[code]
+
A new weapon<br />
  <stacking_group>STACK_DREK_TUTORIAL</stacking_group>
+
'''default/scripting/ship_parts/TUT_WEAPON.focs.txt'''
[/code]
+
<pre style="color: blue; display: block">Part
 +
    name = "TUT_WEAPON"
 +
    description = "TUT_WEAPON_DESC"
 +
    class = ShortRange
 +
    damage = 4
 +
    shots = 1
 +
    mountableSlotTypes = External
 +
    buildcost = 25 * [[FLEET_UPKEEP_MULTIPLICATOR]]
 +
    buildtime = 2
 +
    location = OwnedBy empire = Source.Owner
 +
    icon = ""
  
Stacking groups are mostly for buildings. If you have two buildings in the same solar system that both effect every planet in the solar system, you’d only want one building’s effects to fire. That’s more or less what the stacking group is for.
+
#include "../common/shared.macros"
 +
</pre>
 +
''class'' defines what kind of part this is: a short range weapon, a fighter weapon, a piece of armor, etc.<br />
 +
For direct fire weapons (ShortRange), there is a primary stat of ''damage'' and a secondary stat of ''shots''.<br />
 +
''damage'' refers to the amount of damage for each shot.<br />
 +
''shots'' is how many times this part shoots during each combat round, this may be omitted and defaults to 1.<br />
 +
The FighterHangar class has a primary stat ''capacity'' and a secondary ''damage''.
  
For technologies, it’s safe just to enter the name of the tech, perhaps prefixed with the word “STACK”.
+
''mountableSlotTypes'' are slots types that this part will fit into.  For balancing purposes: weapons, armor, and sensors should usually be limited to the outside of the ship, with other types restricted to the interior.  There are exceptions to this, such as troop pods, but the majority stick to this guideline.<br />
 +
For ship designs, the ''buildcost'' of each part and the hull will be accumulative.  However the ''buildtime'' is not, the longest time of all of the parts will be used.<br />
 +
''location'' limits where ships designs with this part may be constructed.  Some part might be restricted to planets with access to a specific special, or a certain system type.
  
Now, the payload, the actual effects:
+
A new armor<br />
 +
''default/scripting/ship_parts/TUT_ARMOR.focs.txt'''
 +
<pre style="color: blue; display: block">Part
 +
    name = "TUT_ARMOR"
 +
    description = "TUT_ARMOR_DESC"
 +
    class = Armour
 +
    capacity = 4
 +
    mountableSlotTypes = [External Internal]
 +
    buildcost = 6 * [[FLEET_UPKEEP_MULTIPLICATOR]]
 +
    buildtime = 4
 +
    location = OwnedBy empire = Source.Owner
 +
    effectsgroups = [
 +
        EffectsGroup
 +
            scope = Source
 +
            stackinggroup = "TUT_ARMOR_STACKING"
 +
            effects = SetStealth value = Value + 2
 +
    ]
 +
    icon = ""
  
[code]
+
#include "../common/shared.macros"
<effects>
+
</pre>
  <Effect::SetMeter>
+
Many parts simply have a ''capacity''.  What that capacity relates to depends on the ''class'' of the part, in this case it is the amount of extra maximum structure a ship design has.<br />
      <meter>METER_RESEARCH</meter>
+
This allows parts to have effects applied on them from other events with the SetCapacity and SetMaxCapacity effects.
      <value>Target.MaxResearch+2</value>
+
      <max>1</max>
+
  </Effect::SetMeter>
+
</effects
+
[/code]
+
  
My tech has only one effect...but you can include as many effects as you need.  
+
===Ship Hulls===
 +
A new ship hull:<br />
 +
'''default/scripting/ship_hulls/TUT_HULL.focs.txt'''
 +
<pre style="color: blue; display: block">Hull
 +
    name = "TUT_HULL"
 +
    description = "TUT_HULL_DESC"
 +
    speed = 50
 +
    fuel = 4
 +
    stealth = 6
 +
    structure = 20
 +
    slots = [
 +
        Slot type = External position = (0.50, 0.35)
 +
        Slot type = External position = (0.50, 0.60)
 +
        Slot type = External position = (0.80, 0.45)
 +
        Slot type = Internal position = (0.30, 0.40)
 +
    ]
 +
    buildCost = 40 * [[FLEET_UPKEEP_MULTIPLICATOR]]
 +
    buildTime = 4
 +
    location = Contains And [
 +
        Building name = "BLD_SHIPYARD_BASE"
 +
        OwnedBy empire = Source.Owner
 +
    ]
 +
    effectsgroups = [
 +
        [[REGULAR_HULL_DETECTION]]
 +
        [[SCAVANGE_FUEL_UNOWNED]]
 +
        [[UNOWNED_GOOD_VISION]]
 +
        [[UNOWNED_MOVE]]
 +
    ]
 +
    icon = "icons/ship_hulls/basic-large-hull_small.png"
 +
    graphic = "hulls_design/basic-large-hull.png"
  
The most common effect is SetMeter. The first field, meter, determines which meter is effected.  These are enumerations. 
+
#include "ship_hulls.macros"
  
The second field is an expression. An expression can be nearly any math statement (4*3 or Target.MaxResearch+10). Notice, I took the value of the Target’s Max Research, then added 2. If I had just typed “2” into the value field, it would set the meter to “2”. Instead of being a bonus, my tech would suck ass.
+
#include "../common/shared.macros"
 +
</pre>
 +
''speed'', ''fuel'', ''stealth'', and ''structure'' are all starting values.<br />
 +
''slots'' has an entry for each slot and the coordinates to display that slot on the graphic during ship design.<br />
 +
Since the position of the slots need to line up with the graphic used, we will just use the basic large hull here.
  
The third field is max, which determines whether it’s the current value of the meter or the max value of the meter effected.   In FO, techs normally operate on the max value of a meter. Then, the current value slowly rises to match at a speed based on the construction meter.  Putting “1” into the max field (for “true”) will operate on the max meter, which 9 times out of 10 is exactly what you want to do.
+
===Ship Designs===
 +
New ship design<br />
 +
'''default/scripting/ship_designs/SD_TUTORIAL.focs.txt'''
 +
<pre style="color: blue; display: block">ShipDesign
 +
    name = "SD_TUTORIAL"
 +
    description = "SD_TUTORIAL_DESC"
 +
    hull = "TUT_HULL"
 +
    parts = [
 +
        "TUT_WEAPON"
 +
        "TUT_WEAPON"
 +
        "TUT_ARMOR"
 +
        "TUT_ARMOR"
 +
    ]
 +
    model = "mark1"
 +
</pre>
 +
''parts'' need to stay in the same order as they are defined in the hull.<br />
 +
The first three are all external slots, and the fourth is an internal slot.<br />
 +
Since our new armor part can fit in an internal or external slot, this is ok.
  
Our tech is mostly finished. When we slide the Effects group into it’s proper slot, the whole thing looks like this:
+
Ship designs within the [[Resource Files]] are available to all empires.<br />
 +
Designs saved from inside the game are saved in the [[User Directory]], and only available to the human client.
  
[code]
+
There are also designs for space monster ships, which follow the same layout as other designs.<br />
<Tech>
+
They are in a separate directory as the fleets are handled differently.
      <name>LEARN_DREK_TUTORIAL</name>
+
      <description>LEARN_DREK_TUTORIAL_DESC</description>
+
      <type>TT_APPLICATION </type>
+
      <category>LEARNING_CATEGORY</category>
+
      <research_cost>10</research_cost>
+
      <research_turns>5 </research_turns>
+
      <prerequisites>
+
          LEARN_THEORY_OF_DREK
+
      </prerequisites>
+
      <EffectsGroup>
+
        <scope>
+
          <Condition::And>
+
            <Condition::EmpireAffiliation>
+
              <empire_id>Source.Owner</empire_id>
+
              <affiliation>AFFIL_SELF</affiliation>
+
              <exclusive>1</exclusive>
+
            </Condition::EmpireAffiliation>
+
            <Condition::Type>OBJ_POP_CENTER</Condition::Type>
+
            <Condition::Or>
+
              <Condition::Focus>
+
                <primary>1</primary>
+
                <FocusType>FOCUS_RESEARCH</FocusType>
+
              </Condition::FocusType>
+
              <Condition::Focus>
+
                <primary>1</primary>
+
                <FocusType>FOCUS_RESEARCH</FocusType>
+
              </Condition::FocusType>
+
            </Condition::Or>
+
          </Condition::And>
+
        </scope>
+
        <activation><Condition::Self\></activation>
+
        <stacking_group>STACK_DREK_TUTORIAL</stacking_group>
+
        <effects>
+
          <Effect::SetMeter>
+
            <meter>METER_RESEARCH</meter>
+
            <value>Target.MaxResearch+2</value>
+
            <max>1</max>
+
          </Effect::SetMeter>
+
        </effects>
+
      </EffectsGroup>
+
</Tech>
+
[/code]
+
  
As you’ve probably noticed, the scope condition is the longest and toughest part to write.  
+
===Fleets===
 +
Player fleets are typically only defined within default/scripting/starting_unlocks/fleets.inf<br />
 +
These encompass what ships each player starts the game with, and how they are grouped.<br />
 +
A sample fleet:
 +
<pre style="color: blue; display: block">Fleet
 +
    name = "FN_TUTORIAL"
 +
    ships = [
 +
        "SD_TUTORIAL"
 +
        "SD_TUTORIAL"
 +
        "SD_MARK_1"
 +
    ]
 +
</pre>
 +
This would create a fleet with two ships using our new ship designs, and one of the basic mark 1 ships.
  
==Step 4 Composing the string table==
+
===Monster Fleets===
 +
Below is an example of the Small Krill space monster:
 +
<pre style="color: blue; display: block">MonsterFleet
 +
    name = "SM_KRILL_1"
 +
    ships = [
 +
        "SM_KRILL_1"
 +
    ]
 +
    spawnrate = 0.5
 +
    spawnlimit = 9999
 +
    location = And [
 +
        Not Contains Monster
 +
        Not WithinStarlaneJumps jumps = 2 condition = Contains And [
 +
            Planet
 +
            OwnedBy affiliation = AnyEmpire
 +
        ]
 +
    ]
 +
</pre>
 +
''spawnrate'' defines how often the space monster might appear.  This is factored with other values, including the frequency set by the player.<br />
 +
''spawnlimit'' defines the maximum number allowed in the game.  The monster would not spawn anymore during the current turn, if there are more than this limit.
  
Not everyone speaks English.
+
==String Tables==
 +
String tables are the language files used when displaying information to a user.
  
I’ll give my fellow Americans time to recover from that statement.
+
These files are located in ''default/stringtables/'' and are separated by language, the default being the English file ''en.txt''.<br />
 +
Each client has a language setting, which determines which file it uses for references.  Any references not found are then checked for in the default file.
  
...
+
When an entry is given a ''name="BLD_ONE"'', anytime the game passes that entry around it uses BLD_ONE.<br />
 +
When the game displays information about it to the user, the users client translates it according to their string table.<br />
  
...
+
Given the entry in en.txt:
 +
<pre style="color: blue; display: block">BLD_ONE
 +
Building One
 +
</pre>
 +
Any time the building name is displayed to the user, they will see ''Building One''.
  
As tiring as it is to accommodate the English impaired, we need to anyway.  This means writing out any words that appear in the game in a string table.
+
===Macros===
 +
{| class="wikitable" style="float: right; margin-left: 10px; font-size: 9px;"
 +
|+Stringtable Macros
 +
|-
 +
!Type!!Value
 +
|-
 +
| planet || ID
 +
|-
 +
| system || ID
 +
|-
 +
| fleet || ID
 +
|-
 +
| ship || ID
 +
|-
 +
| building || ID
 +
|-
 +
| empire || ID
 +
|-
 +
| tech || string
 +
|-
 +
| buildingtype || string
 +
|-
 +
| special || string
 +
|-
 +
| shiphull || string
 +
|-
 +
| shippart || string
 +
|-
 +
| species || string
 +
|-
 +
| encyclopedia || string
 +
|}Macros in string tables are not handled exactly the same as macros in other FOCS files.<br />
  
It can be pretty simple:
+
Like a normal macro, you can use a string table entry to swap the value for the text.<br />
 +
<pre style="color: blue; display: block">[[BLD_ONE]]</pre>
 +
:swaps ''<nowiki>[[BLD_ONE]]</nowiki>'' with ''Building One''
  
[code]
+
Alternatively, macros may have a preceding ''type'' followed by a value which is a string table entry or an ID.<br />
LEARN_DREK_TUTORIAL
+
These string table macros are used to create a link to a 'pedia entry.<br />
Drek’s Effects Tutorial
+
<pre style="color: blue; display: block">[[buildingtype BLD_ONE]]</pre>
 +
:swaps ''<nowiki>[[buildingtype BLD_ONE]]</nowiki>'' with a link to the BLD_ONE pedia entry displayed as ''<u>Building One</u>''.
  
LEARN_DREK_TUTORIAL_DESC
+
Each of the string table entries are loaded into their ''type'', such as ''tech''. To create the correct link you need to know which type they belong to.<br />
A marvelous, high tech tutorial that enlightens all who read it. /n Effect: +2 Max Science to all friendly worlds set to the Science Focus.
+
If the wrong category is used, a blank 'pedia entry will be shown when the link is clicked on.
[/code]
+
  
Notice the /n, for a “newline.”  There’s other pieces of formatting you can use, see the faq for details.
+
==SitReps==
 +
{| class="wikitable" style="float: right; margin-left: 10px; font-size: 9px;"
 +
|+SitRep Variables
 +
|-
 +
!tag
 +
|-
 +
|text
 +
|-
 +
|rawtext
 +
|-
 +
|planet
 +
|-
 +
|system
 +
|-
 +
|ship
 +
|-
 +
|fleet
 +
|-
 +
|building
 +
|-
 +
|field
 +
|-
 +
|combat
 +
|-
 +
|empire
 +
|-
 +
|shipdesign
 +
|-
 +
|predefinedshipdesign
 +
|-
 +
|tech
 +
|-
 +
|buildingtype
 +
|-
 +
|special
 +
|-
 +
|shiphull
 +
|-
 +
|shippart
 +
|-
 +
|species
 +
|-
 +
|fieldtype
 +
|-
 +
|}A SitRep message can be created as an effect in any EffectsGroup
 +
<pre style="color: blue; display: block">GenerateSitRepMessage
 +
    message = "CUSTOM_SITREP_INTRODUCTION"
 +
    label = "SITREP_WELCOME_LABEL"
 +
    icon = "icons/tech/categories/spy.png"
 +
    parameters = [
 +
        tag = "tech" data = "SPY_CUSTOM_ADVISORIES"
 +
        tag = "system" data = Target.SystemID
 +
    ]
 +
    empire = Source.Owner
 +
</pre>
 +
:The introductory sitrep message.
  
That’s pretty much itCongrats if you’ve read this far.  I probably would have got bored round step #2.
+
''label'' is a reference to a string table entryIt is used for filtering sitrep messages, sitreps can share labels.
  
==Appendix: Additional Examples==
+
Each ''tag'' in the ''parameters'' is passed as a variable to the ''message''.<br />
 +
The ''message'' is a string table entry, the variables are referenced with surrounding percentage signs (%).<br />
 +
<pre style="color: blue; display: block">CUSTOM_SITREP_INTRODUCTION
 +
'''A custom introduction that references the tech %tech% and the system %system%.'''
 +
</pre>
 +
These variables are shown as links to the item or pedia entry.<br />
  
(Forthcoming)
+
Variables are predefined, a custom variable will not work.<br />
 +
The variable ''text'' will be translated from the supplied userstring.(string table match)<br />
 +
''rawtext'' will not be translated and will be displayed as defined.
 +
 
 +
''empire'' defines which empires will receive this message.  It is optional, and if omitted the message will be shown to all empires.
 +
 
 +
General purpose sitreps that should be shown at the start of the game should be placed into the default/customizations/custom_sitreps.txt file.<br />
 +
There are a number of examples for different sitrep options in this file as well.
 +
 
 +
==Encyclopedia Articles==
 +
The encyclopedia articles are 'pedia entries which would not belong to a specific entry.<br />
 +
These include guides, game concepts and overviews for groups of entries.
 +
 
 +
The definitions are placed in default/scripting/encyclopedia<br />
 +
Except for ''icon'', all of the fields are string table entries.
 +
 
 +
==Fields==
 +
Fields are defined in default/scripting/fields, and represent effects that span a limited area in space.<br />
 +
While many of these entries are created during universe generation they can also be created as an effect of another entry using ''CreateField''.
 +
<pre style="color: blue; display: block">effects = CreateField type = "FLD_ACCRETION_DISC" size = 10</pre>
 +
 
 +
==Specials==
 +
Specials are items which can be attached to most of the other universe objects, typically they are found on planets.<br />
 +
They are defined in default/scripting/specials<br />
 +
 
 +
Similar to monster fleets, they have a ''spawnrate'' field and an optional ''spawnlimit'' field that will limit how often they will occur.
 +
 
 +
==Species==
 +
A good amount of info is packed into the effects for species entries.  Historically this was for processing efficiency and to ensure the ordering of specific effects.
 +
 
 +
Following [[Effects#Species_Specification|Effects(Species)]], note the fields for Playable, Native, CanProduceShips, and CanColonize.<br />
 +
The default for these attributes is false, meaning if they are not listed in the file, the species can not perform that action.<br />
 +
'''Playable''' determines if the player can select them as their starting species, and if the species is available to the AI.<br />
 +
'''Native''' species are distributed among planets at the start of the game, according with the game-setup options.  They are not controlled by an AI client and so do not typically construct buildings or ships.
 +
 
 +
'''foci''' contains each planet focus type that the species is able to select from.  This does not give the species the knowledge of that focus type, only the ability to use it if they later acquire it.
 +
 
 +
'''preferredfocus''' is the focus type that will give certain bonuses, like increased happiness, to that planet when used.
 +
 
 +
In addition to having ''CanProduceShips'' and ''CanColonize'' in the species entry, the species will need a colony building entry and knowledge of how to construct them.<br />
 +
Entries for other species colony buildings are in ''default/scripting/buildings/colonies''.  For official additions, the ''col_bld_gen.py'' script should be edited instead and generated from that script.<br />
 +
This file is a [http://www.python.org Python] script and will need the expertise of someone that can program in that language.<br />
 +
Most colony buildings are granted knowledge of to all players at the start of the game from ''default/scripting/starting_unlock/items.inf''.<br />
 +
Some of the species, such as any of the extinct species, are not included here, but granted after a tech is researched or some other criteria is met.
 +
 
 +
===Example===
 +
The following will be a step by step instruction on "quickly" creating a new playable species.
 +
 
 +
Make sure you are using a decent text editor before starting (mainly not Notepad or Wordpad, see above).
 +
 
 +
Change to the (path to freeorion)''/default/scripting'' directory.<br />
 +
Copy ''species/SP_HUMAN.focs.txt'' to ''species/SP_NEW_MAN.focs.txt''
 +
 
 +
Open this new file and change the following fields:<br />
 +
* '''name''' = "''SP_NEW_MAN''"
 +
* '''description''' = "''SP_NEW_MAN_DESC''"
 +
 
 +
Next, make sure to create a colony building for this species:<br />
 +
Copy ''buildings/colonies/SP_HUMAN.focs.txt'' to ''buildings/colonites/SP_NEW_MAN.focs.txt''<br />
 +
 
 +
Open the new file and replace the any human entries with entires for newman.  Replace:
 +
* "BLD_COL_HUMAN" with "''BLD_COL_NEW_MAN''"
 +
* "BLD_COL_HUMAN_DESC" with "''BLD_COL_NEW_MAN_DESC''"
 +
* "SP_HUMAN" with "''SP_NEW_MAN''"
 +
 
 +
 
 +
These new entries need to be creating in the stringtables:<br />
 +
* Open the default stringtable: (path to freeorion)''/default/stringtables/en.txt''.
 +
* Find the entry for SP_HUMAN (CTRL+F in most editors).
 +
* On the line just before ''SP_HUMAN'', enter the following:
 +
<pre style="color: blue; display: block">SP_NEW_MAN
 +
Newman
 +
 
 +
SP_NEWMAN_DESC
 +
A new species with no differences from Humans
 +
 
 +
</pre>
 +
* Next, find the entry for BLD_COL_HUMAN
 +
* On the line just before, enter the following:
 +
<pre style="color: blue; display: block">BLD_COL_NEW_MAN
 +
Newman Colony
 +
 
 +
BLD_COL_NEW_MAN_DESC
 +
[[BLD_COL_PART_1]] [[species SP_NEW_MAN]] colony. [[BLD_COL_PART_2]] Newman colony [[BLD_COL_PART_3]].
 +
 
 +
</pre>
 +
 
 +
Start the game, the ''Newman'' species should be available to select now.
 +
 
 +
Note that we did not change the ''gameplay_description'' field in the species entry, normally each species should have a new stringtable entry here.
 +
For now, both the Human and Newman species show the same description on the Single Player galaxy setup screen.
 +
 
 +
 
 +
=Order of Events During the Turn=
 +
It can be helpful, sometimes important, to understand the order of event handling by the server.  The following summarizes the most pertinent parts of the sequence of server processing that starts once all players have ended their turn.
 +
 
 +
#TODO: update re recent changes to InitialMeter & CurrentMeter handling-- meter update immediately after turn advance, post-invasion back-propagation, etc
 +
 
 +
* orders are executed (invasions & colonizations done, fleet movement orders set, research & production queue changes set (but the progress on those queues is not yet handled)
 +
* fleets_move and resupply takes place (includes refueling and also ship-part upgrades)
 +
* empire visibility is updated & a pre-combat turn update is sent to players
 +
* combat situations are determined and combat takes place
 +
* empire visibility updated again
 +
* loss of empire capitals checked
 +
* all effects applied, including effect-specified sitrep generation, and including building new "current" meter values from "initial" meter values
 +
* empire visibility updated again
 +
* blockades, supply & resources updated
 +
* things made are added to the universe, techs researched are noted but not added to the empire
 +
* scripted events processed
 +
* meter effects applied again (rebuilds new "current" meter values from "initial" meter values, not directly adding another dollop to the previous iteration of current meter values).  Note: that this does '''not''' currently include an updated round of effect-specified sitrep generation and so discrepancies can arise from that.
 +
* population growth
 +
* back-propagation of meters ("initial" values overwritten by "current" values)
 +
* empire visibility updated again
 +
* turn number advances
 +
* the noted newly researched techs are added to the empire
 +
* empire visibility updated again (this time it counts for the new turn)
 +
* post-combat turn update is sent to players
 +
* players enter orders, cycle repeats
 +
 
 +
 
 +
[[Category:Guides]]
 +
[[Category:Scripting]]

Latest revision as of 22:46, 29 September 2019

This tutorial covers how to modify FreeOrion Content Script (FOCS) files. For details on all of the possible values, see FOCS Scripting Details.

Getting Started

All FOCS files are plain text files, though some contain extended characters, especially the language files.
When editing them a somewhat more advanced editor is necessary. For example, on Windows, the Notepad and Wordpad editors can cause trouble, but the third party NotePad++ editor should be fine. An added benefit of using NotePad++ is that one of our contributors has made an add-on to help with the FOCS syntax.

When a reference is made to the default/ directory, this refers to the Resources Files directory.
This directory varies on different systems and can be manually changed.
If you are unsure where this directory is:
Start FreeOrion → OptionsDirectories (next to last) → Resource Files.

Creating a new entry

Create a new file in the default/scripting/buildings/ directory, name it TUTORIAL_ONE.focs.txt
BuildingType
    name = "BLD_TUTORIAL_ONE"
    description = "BLD_TUTORIAL_ONE_DESC"
    buildcost = 15
    buildtime = 1
    icon = ""

It is good practice to make sure the file ends with a blank line.

This creates a very basic building type that could be built anywhere but has no effect.

No player would be able to build this building however, as their empire does not know how.
For now, we will just give the knowledge to everyone at the start of the game:

Edit default/scripting/starting_unlocks/items.inf
Add the following line at the top
Item type = Building name = "BLD_TUTORIAL_ONE"

If you start the game now and select the production screen at your home planet, you will see:

ERROR: BLD_TUTORIAL_ONE

Hover over that and the tooltip shows:

ERROR: BLD_TUTORIAL_ONE_DESC

This is because we have not told the game what our building should be labelled as, just to use the key reference of BLD_TUTORIAL_ONE.
Just like the filename, key references could be named anything, regardless of what label we want to use.
The name entry in the definition needs to be unique, but description can be shared among other entries if needed.

The key references are looked up based on the language selected, in one of the stringtables.
If an entry is not found, the game will use the default lookup as a fallback.
The default table is english, so we will just edit that one for now.

Edit default/stringtables/en.txt
Search for BLD_COL_SUPER_TEST_DESC
On the next blank line enter the following
BLD_TUTORIAL_ONE
A new building type from the scripting tutorial.

BLD_TUTORIAL_ONE_DESC
This is a brand new building type we just created.

Make sure there are blank lines before and after these new entries.

If you are planning to share these changes with others, always make sure any entries you create in other stringtables are included in the default stringtable.

You now have a very basic building in the game, though it has no purpose.

Keep in mind that this is just for demonstration. Building definitions should not be common structures built on every planet or more than once on any planet, in general. Structures like power plants or medical facilities would be covered by the infrastructure mechanic.

Entry Files

All of the FOCS entry files have a double extension of .focs.txt.
These files will be loaded regardless of the rest of their filename, or how deeply nested in the sub-directory they are.

Some special entry files have the extension .inf.
While most of these files can be freely edited, they can not be renamed or moved.

Any other file extension is not loaded into the game, unless an entry file specifically includes it.
The extension .macros is commonly used to denote scripting macros used in various entry files.
Entries that are not wanted in the game currently, but kept around for reference, are typically given the extension .disabled.

Entry files should never #include a file with another entry definition in it.

Directory Structure

Entry files are categorized by their type and should remain within the directory for that type (nested sub-directories are ok).
For example Tech entries can be anywhere in default/scripting/techs/, but should never be in default/scripting/fields/.
This only applies to the actual definition files, those with the extension .focs.txt.

The following directories within default/scripting are for .focs.txt entries:

alignments/ Alignment entries
buildings/ Building entries
empire_statistics/ Empire statistics entries
encyclopedia/ Encyclopedia topic entries
fields/ Field entries
monster_designs/ Ship loadout designs for space monsters
ship_designs/ Ship loadout design entries
ship_hulls/ Ship hull designs
ship_parts/ Ship part entries
specials/ Entries for specials
species/ Species entries
techs/ Tech entries

Required files

These are relative to default/scripting/:

keymaps.inf To Be Determined - Default keymap values
monster_fleets.inf Entries for monster fleets
starting_unlocks/buildings.inf Buildings pre-built on every starting homeworld.
starting_unlocks/fleets.inf Entries for fleets every player starts the game with.
starting_unlocks/items.inf Blueprints available at the start of the game to every player. For techs this means they are completed, for other types it allows the player to produce them.
techs/Categories.inf Categories that a tech must belong to. For now these should not be changed or added to, aside from possibly the graphic or colour definitions.

Additionally, definitions listed in any starting_unlocks/ file or monster_fleets.inf need to be avaiable.
The default AI may assume any or all of the default entries to exist.

Macros

A basic macro definition looks like this:

FIRST_ONE
'''2'''

The three apostrophies denote preformatted text, meaning any newlines are part of the macro.
Macro names should be in all uppercase, with underscores in place of spaces. They should also be uniquely named.

References to a macro are done by adding double brackets:

buildtime = [[FIRST_ONE]]

The game will end up seeing this as buildtime = 2

Macros may also use arguments:

NEW_MACRO
'''@[email protected] * @[email protected]'''
Multiplies the first argument by the second.
[[NEW_MACRO(2,3)]]
Results in 6 (2 * 3)

You can pass other macros for the arguments:

[[NEW_MACRO(FIRST_ONE,4)]]
Results in 8 (2 * 4)

Macros are mainly used to keep consistant values for multiple definitions.
When this is the case, it is best to have the macro definition in a file by itself, so other files can include it.
Sometimes macros are used for a complicated formula to help the readablity of the file. There is no need for these macro definitions to be separated if they are never used in another definition.

Including other files

Files are usually included for macro definitions.
You can include another file with the #include directive:

#include "some_file.macros"
Includes the file named some_file.macros

The directive should by on a line by itself, without any spaces before #include.
There is no restriction on what files are included, however you should not include files containing another FOCS entry in it. This would lead to a conflict when the entry is loaded twice.

Any path separators in the filename should use the forward slash ( / ) and not the backslash ( \ ).
If the filename begins with a path separator, it will refer to the Resource Directory, and not the file-system root.
The double-dot token ( .. ) will refer to the preceding directory, this should be used sparingly as it is hard to read (and easy to mistype) a filename like ../../../../ship.macros.

There is also special handling for a leading asterisk ( * ) in the name of the file, for wild-card matching.
This is useful for including a batch of files from a common place.
Placement of an asterisk outside of the first character, and the use of the single character wild-card ( ? ) are not supported.

Any specific file is only included once per file. When editing a file, it should include any files it needs for macros and not depend on inclusion within other files.

Examples

For the following examples, say we are editing a new file default/scripting/specials/TIMID_SHIP_AI.focs.txt:

#include "/scripting/abc.123"
would point to default/scripting/abc.123.
#include "../common/abc.123"
The above line would refer to default/scripting/common/abc.123.
#include "common/*_AI.macros"
Will include all of the files in default/scripting/fields/common (and any sub-directories) that end with _AI.macros.

This might include the imaginary files default/scripting/fields/common/SHIP_AI.macros and default/scripting/fields/common/BASE_AI.macros, but not default/scripting/fields/common/SHIP.macros.

Troubleshooting

Always check your log files when working with FOCS files.

Typically if there is a problem with the game parsing an entry, it will show the error in the console window.
The error will also be in the log file freeorion.log, which is located in your user directory (Options > Directories > Save files (parent directory))

If there are no errors shown, you can make sure the file is loading by setting the log level to TRACE by either:

  • editing the config.xml file in your user directory and change <log-level>VALUE</log-level> to <log-level>TRACE</log-level>
  • launching the game with the --log-level TRACE argument.

The client log file (freeorion.log) will now show each file as it was loaded in, as well as any files that were skipped.

If the issue is just with the name or description of the entry (it shows as ERROR: ENTRY_NAME in-game), make sure the entry is correct in the english stringtable (default/stringtables/en.txt).

If you need further help, post a question in the forums, attaching your log file will probably speed up any response.

Adding New Content

Linking a Tech and a Building

Create a new file in default/scripting/techs/
We will save this file as TUTORIAL_ONE.focs.txt

Tech
    name = "TECH_TUTORIAL_ONE"
    description = "TECH_TUTORIAL_ONE_DESC"
    short_description = "BUILDING_UNLOCK_SHORT_DESC"
    category = "DEFENSE_CATEGORY"
    researchcost = 4 * [[TECH_COST_MULTIPLIER]]
    researchturns = 1
    prerequisites = "DEF_ROOT_DEFENSE"
    unlock = Item type = Building name = "BLD_TUTORIAL_TWO"
    effectsgroups =
        EffectsGroup
            scope = And [
                Planet
                OwnedBy empire = Source.Owner
                [[CANDIDATE_BATTLE_CHECK]]
            ]
            effects = SetTroops value = Value + 1
    graphic = ""

#include "techs.macros"

#include "../common/shared.macros"

This tech:

  • Requires DEF_ROOT_DEFENSE to be researched first (which every player starts with)
  • Allows a player to build BLD_TUTORIAL_TWO (we have not created this yet)
  • Increases the speed of new troop recruitment on the planet by an additional 1 per turn, as long as combat is not occurring.

The short description is for the hover text on the tech screen, as well as the brief description at the top of the 'pedia entry.
Techs all belong to one tech category, these are defined in Categories.inf. It is recommended to use one of the existing categories.

Notice researchcost uses the macro TECH_COST_MULTIPLIER, which is defined in default/scripting/common/shared.macros So we also #include that file at the bottom.
The ../ means to go back one directory, in this case to default/scripting (because our file is in default/scripting/techs).
This definition also uses the CANDIDATE_BATTLE_CHECK macro, so the techs.macros file is needed for that.

For the first building, we will reuse the earlier BLD_TUTORIAL_ONE

For this next building, we will be showing alternate ways to reach a desired effect. If you just want a workable version without the back and forth, scroll to the end of this section.

Let's go ahead and add the second building in, create the file default/scripting/buildings/TUTORIAL_TWO.focs.txt

BuildingType
    name = "BLD_TUTORIAL_TWO"
    description = "BLD_TUTORIAL_TWO_DESC"
    buildcost = 20
    buildtime = 3
    location = And [
        Planet
        Not Contains Building name = "BLD_TUTORIAL_TWO"
        OwnedBy empire = Source.Owner
        TargetPopulation low = 1
    ]
    EnqueueLocation = [[ENQUEUE_BUILD_ONE_PER_PLANET]]
    effectsgroups = [
        EffectsGroup
            scope = And [
                Planet
                Object id = Source.PlanetID
            ]
            effects = SetMaxTroops value = Value + 3
        EffectsGroup
            scope = And [
                Planet
                Ownedby empire = Source.Owner
                Contains Building name = "BLD_TUTORIAL_TWO"
                Contains Building name = "BLD_TUTORIAL_ONE"
            ]
            effects = SetMaxDefense value = Value + 5
    ]
    icon = ""

#include "../common/shared.macros"

This building can only be built on a planet with at least 1 population, and is limited to one per planet.
It also has a couple of effects, the first allows an additional 3 troops on the planet
The second allows an extra defense of 5, but only if there is also a BLD_TUTORIAL_ONE on the planet.

location tells the game where this building can be constructed.

  • check all of the planets
  • for each planet that is without a BLD_TUTORIAL_TWO
  • that is also owned by the player
  • that also has a population of at least 1

EnqueueLocation restricts when a building can be placed into the production queue.

The effectsgroups contains any effects and the conditions of when and where to apply them.
There are a number of different ways to construct these, so we will show two different methods.

Looking at the first EffectsGroup, the scope defines the Target of our effect:

  • check all of the planets
  • for each one that has an ID that is the same as the sources(this building) planet ID. ID is a unique identifier, so this will only match one result.

For the second EffectsGroup:

  • check all of the planets
  • for each one with the same owner as the sources(this building) owner.
  • that has a completed BLD_TUTORIAL_TWO
  • and also has a completed BLD_TUTORIAL_ONE

effects define what effects apply. The Target variable can be used here if needed, but it can not be used in scope or activation because they define what the target is.

For a more in-depth look at all of the possible attributes and descriptions of each, see Effects

Remember to add in the stringtable entries for the new tech and building:

TECH_TUTORIAL_ONE
Tutorial tech 1

TECH_TUTORIAL_ONE_DESC
The first tutorial tech.

BLD_TUTORIAL_TWO
Tutorial building 2

BLD_TUTORIAL_TWO_DESC
Second tutorial building, adds troops and defense.

Start a new single player game with 1 AI player and Planet Density set to High.

If you play with this building for awhile, once you have it on multiple planets you may notice an issue.
Wherever we have both buildings constructed, it increases the defense effect for the buildings on all of our planets.
That might be a good feature for some other building, but it is not really what we intend here.

Once you have these two buildings on a couple of planets, save the game and exit before we make further changes.
The game will load the FOCS files into memory, so changes made will not neccesarily take effect until restarted.

One way to try and solve this is by adding a stacking group to the effect.
Change the effectsgroups of BLD_TUTORIAL_TWO so it looks like this:

    effectsgroups = [
        EffectsGroup
            scope = And [
                Planet
                Object id = Source.PlanetID
            ]
            effects = SetMaxTroops value = Value + 3
        EffectsGroup
            scope = And [
                Planet
                Ownedby empire = Source.Owner
                Contains Building name = "BLD_TUTORIAL_TWO"
                Contains Building name = "BLD_TUTORIAL_ONE"
            ]
            stackinggroup = "STACKING_TUTORIAL_TWO_DEFENSE"
            effects = SetMaxDefense value = Value + 5
    ]

stackinggroup only allows the first instance of tha effect to apply, ignoring any others. You might create a new building or tech with the same stackinggroup name, and only the first one would apply.

If we gave both effects the same stackinggroup, only the troop effect would apply.

After saving the changes, load the previous game and click on next turn.
The game state is loaded as we left it, once we start a new turn everything is reprocessed.

Now you will see only one defense effect at each planet. While this functionally works how we want, if you hover over a couple of planets they show the effect all coming from the same planet (if they have a supply connection).
What we really want is for the effect to only apply to the planet it is built at.

Our first effect works fine for this. We could combine the effects onto one effect group, saving us from doing the same scope check twice:

effects = [
    SetMaxTroops value = Value + 3
    SetMaxDefense value = Value + (5 * (If condition = ContainedBy Contains Building name = "BLD_TUTORIAL_ONE"))
]

If returns either a 1 when true, otherwise is returns a 0.
This would show a bonus of 0 for defense when we do not have a BLD_TUTORIAL_ONE constructed. If everything showed a notice for not having an effect, the user interface would be very cluttered.

Instead of showing useless information, we will just modify a copy of the first EffectGroup.
default/scripting/buildings/TUTORIAL_TWO.focs.txt

BuildingType
    name = "BLD_TUTORIAL_TWO"
    description = "BLD_TUTORIAL_TWO_DESC"
    buildcost = 20
    buildtime = 3
    location = And [
        Planet
        Not Contains Building name = "BLD_TUTORIAL_TWO"
        OwnedBy empire = Source.Owner
        TargetPopulation low = 1
    ]
    effectsgroups = [
        EffectsGroup
            scope = And [
                Planet
                Object id = Source.PlanetID
            ]
            effects = SetMaxTroops value = Value + 3
        EffectsGroup
            scope = And [
                Planet
                Object id = Source.PlanetID
                Contains Building name = "BLD_TUTORIAL_ONE"
            ]
            effects = SetMaxDefense value = Value + 5
    ]
    icon = ""

#include "../common/shared.macros"

Everything should be working as we had before. When you are testing your changes you can destroy a building by right clicking on the icon for it, on the planet side screen.

We have left the icon blank in all of our examples, letting the game decide the default icon to use. Where mentioned, icon or graphic are required fields and wll be relative to the art directory (default/data/art/). If sharing these wih others, you might pick the icon or graphic asset that best suits the entry.

Ships

Any single ship is constructed from a ship design, which is a combination of a ship hull and zero or more ship parts.

The previous section introduced a number of errors to show ways to troubleshoot them. The remaining sections will concentrate more on anything specific to them. Stringtable entries will be ommitted to keep the sections briefer, feel free to add them as appropriate.

Ship Parts

Ship Part Class
ShortRange
FighterBay
FighterHanger
Shield
Armour
Troops
Detection
Stealth
Fuel
Colony
Speed
General
Bombard
Research
Industry
Trade
ProductionLocation
Keep in mind, these parts will not be available to an empire until they unlock them either by researching a tech, getting them at the start of the game, or through some other means.

You can see what parts are in the game, but not yet unlocked by your empire, by going to the ship design screen and selecting Unavailable in the parts filter.

A new weapon
default/scripting/ship_parts/TUT_WEAPON.focs.txt

Part
    name = "TUT_WEAPON"
    description = "TUT_WEAPON_DESC"
    class = ShortRange
    damage = 4
    shots = 1
    mountableSlotTypes = External
    buildcost = 25 * [[FLEET_UPKEEP_MULTIPLICATOR]]
    buildtime = 2
    location = OwnedBy empire = Source.Owner
    icon = ""

#include "../common/shared.macros"

class defines what kind of part this is: a short range weapon, a fighter weapon, a piece of armor, etc.
For direct fire weapons (ShortRange), there is a primary stat of damage and a secondary stat of shots.
damage refers to the amount of damage for each shot.
shots is how many times this part shoots during each combat round, this may be omitted and defaults to 1.
The FighterHangar class has a primary stat capacity and a secondary damage.

mountableSlotTypes are slots types that this part will fit into. For balancing purposes: weapons, armor, and sensors should usually be limited to the outside of the ship, with other types restricted to the interior. There are exceptions to this, such as troop pods, but the majority stick to this guideline.
For ship designs, the buildcost of each part and the hull will be accumulative. However the buildtime is not, the longest time of all of the parts will be used.
location limits where ships designs with this part may be constructed. Some part might be restricted to planets with access to a specific special, or a certain system type.

A new armor
default/scripting/ship_parts/TUT_ARMOR.focs.txt'

Part
    name = "TUT_ARMOR"
    description = "TUT_ARMOR_DESC"
    class = Armour
    capacity = 4
    mountableSlotTypes = [External Internal]
    buildcost = 6 * [[FLEET_UPKEEP_MULTIPLICATOR]]
    buildtime = 4
    location = OwnedBy empire = Source.Owner
    effectsgroups = [
        EffectsGroup
            scope = Source
            stackinggroup = "TUT_ARMOR_STACKING"
            effects = SetStealth value = Value + 2
    ]
    icon = ""

#include "../common/shared.macros"

Many parts simply have a capacity. What that capacity relates to depends on the class of the part, in this case it is the amount of extra maximum structure a ship design has.
This allows parts to have effects applied on them from other events with the SetCapacity and SetMaxCapacity effects.

Ship Hulls

A new ship hull:
default/scripting/ship_hulls/TUT_HULL.focs.txt

Hull
    name = "TUT_HULL"
    description = "TUT_HULL_DESC"
    speed = 50
    fuel = 4
    stealth = 6
    structure = 20
    slots = [
        Slot type = External position = (0.50, 0.35)
        Slot type = External position = (0.50, 0.60)
        Slot type = External position = (0.80, 0.45)
        Slot type = Internal position = (0.30, 0.40)
    ]
    buildCost = 40 * [[FLEET_UPKEEP_MULTIPLICATOR]]
    buildTime = 4
    location = Contains And [
        Building name = "BLD_SHIPYARD_BASE"
        OwnedBy empire = Source.Owner
    ]
    effectsgroups = [
        [[REGULAR_HULL_DETECTION]]
        [[SCAVANGE_FUEL_UNOWNED]]
        [[UNOWNED_GOOD_VISION]]
        [[UNOWNED_MOVE]]
    ]
    icon = "icons/ship_hulls/basic-large-hull_small.png"
    graphic = "hulls_design/basic-large-hull.png"

#include "ship_hulls.macros"

#include "../common/shared.macros"

speed, fuel, stealth, and structure are all starting values.
slots has an entry for each slot and the coordinates to display that slot on the graphic during ship design.
Since the position of the slots need to line up with the graphic used, we will just use the basic large hull here.

Ship Designs

New ship design
default/scripting/ship_designs/SD_TUTORIAL.focs.txt

ShipDesign
    name = "SD_TUTORIAL"
    description = "SD_TUTORIAL_DESC"
    hull = "TUT_HULL"
    parts = [
        "TUT_WEAPON"
        "TUT_WEAPON"
        "TUT_ARMOR"
        "TUT_ARMOR"
    ]
    model = "mark1"

parts need to stay in the same order as they are defined in the hull.
The first three are all external slots, and the fourth is an internal slot.
Since our new armor part can fit in an internal or external slot, this is ok.

Ship designs within the Resource Files are available to all empires.
Designs saved from inside the game are saved in the User Directory, and only available to the human client.

There are also designs for space monster ships, which follow the same layout as other designs.
They are in a separate directory as the fleets are handled differently.

Fleets

Player fleets are typically only defined within default/scripting/starting_unlocks/fleets.inf
These encompass what ships each player starts the game with, and how they are grouped.
A sample fleet:

Fleet
    name = "FN_TUTORIAL"
    ships = [
        "SD_TUTORIAL"
        "SD_TUTORIAL"
        "SD_MARK_1"
    ]

This would create a fleet with two ships using our new ship designs, and one of the basic mark 1 ships.

Monster Fleets

Below is an example of the Small Krill space monster:

MonsterFleet
    name = "SM_KRILL_1"
    ships = [
        "SM_KRILL_1"
    ]
    spawnrate = 0.5
    spawnlimit = 9999
    location = And [
        Not Contains Monster
        Not WithinStarlaneJumps jumps = 2 condition = Contains And [
            Planet
            OwnedBy affiliation = AnyEmpire
        ]
    ]

spawnrate defines how often the space monster might appear. This is factored with other values, including the frequency set by the player.
spawnlimit defines the maximum number allowed in the game. The monster would not spawn anymore during the current turn, if there are more than this limit.

String Tables

String tables are the language files used when displaying information to a user.

These files are located in default/stringtables/ and are separated by language, the default being the English file en.txt.
Each client has a language setting, which determines which file it uses for references. Any references not found are then checked for in the default file.

When an entry is given a name="BLD_ONE", anytime the game passes that entry around it uses BLD_ONE.
When the game displays information about it to the user, the users client translates it according to their string table.

Given the entry in en.txt:

BLD_ONE
Building One

Any time the building name is displayed to the user, they will see Building One.

Macros

Stringtable Macros
Type Value
planet ID
system ID
fleet ID
ship ID
building ID
empire ID
tech string
buildingtype string
special string
shiphull string
shippart string
species string
encyclopedia string
Macros in string tables are not handled exactly the same as macros in other FOCS files.

Like a normal macro, you can use a string table entry to swap the value for the text.

[[BLD_ONE]]
swaps [[BLD_ONE]] with Building One

Alternatively, macros may have a preceding type followed by a value which is a string table entry or an ID.
These string table macros are used to create a link to a 'pedia entry.

[[buildingtype BLD_ONE]]
swaps [[buildingtype BLD_ONE]] with a link to the BLD_ONE pedia entry displayed as Building One.

Each of the string table entries are loaded into their type, such as tech. To create the correct link you need to know which type they belong to.
If the wrong category is used, a blank 'pedia entry will be shown when the link is clicked on.

SitReps

SitRep Variables
tag
text
rawtext
planet
system
ship
fleet
building
field
combat
empire
shipdesign
predefinedshipdesign
tech
buildingtype
special
shiphull
shippart
species
fieldtype
A SitRep message can be created as an effect in any EffectsGroup
GenerateSitRepMessage
    message = "CUSTOM_SITREP_INTRODUCTION"
    label = "SITREP_WELCOME_LABEL"
    icon = "icons/tech/categories/spy.png"
    parameters = [
        tag = "tech" data = "SPY_CUSTOM_ADVISORIES"
        tag = "system" data = Target.SystemID
    ]
    empire = Source.Owner
The introductory sitrep message.

label is a reference to a string table entry. It is used for filtering sitrep messages, sitreps can share labels.

Each tag in the parameters is passed as a variable to the message.
The message is a string table entry, the variables are referenced with surrounding percentage signs (%).

CUSTOM_SITREP_INTRODUCTION
'''A custom introduction that references the tech %tech% and the system %system%.'''

These variables are shown as links to the item or pedia entry.

Variables are predefined, a custom variable will not work.
The variable text will be translated from the supplied userstring.(string table match)
rawtext will not be translated and will be displayed as defined.

empire defines which empires will receive this message. It is optional, and if omitted the message will be shown to all empires.

General purpose sitreps that should be shown at the start of the game should be placed into the default/customizations/custom_sitreps.txt file.
There are a number of examples for different sitrep options in this file as well.

Encyclopedia Articles

The encyclopedia articles are 'pedia entries which would not belong to a specific entry.
These include guides, game concepts and overviews for groups of entries.

The definitions are placed in default/scripting/encyclopedia
Except for icon, all of the fields are string table entries.

Fields

Fields are defined in default/scripting/fields, and represent effects that span a limited area in space.
While many of these entries are created during universe generation they can also be created as an effect of another entry using CreateField.

effects = CreateField type = "FLD_ACCRETION_DISC" size = 10

Specials

Specials are items which can be attached to most of the other universe objects, typically they are found on planets.
They are defined in default/scripting/specials

Similar to monster fleets, they have a spawnrate field and an optional spawnlimit field that will limit how often they will occur.

Species

A good amount of info is packed into the effects for species entries. Historically this was for processing efficiency and to ensure the ordering of specific effects.

Following Effects(Species), note the fields for Playable, Native, CanProduceShips, and CanColonize.
The default for these attributes is false, meaning if they are not listed in the file, the species can not perform that action.
Playable determines if the player can select them as their starting species, and if the species is available to the AI.
Native species are distributed among planets at the start of the game, according with the game-setup options. They are not controlled by an AI client and so do not typically construct buildings or ships.

foci contains each planet focus type that the species is able to select from. This does not give the species the knowledge of that focus type, only the ability to use it if they later acquire it.

preferredfocus is the focus type that will give certain bonuses, like increased happiness, to that planet when used.

In addition to having CanProduceShips and CanColonize in the species entry, the species will need a colony building entry and knowledge of how to construct them.
Entries for other species colony buildings are in default/scripting/buildings/colonies. For official additions, the col_bld_gen.py script should be edited instead and generated from that script.
This file is a Python script and will need the expertise of someone that can program in that language.
Most colony buildings are granted knowledge of to all players at the start of the game from default/scripting/starting_unlock/items.inf.
Some of the species, such as any of the extinct species, are not included here, but granted after a tech is researched or some other criteria is met.

Example

The following will be a step by step instruction on "quickly" creating a new playable species.

Make sure you are using a decent text editor before starting (mainly not Notepad or Wordpad, see above).

Change to the (path to freeorion)/default/scripting directory.
Copy species/SP_HUMAN.focs.txt to species/SP_NEW_MAN.focs.txt

Open this new file and change the following fields:

  • name = "SP_NEW_MAN"
  • description = "SP_NEW_MAN_DESC"

Next, make sure to create a colony building for this species:
Copy buildings/colonies/SP_HUMAN.focs.txt to buildings/colonites/SP_NEW_MAN.focs.txt

Open the new file and replace the any human entries with entires for newman. Replace:

  • "BLD_COL_HUMAN" with "BLD_COL_NEW_MAN"
  • "BLD_COL_HUMAN_DESC" with "BLD_COL_NEW_MAN_DESC"
  • "SP_HUMAN" with "SP_NEW_MAN"


These new entries need to be creating in the stringtables:

  • Open the default stringtable: (path to freeorion)/default/stringtables/en.txt.
  • Find the entry for SP_HUMAN (CTRL+F in most editors).
  • On the line just before SP_HUMAN, enter the following:
SP_NEW_MAN
Newman

SP_NEWMAN_DESC
A new species with no differences from Humans

  • Next, find the entry for BLD_COL_HUMAN
  • On the line just before, enter the following:
BLD_COL_NEW_MAN
Newman Colony

BLD_COL_NEW_MAN_DESC
[[BLD_COL_PART_1]] [[species SP_NEW_MAN]] colony. [[BLD_COL_PART_2]] Newman colony [[BLD_COL_PART_3]].

Start the game, the Newman species should be available to select now.

Note that we did not change the gameplay_description field in the species entry, normally each species should have a new stringtable entry here. For now, both the Human and Newman species show the same description on the Single Player galaxy setup screen.


Order of Events During the Turn

It can be helpful, sometimes important, to understand the order of event handling by the server. The following summarizes the most pertinent parts of the sequence of server processing that starts once all players have ended their turn.

  1. TODO: update re recent changes to InitialMeter & CurrentMeter handling-- meter update immediately after turn advance, post-invasion back-propagation, etc
  • orders are executed (invasions & colonizations done, fleet movement orders set, research & production queue changes set (but the progress on those queues is not yet handled)
  • fleets_move and resupply takes place (includes refueling and also ship-part upgrades)
  • empire visibility is updated & a pre-combat turn update is sent to players
  • combat situations are determined and combat takes place
  • empire visibility updated again
  • loss of empire capitals checked
  • all effects applied, including effect-specified sitrep generation, and including building new "current" meter values from "initial" meter values
  • empire visibility updated again
  • blockades, supply & resources updated
  • things made are added to the universe, techs researched are noted but not added to the empire
  • scripted events processed
  • meter effects applied again (rebuilds new "current" meter values from "initial" meter values, not directly adding another dollop to the previous iteration of current meter values). Note: that this does not currently include an updated round of effect-specified sitrep generation and so discrepancies can arise from that.
  • population growth
  • back-propagation of meters ("initial" values overwritten by "current" values)
  • empire visibility updated again
  • turn number advances
  • the noted newly researched techs are added to the empire
  • empire visibility updated again (this time it counts for the new turn)
  • post-combat turn update is sent to players
  • players enter orders, cycle repeats