Adding a New Faction - OpenRA/OpenRA GitHub Wiki
This is a step-by-step guide on how to add a new faction to the RA mod (release 20160508).
Break out your favorite sophisticated text file editor (Notepad++, ConText, Editra, etc.), because this is all work with ".yaml" files. Proper indentation is very important for work with these ".yaml" files.
This procedure should work universally for all the mods, but for this example's sake, we will use the Red Alert mod (or rather, a copy of it). I always recommend making a "sandbox" copy of a mod so if anything goes wrong, you still have the originals right there and handy. It also makes a great testing environment.
The files we need to edit are:
- world.yaml (located inside the mod's /rules/ directory)
- chrome.yaml (located in the mod's main directory)
- metrics.yaml (located in the mod's main directory)
- voices.yaml (located in the mod's /audio/ directory)
- structures.yaml (located in the mod's /rules/ directory)
world.yaml
First, you need to edit your world.yaml file, located in the /rules/ directory, which contains stuff about your mod's world; such as the factions the game will render.
Look for this code snippet:
Faction@0:
Name: Allies
InternalName: allies
Side: Allies
Selectable: False
Faction@1:
Name: England
InternalName: england
Side: Allies
Description: England: Espionage\nSpecial Unit: British Spy\nSpecial Unit: Phase Transport
Copy the Faction@1 block (all three lines), and paste it under the Ukraine-faction. Replace the @1 with a @7.
(You can place it all in between or even above Faction@0:
as well. The rule is that they stay together in a group. The @ symbol is also just a way to label a trait that is repeatedly used, such as Faction: here, so you can name them whatever you like, like @allies or @soviet. Also note that when creating a map, it will use the first listed faction as the defaults for "Neutral" and "Creeps" groups in a map.yaml file, so I usually also make a "Non-Playable Faction" definition; but this is not important for this tutorial.)
Replace the Name: trait with the faction's name. This should be the name that will show up in-game (for example "Spain"). In programming terms, this is just a string; a block of text to output.
Replace the InternalName:
trait with a name too. This one is special though, because this is what the game engine uses to read across your mod as the faction you define, so to make it easier for you, name it something short, sweet, and simple (Our name "spain" is short enough, but for countrys like "People's Republic of China").
The final code should look like this:
Faction@7:
Name: Spain
InternalName: spain
Side: Allies
Description: Spain: Tradition\nSpecial Unit: Rodeo Man\nSpecial Ability: Angry Ox
So all of that helps "define" our faction. Now the game knows it exists by definition. But you will not get much else, because there is some more to do to make it truly playable.
For our next step, we need to fix the starting units for our new faction. Search for this code now:
MPStartUnits@mcvonly:
Class: none
ClassName: MCV Only
Factions: allies, england, france, germany, soviet, russia, ukraine
BaseActor: mcv
MPStartUnits@lightallies:
Class: light
ClassName: Light Support
Factions: allies, england, france, germany
BaseActor: mcv
SupportActors: e1,e1,e1,e3,e3,jeep,1tnk
InnerSupportRadius: 3
OuterSupportRadius: 5
Add your faction in Factions:
below MPStartUnits@mcvonly:
, using your faction's InternalName
label you gave it (for us: spain
).
Now if you clone allies or soviet, copy and paste the MPStartUnit@light(soviet/allies) and heavy(soviet/allies). Replace the @ name with your faction's name. In this example we would write @lightspain. Replace the Factions:
with our faction's name (again, spain).
The BaseActor is our main unit, the MCV. The Support Actors are the support units, like the spare soldiers/tanks you get. In the light starting unit class we start with 3 rifle infantry (e1), 2 rocket infantry (e3), one ranger (jeep), and a light tank (1tnk). These codes can be found under the /rules/ directory, in the infantry.yaml, vehicles.yaml, ships.yaml and aircraft.yaml files to get the unit codes. When you start designing your own units, you can throw your definitions here for your team to start with.
The edited code should look like this now:
MPStartUnits@mcvonly:
Class: none
ClassName: MCV Only
Factions: allies, england, france, germany, soviet, russia, ukraine, spain
BaseActor: mcv
MPStartUnits@lightspain:
Class: light
Races: spain
BaseActor: mcv
SupportActors: e1,e1,e1,e3,e3,jeep,1tnk
InnerSupportRadius: 3
OuterSupportRadius: 5
MPStartUnits@heavyspain:
Class: heavy
Races: spain
BaseActor: mcv
SupportActors: e1,e1,e1,e3,e3,jeep,1tnk,2tnk,2tnk,2tnk
InnerSupportRadius: 3
OuterSupportRadius: 5
Naturally, you want to keep the Allies/Soviet definitions. Do not remove them. I just took them out from this example to cut the size of this tutorial down.
You also do not want to make a new "mcvonly" definition. Just throw in your faction's InternalName
. And if you make another faction, throw that one's faction's InternalName
in there too. You only need one mcvonly definition here.
What have we accomplished?
- Defining the faction's existence by making a name and faction.
- Made the starting units accessible for the faction.
We're done with the world.yaml file now. Save it and close.
(Optionally, you can take all those snippets and put them in a separate section of the world.yaml file so it's easier to look up and edit instead of being mixed in the clutter of the other world.yaml definitions.)
chrome.yaml
At first, if you don't want to use an own look for your faction, go into the metrics.yaml:
FactionSuffix-allies: allies
FactionSuffix-england: allies
FactionSuffix-france: allies
FactionSuffix-germany: allies
FactionSuffix-soviet: soviet
FactionSuffix-russia: soviet
FactionSuffix-ukraine: soviet
Add your Faction below this list:
FactionSuffix-spain: allies
Now your faction uses the allied look.
If you want to add your own look, go into the chrome.yaml file, located in the main directory of the mod. This is the file that maintains your User Interface. Without this code the game will crash.
Start by copying/pasting this code:
sidebar-allies: chrome.png
background-top: 0,167,238,290
background-iconrow: 0,457,238,47
background-bottom: 0,504,238,8
background-supportoverlay: 184,118,64,48
What this snippet does is it goes through the material in the /uibits/ directory, and makes cookie-cut rectangles of those graphics files, using the coordinates/dimensions written for the parts.
(The four numbers are written as x,y,w,h; where x and y are the top-left coordinate of your rectangle, and w and h are your width and height sizes of the rectangle you are using to cut the piece out of the graphic. For example, to extract the digit number 9: from chrome-allies.png, the rectangle's top-left coordinate is at (149,0), and the rectangle is 13 pixels wide and 17 pixels tall.)
Replace anything that says "allies" with your faction's InternalName
(here "spain").
(You can make your own UI interfaces. Use your favorite image editor that supports transparency, such as Photoshop or GIMP, to make your own custom UI. Then you can point your faction's chrome definitions to the new file.)
The next part to edit in this file is this part of the code:
sidebar-button-allies: chrome.png
background: 59,31,22,22
border-r: 81,31,3,22
border-l: 56,31,3,22
border-b: 59,53,22,3
border-t: 59,28,22,3
corner-tl: 56,28,3,3
corner-tr: 81,28,3,3
corner-bl: 56,53,3,3
corner-br: 81,53,3,3
sidebar-button-allies-hover: chrome.png
background: 59,3,22,22
border-r: 81,3,3,22
border-l: 56,3,3,22
border-b: 59,25,22,3
border-t: 59,0,22,3
corner-tl: 56,0,3,3
corner-tr: 81,0,3,3
corner-bl: 56,25,3,3
corner-br: 81,25,3,3
sidebar-button-allies-pressed: chrome.png
background: 59,31,22,22
border-r: 81,31,3,22
border-l: 56,31,3,22
border-b: 59,53,22,3
border-t: 59,28,22,3
corner-tl: 56,28,3,3
corner-tr: 81,28,3,3
corner-bl: 56,53,3,3
corner-br: 81,53,3,3
sidebar-button-allies-highlighted: chrome.png
background: 87,31,22,22
border-r: 109,31,3,22
border-l: 84,31,3,22
border-b: 87,53,22,3
border-t: 87,28,22,3
corner-tl: 84,28,3,3
corner-tr: 109,28,3,3
corner-bl: 84,53,3,3
corner-br: 109,53,3,3
sidebar-button-allies-highlighted-hover: chrome.png
background: 87,3,22,22
border-r: 109,3,3,22
border-l: 84,3,3,22
border-b: 87,25,22,3
border-t: 87,0,22,3
corner-tl: 84,0,3,3
corner-tr: 109,0,3,3
corner-bl: 84,25,3,3
corner-br: 109,25,3,3
sidebar-button-allies-highlighted-pressed: chrome.png
background: 87,31,22,22
border-r: 109,31,3,22
border-l: 84,31,3,22
border-b: 87,53,22,3
border-t: 87,28,22,3
corner-tl: 84,28,3,3
corner-tr: 109,28,3,3
corner-bl: 84,53,3,3
corner-br: 109,53,3,3
sidebar-button-allies-disabled: chrome.png
background: 171,3,22,22
border-r: 193,3,3,22
border-l: 168,3,3,22
border-b: 171,25,22,3
border-t: 171,0,22,3
corner-tl: 168,0,3,3
corner-tr: 193,0,3,3
corner-bl: 168,25,3,3
corner-br: 193,25,3,3
sidebar-button-allies-highlighted-disabled: chrome.png
background: 171,3,22,22
border-r: 193,3,3,22
border-l: 168,3,3,22
border-b: 171,25,22,3
border-t: 171,0,22,3
corner-tl: 168,0,3,3
corner-tr: 193,0,3,3
corner-bl: 168,25,3,3
corner-br: 193,25,3,3
These are the buttons that display the things you build in the game, such as units or structures. The three sections note what state the tab is in (ready, normal, selected), and of course, the cookie-cutter formula to pick specifically which part of the graphic represents which tabs and tab states.
- button is for the tabs in their unselected, unbuilt state.
- button-highlighted is for when you select a tab and look through the tab's menu of things to build.
- button-disabled is when the button is disabled.
You can make your own tab images and cookie-cuts. But just to keep it simple, we will use the allies one for now. We are almost done here. The last bit of code to change is the flags to represent your faction in the game.
Our Spain flag does already exist in buttons.png but is unused:
flags: buttons.png
soviet: 0,112,30,15
allies: 30,112,30,15
Random: 60,112,30,15
RandomAllies: 30,172,30,15
RandomSoviet: 0,172,30,15
spectator: 60,112,30,15
russia: 0,127,30,15
ukraine: 30,127,30,15
england: 60,127,30,15
germany: 0,142,30,15
spain: 30,142,30,15
france: 60,142,30,15
turkey: 0,157,30,15
greece: 30,157,30,15
You can use your program of choice to add a flag to the buttons.png, and then add it to the code, using the x,y,w,h formula to cut out the flag you want. Make sure they're all the same size of 30,15; unless you know how to edit the entire widget interface in the game's lobby system to accommodate larger flag sizes.
(Alternatively, and my recommendation, you can make your own flags.png file and point the trait to that file instead, to keep it separate from the button graphics. It will be great for when you want to have a lot of factions. Some games have had as much as 18 teams, for example).
What have we accomplished?
- Making the UI (Interface) for our faction.
Save the chrome.yaml file and close it.
Voices.yaml
The next of the files we need to edit is the voices.yaml file, located in the audio folder. This is the file that controls your units' voices.
The code we want is right on the top of the file. It looks like this:
GenericVoice:
Variants:
allies: .v01,.v03
england: .v01,.v03
france: .v01,.v03
germany: .v01,.v03
soviet: .r01,.r03
russia: .r01,.r03
ukraine: .r01,.r03
Voices:
Select: await1,ready,report1,yessir1
Action: ackno,affirm1,noprob,overout,ritaway,roger,ugotit
Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8
Burned: dedman10
Zapped: dedman6
DisableVariants: Die, Burned, Zapped
VehicleVoice:
Variants:
allies: .v00,.v02
england: .v00,.v02
france: .v00,.v02
germany: .v00,.v02
soviet: .r00,.r02
russia: .r00,.r02
ukraine: .r00,.r02
Voices:
Select: vehic1,yessir1,report1,await1
Action: ackno,affirm1
As you can probably guess, GenericVoice:
is used for infantry units, and VehicleVoice:
is used for the vehicles. Truth is, these names aren't engine-critical. You can make your own trait names; as long as you remember to assign your units that use the voice definition the very name you give the trait.
Variants: define the 'extension' of the filename that the faction will use. For example, if I made my own collection of sound files and I made them end in .allies.wav or .soviet.wav, and assigned those to their race, now when I play the race, it will only use sound files that have that assigned extension. (Do be careful though, because you have to match the same amount of files for each team using this definition, otherwise it will render a non-existent sound and go silent. To remedy this, just define another voice set that the faction will specifically use.)
Voices: tell the system which file names to play at random, depending on the action. Select: plays when you choose the unit, Action: plays when you move the unit or when the unit attacks. Die: plays when the unit dies. There is also "Burned" and "Zapped" for when the unit gets burned up in flames or zapped with an electric shock.
Altogether, say you are telling a Soviet tank to move (Action:
). It will look for any sound file called "ackno" or "affirm1", ending in either .r00 or .r02 (ie: ackno.r00).
So, choose which voice set you want your faction to sound like. Copy-paste the piece you want, and use your faction's race name in its place.
The code should look like this now:
GenericVoice:
Variants:
allies: .v01,.v03
england: .v01,.v03
france: .v01,.v03
germany: .v01,.v03
spain: .v01,.v03
soviet: .r01,.r03
russia: .r01,.r03
ukraine: .r01,.r03
Voices:
Select: await1,ready,report1,yessir1
Action: ackno,affirm1,noprob,overout,ritaway,roger,ugotit
Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8
Burned: dedman10
Zapped: dedman6
DisableVariants: Die, Burned, Zapped
VehicleVoice:
Variants:
allies: .v00,.v02
england: .v00,.v02
france: .v00,.v02
germany: .v00,.v02
spain: .v00,.v02
soviet: .r00,.r02
russia: .r00,.r02
ukraine: .r00,.r02
Voices:
Select: vehic1,yessir1,report1,await1
Action: ackno,affirm1
What have we accomplished?
- The faction's units can now speak.
structures.yaml
Now that we have our faction exist, have an interface, and a set of voices, it now needs its arsenal.
Go into the structures.yaml file, located in the /rules/ directory, and look for this snippet:
FACT:
Inherits: ^Building
Building:
Footprint: xxx xxx xxx
Dimensions: 3,3
Buildable:
Queue: Building
BuildPaletteOrder: 1000
Prerequisites: ~disabled
ProvidesPrerequisite@allies:
Factions: allies, england, france, germany
Prerequisite: structures.allies
ProvidesPrerequisite@alliesvanilla:
Factions: allies
Prerequisite: structures.alliesvanilla
ProvidesPrerequisite@england:
Factions: england
Prerequisite: structures.england
ProvidesPrerequisite@france:
Factions: france
Prerequisite: structures.france
ProvidesPrerequisite@germany:
Factions: germany
Prerequisite: structures.germany
Make a copy-paste of any of the "ProvidesCustomPrerequisite" blocks you see here, replace the @ label for your faction, and insert your faction's name where it says Factions:
. Depending on which faction you're cloning, just keep the Prerequisite:
trait, unless you're designing your own set of faction assets; in which case you start writing new definitions and assigning the prerequisites for your faction to them.
What have we accomplished?
- The faction now shares the tech tree of the faction you cloned from, and thus can build units/structures.
Conclusion
The game should now be able to run, and you can choose the faction you made.