Adding a New Faction

abc013 edited this page Aug 29, 2016 · 3 revisions
Clone this wiki locally

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 exsist 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.