Difference between revisions of "FOCS Scripting Tutorial"

From FreeOrionWiki
Jump to: navigation, search
m (out of date)
(Initial 0.4.5+ rewrite)
Line 1: Line 1:
'''Note: This page is very out of date, and does not represent the current system for defining techs or other game content.  [[User:Geoff the Medio|Geoff the Medio]] 09:56, 24 Feb 2007 (EST)'''
+
{{WIP}}
  
-------
+
This tutorial covers how to modify FreeOrion Content Script (FOCS) files.  For details on all of the possible values, see [[Effects]].
  
'''Texas Drek’s Downhome Effects Tutorial'''
+
All FOCS files are plain text files, though some contain extended characters, especially the language files.<br />
 +
{{FOCS_Notepad_Notice}}
  
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.
+
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, or want to change it:
 +
;Start FreeOrion
 +
: select ''Options''
 +
:: select the tab ''Directories'' (next to last)
 +
::: see ''Resource Files''.
 +
On Windows this is typically 'C:\Freeorion\default\'<br />
 +
Be aware if you change it, you should likely copy the contents of the original default directory to the new location.
  
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”.
+
==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 = ""
  
=Step 1: Define your tech=
+
</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.
  
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.
+
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>
  
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 [[V3_ScratchPad|cliff notes]], but the [[Effects]] document is a must.)  Read [http://www.freeorion.org/forum/viewtopic.php?p=17335#17335 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 can be used in the actual game.
+
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.
  
If you have any questions about [[requirements]] or [[effects]] doc, ask away on the forum. Someone will answer.
+
The key references are looked up based on the language selected, in one of the stringtables.<br />
 +
You can start with the file that suits you best, for this example we will use the english file.
 +
;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">
  
Here’s the tech I’ve come up with, for the purposes of this tutorial:
+
BLD_TUTORIAL_ONE
 +
A new building type from the scripting tutorial.
  
Drek’s Effects Tutorial
+
BLD_TUTORIAL_ONE_DESC
A marvelous, high tech tutorial that enlightens all who read it.
+
This is a brand new building type we just created.
Effect: +2 Max Science to all friendly worlds set to the Science Focus
+
  
=Step 2Copy n' paste the correct XML template.=
+
</pre>
 +
:Make sure there are blank lines before and after these new entries.
 +
If you were going to share this entry with others, create the same entries in each of the other stringtable files as well. Few people are fluent in all of these languages, so simply copy the same text into the same spot in each file.  If you can provide a translated version, please do as it cuts down on work others would need to do.
  
The templates are: [[Effects#Tech|tech]], [[Effects#BuildingType|building]], and [[Effects#Special|special]].  
+
You now have a very basic building in the game, though it has no purpose.
  
You’ll need to fill out the “fields” in the XML form.  Since “Drek’s Effects Turorial” is a technology, I’ll be filling out the technology XML form:
+
==Entry Files==
 +
All of the FOCS entry files have a double extension of '''.focs.txt'''.<br />
 +
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'''.<br />
 +
While most of these files can be freely edited, they can not be renamed or moved.
  
<Tech>
+
Any other file extension is not loaded into the game, unless an entry file specifically includes it.<br />
    <name>NAME</name>
+
The extension '''.macros''' is commonly used to denote scripting macros used in various entry files.<br />
    <description>DESCRIPTION</description>
+
Entries that are not wanted in the game currently, but kept around for reference, are typically given the extension '''.disabled'''.
    <type>TYPE</type>
+
    <category>CATEGORY</category>
+
    <research_cost>RESEARCH_COST</research_cost>
+
    <research_turns>RESEARCH_TURNS</research_turns>
+
    <prerequisites>
+
        <prereq>NAME0</prereq>
+
        <prereq>NAME1</prereq>
+
        ...
+
        <prereq>NAMEN</prereq>
+
    </prerequisites>
+
    <unlocked_items>
+
        ITEM0
+
        ITEM1
+
        ...
+
        ITEMN
+
    </unlocked_items>
+
    <effects>            [optional -- may be left out]
+
          EFFECTS_GROUP0
+
          EFFECTS_GROUP1
+
          ...
+
          EFFECTS_GROUPN
+
    </effects>
+
</Tech>
+
  
'''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 should never '''#include''' a file with another entry definition in it.
  
    <Tech>
+
===Directory Structure===
        <name>LEARN_DREK_TUTORIAL</name>
+
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'''.
  
'''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.
+
The following directories within default/scripting are for '''.focs.txt''' entries:
 +
{|
 +
|alignments/ || [[Alignment]] entries
 +
|-
 +
|buildings/ || [[Building]] entries
 +
|-
 +
|empire_statistics/ || [[Empire_Stats|Empire statistics]] entries
 +
|-
 +
|encyclopedia/ || [[Encyclopedia]] topic entries
 +
|-
 +
|fields/ || [[Field]] entries
 +
|-
 +
|monster_designs/ || [[Ship_Design|Ship loadout designs]] for [[Space_Monsters|space monsters]]
 +
|-
 +
|ship_designs/ || [[Ship_Design|Ship loadout design]] entries
 +
|-
 +
|ship_hulls/ || [[Ship_Hull|Ship hull]] designs
 +
|-
 +
|ship_parts/ || [[Ship_Part|Ship part]] entries
 +
|-
 +
|specials/ || Entries for [[specials]]
 +
|-
 +
|species/ || [[Species]] entries
 +
|-
 +
|techs/ || [[Techs|Tech]] entries
 +
|-
 +
|}
  
  <description>LEARN_DREK_TUTORIAL_DESC</description>
+
===Required files===
 +
These are relative to default/scripting/:
 +
{|
 +
|keymaps.inf || To Be Determined - Default keymap values
 +
|-
 +
|monster_fleets.inf || Entries for [[Space_Monsters|monster]] fleets
 +
|-
 +
|starting_unlocks/buldings.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.
  
'''TYPE:''' This is the type of technology.  In FreeOrion, there are three different types of techs:
+
==Macros==
* TT_THEORY  A theory.  A theory contains applications, and generally should have little or no effects.
+
A basic macro definition looks like this:
* TT_APPLICATION  An application.  An application is contained by a theory, and has some sort of minor effect and/or unlocks a building.
+
<pre style="color: blue; display: block">FIRST_ONE
* TT_REFINEMENT  A refinementA 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.
+
'''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 spacesThey should also be uniquely named.
  
For the Type field, you’ll need to input one of the above tech types.  Most techs (esp. techs that actually do things) should be Applications. 
+
References to a macro are done by adding double brackets:
 +
<pre style="color: blue; display: block">buildtime = [[FIRST_ONE]]</pre>
 +
The game will end up seeing this as '''buildtime = 2'''<br />
  
    <type>TT_APPLICATION</type>
+
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)
  
'''CATEGORY:''' There are five categories that “hold” techs in FreeOrion. You need to assign your technology to one of themAn application or refinement should be in the same category as it’s parent theory.
+
Macros are mainly used to keep consistant values for multiple definitions.<br />
 +
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 />
 +
Sometimes macros are used for a complicated formula to help the readablity of the fileThere is no need for these macro definitions to be separated if they are never used in another definition.
  
The categories you can use:
+
==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>.
 +
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.
  
* LEARNING_CATEGORY  deals with the science meter, and fundamental technologies
+
==Troubleshooting==
* GROWTH_CATEGORY  deals with the health of a population, the size of a population, and growing food.
+
If the entry is in the game, but does not show the name or the description correctly, check the stringtable entry for your selected language.
* PRODUCTION_CATEGORY  deal with building stuff like ships and structures.  The mining and industry meters are governed here.
+
* CONSTRUCTION_CATEGORY  deals with developing your colonies.  The construction meter is handled here.
+
* ECONOMICS_CATEGORY deals with the trade meter, money, etc.
+
  
The technology I’m developing clearly falls into the Learning Category.
+
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))
  
  <category>LEARNING_CATEGORY</category>
+
If there are no errors shown, you can make sure the file is loading by setting the log level to TRACE.<br />
 +
Either edit the config.xml file in your user directory or launch the game with the '''--log-level TRACE''' argument.<br />
 +
The client log file (freeorion.log) will now show each file as it was loaded in, as well as any files that were skipped.
  
'''RESEARCH_COST:'''  The number of research points a player needs to spend each turn to research a tech.
+
If you need further help, post a question in the [http://www.freeorion.org/forum/ forums].
 
+
'''RESEARCH_TURNS:'''  The number of turns required to research a tech.
+
 
+
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.
+
 
+
    <research_cost>10</research_cost>
+
    <research_turns>5</research_turns>
+
 
+
'''PREREQUISITES:''' The techs required before research can start.  An application should always have its parent theory as a prerequisite.  You’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.
+
 
+
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.
+
 
+
Let’s say the Theory of Drek is the parent theory for my technology:
+
 
+
    <prerequisites>
+
        <prereq>LEARN_THEORY_OF_DREK</prereq>
+
    </prerequisites>
+
 
+
Notice the <prereq> tags around the NAMEN values.  We only need to refer to techs by their placeholder name here.
+
 
+
'''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.
+
 
+
If your tech doesn’t unlock any buildings, then just delete this field.
+
 
+
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:
+
 
+
  <unlocked_items>
+
    <Item>
+
      <type>UIT_BUILDING</type>
+
      <name>BUILDING_TOWER_BABEL</name>
+
    </Item>
+
    <Item>
+
      <type>UIT_BUILDING</type>
+
      <name>BUILDING_GREAT_PRYAMIDS</type>
+
    </Item>
+
  </unlocked_items>
+
 
+
Notice how each building unlocked has its own little [[Effects#Item|item XML markup]].
+
 
+
So far my tech looks like this:
+
 
+
<Tech>
+
  <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>
+
    <prereq>LEARN_THEORY_OF_DREK</prereq>
+
  </prerequisites>
+
  <effects>
+
    EFFECTS_GROUP0
+
    EFFECTS_GROUP1
+
    ...
+
    EFFECTS_GROUPN
+
  </effects>
+
</Tech>
+
 
+
=Step 3: The Defining the Effects Groups=
+
 
+
This is the hard part.  Defining an [[Effects#EffectsGroup|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 very versatile--the trade off is complexity: it’s not as trivial as just filling out fields in a form.
+
 
+
You can have as many, [[Effects#EffectsGroup|effects groups]] as you need to define what a tech does, including none, as indicated by the note in the template: [optional -- may be left out].  Notice the <effects> tags around all of the effects groups.
+
 
+
My effect...
+
 
+
+2 Max Science to all friendly worlds set to Primary/Secondary Science Focus
+
 
+
...requires just one [[Effects#EffectsGroup|effects group]].
+
 
+
Just like techs, [[Effects#EffectsGroup|effects groups]] have an XML form that you need to fill out.  Here it is:
+
 
+
  <EffectsGroup>
+
      <scope>SCOPE</scope>
+
      <activation>ACTIVATION</activation>
+
      <stacking_group>STACKING_GROUP</stacking_group>
+
      <effects>
+
          EFFECT0
+
          EFFECT1
+
          ...
+
          EFFENTN
+
      </effects>
+
  </EffectsGroup>
+
 
+
'''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.
+
 
+
First off, we need to pick out all friendly worlds.  We can do that with the [[Effects#EmpireAffiliation|EmpireAffiliation condition]]:
+
 
+
  <Condition::EmpireAffiliation>
+
      <empire_id>Source.Owner</empire_id>
+
      <affiliation>AFFIL_SELF</affiliation>
+
      <exclusive>1</exclusive>
+
  </Condition::EmpireAffiliation>
+
 
+
Notice I filled out empire_id with source.owner.  This is a [[Effects#Types_and_Expressions|variable]]...there are many [[Effects#Types_and_Expressions|variables]] you can access, listed in the [[Effects]] document.
+
 
+
I filled out the affiliation field with an [[Tech_Description_Enums|enumeration]].  Certain fields require certain [[Tech_Description_Enums|enumeration]]: it’s mostly self explanatory.  For example, the [[Effects#PlanetType|PlanetType condition]] requires [[Tech_Description_Enums#PlanetType|PlanetType enumerations]].
+
 
+
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.
+
 
+
When FreeOrion executes this [[Effects#EmpireAffiliation|EmpireAffiliation 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 [[Effects#Type|Type]] condition.
+
 
+
  <Condition::Type>OBJ_POP_CENTER</Condition::Type>
+
 
+
OBJ_POP_CENTER is yet another [[Tech_Description_Enums#UniverseObjectType|enumeration]].  Now, all population centers will be selected, including any future space based colonies that are not on planets.
+
 
+
We need to glue these two conditions together.  The [[Effects#And|And condition]] does exactly that:
+
 
+
  <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::And>
+
 
+
Pretty cool, huh?  By sticking our conditions into an [[Effects#And|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. 
+
 
+
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”.
+
 
+
First, let’s select all worlds that have the primary science focus, using the [[Effects#FocusType|FocusType condition]]:
+
 
+
  <Condition::FocusType>
+
      <primary>1</primary>
+
      <FocusType>FOCUS_RESEARCH</FocusType>
+
  </Condition::FocusType>
+
 
+
I filled out the primary field with a 1, meaning “true”.  This will select all worlds with a Primary focus in science.  It really will select ALL worlds, including those of enemy empires.
+
 
+
FOCUS_RESEARCH is another [[Tech_Description_Enums#FocusType|enumeration]].
+
 
+
We need to do the same thing to select all worlds with Secondary focus in science, only this time the primary field would be filled in with "0". 
+
 
+
The two [[Effects#FocusType|FocusType conditions]] need to be glued together.  Since the effect works on Secondary *or* Primary focus, use the [[Effects#Or|condition Or]]:
+
 
+
  <Condition::Or>
+
      <Condition::FocusType>
+
        <primary>1</primary>
+
        <FocusType>FOCUS_RESEARCH</FocusType>
+
      </Condition::FocusType>
+
      <Condition::FocusType>
+
        <primary>1</primary>
+
        <FocusType>FOCUS_RESEARCH</FocusType>
+
      </Condition::FocusType>
+
  </Condition::Or>
+
 
+
Finally, to complete our scope field, we need to glue both pieces together.  Just insert the [[Effects#Or|Or condition]] into the [[Effects#And|And condition]]:
+
 
+
  <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::FocusType>
+
          <primary>1</primary>
+
          <FocusType>FOCUS_RESEARCH</FocusType>
+
        </Condition::FocusType>
+
        <Condition::FocusType>
+
          <primary>1</primary>
+
          <FocusType>FOCUS_RESEARCH</FocusType>
+
        </Condition::FocusType>
+
      </Condition::Or>
+
    </Condition::And>
+
  </scope>
+
 
+
Notice, you can nest And/Or conditions.  The above states:
+
 
+
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.
+
 
+
Seems like a lot of work spelled out like that, but it’s easier once you get the hang of it.
+
 
+
Notice that everything above is contained by the scope XML field of the [[Effects#EffectsGroup|Effects Group]].  We now need to fill out the activation field.
+
 
+
  <activation>
+
    <Condition::Self/>
+
  <activeation>
+
 
+
The activation condition is just like any other condition, except that it acts only on the Source object (the object that the EffectsGroup is attached to), rather than everything in the game universe.  You use the same conditions as the scope field—if the Source object is selected by the condition, then the effect fires.  This is useful if 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.
+
 
+
It’s safe just to enter the [[Effects#Self|Self condition]], which ensures the effect always fires.
+
 
+
Next, the stacking group:
+
 
+
  <stacking_group>STACK_DREK_TUTORIAL</stacking_group>
+
 
+
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.
+
 
+
For technologies, it’s safe just to enter the name of the tech, perhaps prefixed with the word “STACK”.
+
 
+
Now, the payload, the actual effects:
+
 
+
  <effects>
+
    <Effect::SetMeter>
+
      <meter>METER_RESEARCH</meter>
+
      <value>Target.MaxResearch+2</value>
+
      <max>1</max>
+
    </Effect::SetMeter>
+
  </effects> 
+
 
+
My tech has only one effect...but you can include as many effects as you need in an [[Effects#EffectsGroup|effects group]].
+
 
+
The most common effect is [[Effects#SetMeter|SetMeter]].  The first field, meter, determines which meter is effected.  METER_RESEARCH is an [[Tech_Description_Enums#MeterType|enumeration]]. 
+
 
+
The value field is filled by an [[Effects#Types_and_Expressions|expression]].  An [[Effects#Types_and_Expressions|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.
+
 
+
The third field of [[Effects#SetMeter|SetMeter]] 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.
+
 
+
Our tech is mostly finished.  When the [[Effects#EffectsGroup|effects group]] is placed into it’s proper position, the whole thing looks like this:
+
 
+
  <Tech>
+
      <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>
+
          <prereq>LEARN_THEORY_OF_DREK</prereq>
+
      </prerequisites>
+
      <effects>
+
        <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::FocusType>
+
                  <primary>1</primary>
+
                  <FocusType>FOCUS_RESEARCH</FocusType>
+
                </Condition::FocusType>
+
                <Condition::FocusType>
+
                  <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>
+
      </effects>
+
  </Tech>
+
 
+
As you’ve probably noticed, the scope condition is the longest and toughest part to write.
+
 
+
=Step 4: Composing the string table=
+
 
+
Not everyone speaks English.
+
 
+
I’ll give my fellow Americans time to recover from that statement.
+
 
+
...
+
 
+
...
+
 
+
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.
+
 
+
It can be pretty simple:
+
 
+
LEARN_DREK_TUTORIAL
+
Drek’s Effects Tutorial
+
LEARN_DREK_TUTORIAL_DESC
+
A marvelous, high tech tutorial that enlightens all who read it.\nEffect: +2 Max Science to all friendly worlds set to the Science Focus.
+
 
+
Notice the "\n", for a “newline.”  The text must appear all on one line, but adding a "\n" will insert a line break when you see the text in FreeOrion.  There’s other pieces of formatting you can use, see the [http://www.freeorion.org/forum/viewtopic.php?p=17335#17335 FAQ] for details.
+
 
+
That’s pretty much it.  Congrats if you’ve read this far.  I probably would have got bored round step #2.
+
 
+
=Appendix: Additional Examples=
+
 
+
Visit Geoff's house of horrors to view some examples:  [[XML_Description_Examples|XML Examples]]
+

Revision as of 17:37, 12 March 2016

Template:WIP

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

All FOCS files are plain text files, though some contain extended characters, especially the language files.
Template:FOCS Notepad Notice

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, or want to change it:

Start FreeOrion
select Options
select the tab Directories (next to last)
see Resource Files.

On Windows this is typically 'C:\Freeorion\default\'
Be aware if you change it, you should likely copy the contents of the original default directory to the new location.

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.
You can start with the file that suits you best, for this example we will use the english file.

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 were going to share this entry with others, create the same entries in each of the other stringtable files as well. Few people are fluent in all of these languages, so simply copy the same text into the same spot in each file. If you can provide a translated version, please do as it cuts down on work others would need to do.

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

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/buldings.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.

Troubleshooting

If the entry is in the game, but does not show the name or the description correctly, check the stringtable entry for your selected language.

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.
Either edit the config.xml file in your user directory or launch 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 you need further help, post a question in the forums.