HOW-TO : Converting a mission to Co-op.

Post here if you want to help developing something for FAF.

HOW-TO : Converting a mission to Co-op.

Postby Ze_PilOt » 16 Sep 2013, 12:09

First thing to know : missions are maps. Nothing more.
Missions are in your FA install folder/maps, and they start with X1CA_ for FA missions.

We need to alter a few files in it.
First thing is to duplicate that map.

- Duplicating the map
Let's take X1CA_001.
- Copy it in your user map folder.
- Rename the folder X1CA_Coop_001.
- Rename all files in it X1CA_001.* to X1CA_Coop_001.* (Use a batch renamer).
- In all the LUA files, replace
/maps/X1CA_001/X1CA_001
with
/maps/X1CA_Coop_001/X1CA_Coop_001

ie in scenario.lua :
Code: Select all
    map = '/maps/X1CA_Coop_001/X1CA_Coop_001.scmap',
    save = '/maps/X1CA_Coop_001/X1CA_Coop_001_save.lua',
    script = '/maps/X1CA_Coop_001/X1CA_Coop_001_script.lua',


in script.lua :
Code: Select all
local M1OrderAI = import('/maps/X1CA_COOP_001/X1CA_COOP_001_m1orderai.lua')
local M2OrderAI = import('/maps/X1CA_COOP_001/X1CA_COOP_001_m2orderai.lua')
local M2UEFAI = import('/maps/X1CA_COOP_001/X1CA_COOP_001_m2uefai.lua')
local M3OrderAI = import('/maps/X1CA_COOP_001/X1CA_COOP_001_m3orderai.lua')
local M4UEFAI = import('/maps/X1CA_COOP_001/X1CA_COOP_001_m4uefai.lua')
local M4SeraphimAI = import('/maps/X1CA_COOP_001/X1CA_COOP_001_m4seraphimai.lua')
local OpStrings = import('/maps/X1CA_COOP_001/X1CA_COOP_001_strings.lua')


You can do a search & replace.
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: HOW-TO : Converting a mission to Co-op.

Postby Ze_PilOt » 16 Sep 2013, 12:16

- Adding "spawn" points for players.

- In scenario.lua:
{ name = 'FFA', armies = {'Player','Seraphim','Order','UEF','Civilians'} },

These are all the armies, human and AIs, that are in the game.
By convention with the Coop lobby, you need to add the Coop players at the end.
In 001 :
{ name = 'FFA', armies = {'Player','Seraphim','Order','UEF','Civilians','Coop1','Coop2','Coop3'} },

That's all for scenario.lua

- in save.lua.
First, you need to edit the alliances. ie.
Code: Select all
        ['Player'] = 
        {
...
            Alliances = {
                ['Civilians'] = 'Ally',
               ['Player'] = 'Ally',
                ['Order'] = 'Enemy',
                ['Seraphim'] = 'Enemy',
                ['UEF'] = 'Ally',


To
Code: Select all
            Alliances = {
                ['Civilians'] = 'Ally',
   ['Coop1'] = 'Ally',
   ['Coop2'] = 'Ally',
   ['Coop3'] = 'Ally',
                ['Order'] = 'Enemy',
                ['Seraphim'] = 'Enemy',
                ['UEF'] = 'Ally',
            },


Do that for each alliance you see in the file.

Also, you need to duplicate the whole "['Player'] =" part, and rename it Coop1, Coop2, Coop3.
Be sure to alter the alliances correctly so each Coop player is allied with Player and the two other Coop.
I've attached a corrected _save.lua for mission 001.
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: HOW-TO : Converting a mission to Co-op.

Postby Ze_PilOt » 16 Sep 2013, 12:19

script.lua.

The biggest part.

Some mission has debug variable that allow you to skip dialogues or parts of the missions. ie for 001:
Code: Select all
# -----------
# Debug only!
# -----------
local SkipNIS1 = true

Will skip the intro.

First, edit the variables on top of the file by adding the coop players.
The Coop players are always the last ones :

Code: Select all
# -------
# Globals
# -------
ScenarioInfo.Player = 1
ScenarioInfo.Seraphim = 2
ScenarioInfo.Order = 3
ScenarioInfo.UEF = 4
ScenarioInfo.Civilians = 5
ScenarioInfo.Coop1 = 6
ScenarioInfo.Coop2 = 7
ScenarioInfo.Coop3 = 8

# ------
# Locals
# ------
local Player = ScenarioInfo.Player
local Coop1 = ScenarioInfo.Coop1
local Coop2 = ScenarioInfo.Coop2
local Coop3 = ScenarioInfo.Coop3
local Seraphim = ScenarioInfo.Seraphim
local Order = ScenarioInfo.Order
local UEF = ScenarioInfo.UEF
local Civilians = ScenarioInfo.Civilians


Also add a table with all human players :
Code: Select all
local Players = {ScenarioInfo.Player, ScenarioInfo.Coop1, ScenarioInfo.Coop2, ScenarioInfo.Coop3}


Also be sure that the coop players are affected the same way by map areas:

Code: Select all
    for i = 2, table.getn(ArmyBrains) do
        SetArmyShowScore(i, false)
        SetIgnorePlayableRect(i, true)
    end

to
Code: Select all
    # Hide all but the player army score
    for i = 2, table.getn(ArmyBrains) do
      if i < ScenarioInfo.Coop1 then
         SetArmyShowScore(i, false)
         SetIgnorePlayableRect(i, true)
      end
    end
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: HOW-TO : Converting a mission to Co-op.

Postby Ze_PilOt » 16 Sep 2013, 12:25

Settings the build restrictions

In the script file, you will have a lot of ScenarioFramework.AddRestriction and ScenarioFramework.RemoveRestriction commands.
We need to extend them to the coop players.

This is where the Players variable we've created earlier will be used :
Code: Select all
    # ------------------
    # Build Restrictions
    # ------------------
   local tblArmy = ListArmies()
   for _, player in Players do
      for iArmy, strArmy in pairs(tblArmy) do
         if iArmy == player then
            ScenarioFramework.AddRestriction(player, categories.xal0305) # Aeon Sniper Bot
            ScenarioFramework.AddRestriction(player, categories.xaa0202) # Aeon Mid Range fighter (Swift Wind)
            ScenarioFramework.AddRestriction(player, categories.xal0203) # Aeon Assault Tank (Blaze)
............


Some explanations:
Code: Select all
local tblArmy = ListArmies()

Will add all the current armies in the game into tblArmy.

Code: Select all
for _, player in Players do

We are iterating over the "Players" table (Player, Coop1, 2 and 3).

Code: Select all
for iArmy, strArmy in pairs(tblArmy) do
if iArmy == player then


We've added all the coop players, but maybe there is only one. That part is a sanity check : We are checking that the army is really in the game.
Code: Select all
ScenarioFramework.AddRestriction(player, categories.xal0305) # Aeon Sniper Bot

The original AddRestriction command, but we replace "Player" with "player", the current army (will be Player, Coop1,2 and/or 3).
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: HOW-TO : Converting a mission to Co-op.

Postby Ze_PilOt » 16 Sep 2013, 12:31

Settings the build unlocks

After a certain time, unlocks are given to the player. We need to give them to the coop players too!
Code: Select all
function M1TechReveal()
    #tech reveal dialogue, siege bots
    if(Faction == 'uef') then
        ScenarioFramework.Dialogue(OpStrings.X01_M01_070)           #xel0305 Percival
        ScenarioFramework.RemoveRestriction(Player, categories.xel0305)
    elseif(Faction == 'cybran') then
        ScenarioFramework.Dialogue(OpStrings.X01_M01_080)           #xrl0305 Bricks
        ScenarioFramework.RemoveRestriction(Player, categories.xrl0305)
    elseif(Faction == 'aeon') then
        ScenarioFramework.Dialogue(OpStrings.X01_M01_032)           #xal0203 Blaze assault tank
        ScenarioFramework.RemoveRestriction(Player, categories.xal0203)
    end
   
   # for coop players
   local tblArmy = ListArmies()
   for iArmy, strArmy in pairs(tblArmy) do
      if iArmy >= ScenarioInfo.Coop1 then    
         factionIdx = GetArmyBrain(strArmy):GetFactionIndex()
         if (factionIdx == 1) then
            ScenarioFramework.RemoveRestriction(iArmy, categories.xel0305)
         elseif(factionIdx == 2) then
            ScenarioFramework.RemoveRestriction(iArmy, categories.xal0203)
         else
            ScenarioFramework.RemoveRestriction(iArmy, categories.xrl0305)
         end
      end   
         
   end
end


Some explanations :

Code: Select all
    #tech reveal dialogue, siege bots
    if(Faction == 'uef') then
        ScenarioFramework.Dialogue(OpStrings.X01_M01_070)           #xel0305 Percival
        ScenarioFramework.RemoveRestriction(Player, categories.xel0305)
    elseif(Faction == 'cybran') then
        ScenarioFramework.Dialogue(OpStrings.X01_M01_080)           #xrl0305 Bricks
        ScenarioFramework.RemoveRestriction(Player, categories.xrl0305)
    elseif(Faction == 'aeon') then
        ScenarioFramework.Dialogue(OpStrings.X01_M01_032)           #xal0203 Blaze assault tank
        ScenarioFramework.RemoveRestriction(Player, categories.xal0203)
    end


This is the original unlock commands. It's not altered. The reason that we didn't use the Players table like previously is that we want the dialogue to only appears once, so the main player has to be threaten differently.

Code: Select all
   # for coop players
   local tblArmy = ListArmies()
   for iArmy, strArmy in pairs(tblArmy) do
      if iArmy >= ScenarioInfo.Coop1 then    



As previously, we are iterating over the army list. If the army is equal or above ScenarioInfo.Coop1, it means it's another human player (as they are all in the end of the list).

Code: Select all
         factionIdx = GetArmyBrain(strArmy):GetFactionIndex()


We need to get the current faction of the coop player.
Code: Select all
         if (factionIdx == 1) then
            ScenarioFramework.RemoveRestriction(iArmy, categories.xel0305)
         elseif(factionIdx == 2) then
            ScenarioFramework.RemoveRestriction(iArmy, categories.xal0203)
         else
            ScenarioFramework.RemoveRestriction(iArmy, categories.xrl0305)
         end

We are doing the unlock depending of the faction. We stop at 2, so the players can't be seraphim (it's not planned in the campaign).
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: HOW-TO : Converting a mission to Co-op.

Postby Ze_PilOt » 16 Sep 2013, 12:36

Make the coop players spawning

The coop players will spawn the same way as the first player.
Mission 01 is special : it spawn through a gate. This is probably the more complicate case.

In case of mission 01, the spawning is done in IntroNISPart2.
You can find where quite easily by searching "ScenarioInfo.PlayerCDR = ScenarioUtils.CreateArmyUnit('Player'

NO ALTERATION BELOW, JUST EXPLANATIONS

Code: Select all
    if(Faction == 'cybran') then
        ScenarioInfo.PlayerCDR = ScenarioUtils.CreateArmyUnit('Player', 'CybranPlayer')
    elseif(Faction == 'uef') then
        ScenarioInfo.PlayerCDR = ScenarioUtils.CreateArmyUnit('Player', 'UEFPlayer')
    elseif(Faction == 'aeon') then
        ScenarioInfo.PlayerCDR = ScenarioUtils.CreateArmyUnit('Player', 'AeonPlayer')
    end

This create the ACU of the player.
Then some code to give him the current base, settings patrols, ...
Code: Select all
    local cmd = IssueMove({ScenarioInfo.PlayerCDR}, ScenarioUtils.MarkerToPosition('CDRWarp'))


This order the ACU of the player to move to a map marker (CDRWarp)

Code: Select all
    ScenarioFramework.FakeGateInUnit(ScenarioInfo.PlayerCDR)


This is purely cosmetic : It does a fake gating in effect around the ACU.

Really make the coop players spawning

So, for each coop player, we need to:
- Create a ACU
- Move them to the marker
- Create a effect for gating in.
Code: Select all
    ScenarioInfo.PlayerCDR:SetCustomName(LOC '{i CDR_Player}')

   ScenarioInfo.CoopCDR = {}
   local tblArmy = ListArmies()
   coop = 1
   for iArmy, strArmy in pairs(tblArmy) do
      if iArmy >= ScenarioInfo.Coop1 then
         factionIdx = GetArmyBrain(strArmy):GetFactionIndex()
         if(factionIdx == 1) then
            ScenarioInfo.CoopCDR[coop] = ScenarioUtils.CreateArmyUnit(strArmy, 'UEFPlayer')
         elseif(factionIdx == 2) then
            ScenarioInfo.CoopCDR[coop] = ScenarioUtils.CreateArmyUnit(strArmy, 'AeonPlayer')
         else
            ScenarioInfo.CoopCDR[coop] = ScenarioUtils.CreateArmyUnit(strArmy, 'CybranPlayer')
         end
         IssueMove({ScenarioInfo.CoopCDR[coop]}, ScenarioUtils.MarkerToPosition('CDRWarp'))
         ScenarioFramework.FakeGateInUnit(ScenarioInfo.CoopCDR[coop])         
         coop = coop + 1
         WaitSeconds(2)
      end
   end




Code: Select all
    ScenarioInfo.PlayerCDR:SetCustomName(LOC '{i CDR_Player}')
   ScenarioInfo.CoopCDR = {}


We are preparing a table in ScenarioInfo that will contains all Coop ACUs.


Code: Select all
   local tblArmy = ListArmies()
   coop = 1


Same as before, we will iterate over all the armies.
We also set a variable that will increase for all coop players added.

Code: Select all
for iArmy, strArmy in pairs(tblArmy) do
      if iArmy >= ScenarioInfo.Coop1 then


Same as before, if the army is equal or above ScenarioInfo.Coop1, it's a coop player.

Code: Select all
                                          factionIdx = GetArmyBrain(strArmy):GetFactionIndex()
         if(factionIdx == 1) then
            ScenarioInfo.CoopCDR[coop] = ScenarioUtils.CreateArmyUnit(strArmy, 'UEFPlayer')
         elseif(factionIdx == 2) then
            ScenarioInfo.CoopCDR[coop] = ScenarioUtils.CreateArmyUnit(strArmy, 'AeonPlayer')
         else
            ScenarioInfo.CoopCDR[coop] = ScenarioUtils.CreateArmyUnit(strArmy, 'CybranPlayer')
         end


As with the unlock, we take the faction of the army and spawn the appropriate ACU type (no further than Cybran - no seraphim or nomads).
We put that in the ScenarioInfo.CoopCDR table, at the position of the coop variable.

Code: Select all
         IssueMove({ScenarioInfo.CoopCDR[coop]}, ScenarioUtils.MarkerToPosition('CDRWarp'))



We ask that ACU to move to the spawn point.

Code: Select all
         ScenarioFramework.FakeGateInUnit(ScenarioInfo.CoopCDR[coop])         
         coop = coop + 1

We are adding the fake effect, and we increase the coop variable.

Code: Select all
         WaitSeconds(2)

In order to not have all the ACU to spawn at the same time, we are asking to wait 2 seconds before spawning the next one.
The gate won't be destroyed until the last one spawn, so we are good visually.
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: HOW-TO : Converting a mission to Co-op.

Postby Ze_PilOt » 16 Sep 2013, 12:44

This is done! (at least for mission 001).

Some scripts alterations can or must be make depending of the scenario, if you want to coop players to be a cause of defeat,....
ie
Code: Select all
ScenarioFramework.PauseUnitDeath(ScenarioInfo.PlayerCDR)
ScenarioFramework.CreateUnitDeathTrigger(PlayerDeath, ScenarioInfo.PlayerCDR)

You can add all the CoopCDR previously to these triggers.

You will have to test the map/read the script to be sure.

The scripts events will only react to the first player, it can't be done otherwise without heavily modifying the whole script. (and redo some voice-over).

This looks complicated, but it's easier that it looks.
You can do a restart of the map when testing script changes. No need to reload the whole game.
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: HOW-TO : Converting a mission to Co-op.

Postby Myxir » 16 Sep 2013, 22:27

i'm not really sure how i can properly test if the coop map works

it's not showing up in the map list or the campaign list until i change
type = 'campaign',
from the [...]scenario.lua to
type = 'skirmish',
but then it won't spawn anything at all

if you have a way to test it, please tell me or check it out yourself :)
Last edited by Myxir on 17 Sep 2013, 21:29, edited 1 time in total.
Unhappy with balance http://i.imgur.com/q5G2BlM.png
User avatar
Myxir
Evaluator
 
Posts: 791
Joined: 09 Apr 2012, 14:01
Has liked: 94 times
Been liked: 306 times
FAF User Name: Washy (irc)

Re: HOW-TO : Converting a mission to Co-op.

Postby Ze_PilOt » 17 Sep 2013, 08:49

Great, You are going faster than me :)

You will have to wait for the new lobby version (today or tomorrow).
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: HOW-TO : Converting a mission to Co-op.

Postby Typo91 » 18 Sep 2013, 05:53

Any Experimental causes desync. Even ones the AI team gets.

Till then, it works great.

Also how do we set it to the "hard" version of the mission ?
User avatar
Typo91
Avatar-of-War
 
Posts: 95
Joined: 05 Jul 2012, 18:56
Has liked: 0 time
Been liked: 8 times
FAF User Name: Typo91

Next

Return to Contributors

Who is online

Users browsing this forum: No registered users and 1 guest