Hypoxic125/Sandbox – User

From Bohemia Interactive Community
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
== Creating A Multiplayer Campaign ==
== Creating A Multiplayer Campaign In ArmA 3 ==


A multiplayer campaign is a series of interconnected missions that follow a sequential order, creating a storyline that groups of players can enjoy together.
A multiplayer campaign is a series of interconnected missions that follow a sequential order, creating a storyline that groups of players can enjoy together.
Line 21: Line 21:
  <span style="color: blue;">'''myModName'''</span>
  <span style="color: blue;">'''myModName'''</span>
  |--<span style="color: red;">addons</span>
  |--<span style="color: red;">addons</span>
     |--<span style="color: red;">myCampaignName</span>
     |--<span style="color: red;">myCampaignAddon</span>
       |--<span style="color: green;">data</span>
       |--<span style="color: green;">data</span>
       |--<span style="color: green;">functions</span>
       |--<span style="color: green;">functions</span>
Line 38: Line 38:


== Campaign Description.ext ==
== Campaign Description.ext ==
Location: "\myModName\addons\myCampaignAddon\campaign\description.ext"


The campaign description file will dictate how the missions are structured within the campaign menus. Unlike a single-player campaign, we are going to be ignoring the mission flow aspect of the campaign description file so that the multiplayer campaign menu functions correctly.
The campaign description file will dictate how the missions are structured within the campaign menus. Unlike a single-player campaign, we are going to be ignoring the mission flow aspect of the campaign description file so that the multiplayer campaign menu functions correctly.
Line 48: Line 50:
// Setting up no endings, cutscenes, or rewards (stuff for single-player campaigns).
// Setting up no endings, cutscenes, or rewards (stuff for single-player campaigns).


class NoEndings                                     // For use in chapter class and class MissionDefault.
class NoEndings                     // For use in chapter class and class MissionDefault.
{
{
     endDefault = "";
     endDefault = "";
};
};


class MissionDefault : NoEndings                   // For use in individual mission classes.
class MissionDefault : NoEndings   // For use in individual mission classes.
{
{
     lives = -1;                                     // Not important with/without "Tickets" respawn template.
     lives = -1;                     // Not important with/without "Tickets" respawn template.
     noAward = 1;
     noAward = 1;
     cutscene = "";
     cutscene = "";
Line 64: Line 66:
-------------------------------------------------- */
-------------------------------------------------- */


class Campaign                                     // Contained inside CfgMissions - Holds other campaign classes such as "Apex", "Bootcamp", "EastWind".
class Campaign                                 // Contained inside CfgMissions - Holds other campaign classes such as "Apex", "Bootcamp", "EastWind".
{
{
     firstBattle = "Missions";                       // This will point to class Missions below which contains no information on purpose
     firstBattle = "Missions";                   // This will point to class Missions below which contains no information on purpose
                                                    // so that the mp campaign menu will load all missions.
                                                // so that the mp campaign menu will load all missions.
                                                    // If info is given, no MPCampaignDisplay will be created.
                                                // If info is given, no MPCampaignDisplay will be created.
     name = "$STR_CAMPAIGN_TITLE";
     name = "$STR_CAMPAIGN_TITLE";
     briefingName = "$STR_CAMPAIGN_TITLE";
     briefingName = "$STR_CAMPAIGN_TITLE";
Line 76: Line 78:
     disableMP = 0;
     disableMP = 0;


     class myCampaign : NoEndings                   // Chapter class - Typically only use one chapter when dealing with MP Campaigns.
     class MyCampaign : NoEndings               // Chapter class - Typically only use one chapter when dealing with MP Campaigns.
     {
     {
         firstMission = "myMission01";
         firstMission = "myMission01";
Line 83: Line 85:
         end1 = "";
         end1 = "";


         class myMission01 : MissionDefault         // Mission class - Inherits default settings from class MissionDefault above.
         class myMission01 : MissionDefault     // Mission class - Inherits default settings from class MissionDefault above.
         {
         {
             end1 = "myMission02";                   // Default Ending - "end1" call BIS_fnc_endMission will use this mission as next mission.
             end1 = "myMission02";               // Default Ending - "end1" call BIS_fnc_endMission will use this mission as next mission.
             myCustomEnd = "myMission01";           // Custom Ending - Defined in mission's class CfgDebriefing - Can be whatever you want.
             myCustomEnd = "myMission01";       // Custom Ending - Defined in mission's class CfgDebriefing - Can be whatever you want.
             lost = "myMission01";                   // You can send the lobby back to current mission on loss using this. Can also be custom.
             lost = "myMission01";               // You can send the lobby back to current mission on loss using this. Can also be custom.
             template = "myMission01.worldName";
             template = "myMission01.worldName";
         };
         };


         class myMission02 : MissionDefault
         class MyMission02 : MissionDefault
         {
         {
             end1 = "myMission03";
             end1 = "MyMission03";
             lost = "myMission02";
             lost = "MyMission02";
             template = "myMission02.worldName";
             template = "MyMission02.worldName";
         };
         };


         class myMission03 : MissionDefault
         class MyMission03 : MissionDefault
         {
         {
             end1 = "";
             end1 = "";
             lost = "myMission03";
             lost = "MyMission03";
             template = "myMission03.worldName";
             template = "MyMission03.worldName";
         };
         };
     };
     };


     class Missions                                 // This is essentially a class with empty values. Used to invoke MPCampaignDisplay - See firstBattle above.
     class Missions                     // This is essentially a class with empty values. Used to invoke MPCampaignDisplay - See firstBattle above.
     {
     {
         name = "$STR_CAMPAIGN_TITLE";
         name = "$STR_CAMPAIGN_TITLE";
Line 121: Line 123:
};
};
</syntaxhighlight>
</syntaxhighlight>
{{Feature|important|An error in Description.ext WILL crash your game!}}
== Config.cpp ==
Config.cpp will contain all of our top level classes we want our mod to modify in-game. In our campaign's case, this will mainly be CfgPatches and CfgMissions
'''CfgPatches'''
<syntaxhighlight lang="cpp">
class CfgPatches
{
    class MyCampaign
    {
        name = "MyCampaign - A Campaign That Campaigns";
        author = "Hypoxic";
        url = "https://arepublixchickentendersubsonsale.com/";
        requiredVersion = 2.10;
        requiredAddons[] = { // Insert addons that your mod/campaign requires
            "A3_Functions_F"
        };
        units[] = {};
        weapons[] = {};
    };
};
</syntaxhighlight>
If your campaign addon contains units/weapons/etc, add them to units[] and weapons[], just like you would with a normal mod.
'''CfgMissions'''
<syntaxhighlight lang="cpp">
class CfgMissions
{
    class Campaigns
    {
        class MyCampaign
        {
            directory = "\myModName\myCampaignAddon\campaign";
        };
    };
    class MPMissions
    {
        class MyCampaign    // Campaign class from above
        {
            briefingName = "$STR_CAMPAIGN_TITLE";
            class MyMission01
            {
                briefingName = "$STR_M01_MISSION_TITLE";
                directory = "\myModName\myCampaignAddon\campaign\missions\myMission01.worldName";
            };
            class MyMission02
            {
                briefingName = "$STR_M02_MISSION_TITLE";
                directory = "\myModName\myCampaignAddon\campaign\missions\myMission02.worldName";
            };
            class MyMission03
            {
                briefingName = "$STR_M03_MISSION_TITLE";
                directory = "\myModName\myCampaignAddon\campaign\missions\myMission03.worldName";
            };
        };
    };
};
</syntaxhighlight>
== The MPCampaign Display ==
[[File:mpcampaigndisplay example filled.png|frame|right|A filled out MPCampaignDisplay]]
==== Defining Values ====
# '''Campaign Name''' - Defined In Either:
## CfgMissions.MPMissions.MyCampaign.briefingName
## Campaign description.ext: Campaign.briefingName
# '''Mission Name''' - Defined In Either:
## CfgMissions.MPMissions.MyMission01.briefingName
## Mission description.ext: briefingName
# '''See #2'''
# '''Author''' - Defined In:
## Campaign description.ext: Campaign.author
# '''Mission Overview Picture''' - Defined In:
## Mission description.ext: overviewPicture
# '''Mission Overview Text''' - Defined In:
## Mission description.ext: overviewText

Revision as of 02:01, 9 June 2023

Creating A Multiplayer Campaign In ArmA 3

A multiplayer campaign is a series of interconnected missions that follow a sequential order, creating a storyline that groups of players can enjoy together.

Key things that a multiplayer campaign will include:

  • Interconnected sequential missions
  • Centralized location of common mission files to save on storage space
  • Utilizes MPCampaignDisplay
  • Missions can be selected in the hosted server mission selection menu

Creating the Missions

If new to creating missions, it is advised that you ignore concerns about disk space and make each mission independent of the campaign mod. When you get more comfortable with how the file structure works, and have more confidence in your code, you can then move on to centralizing common files. Debugging missions within the mod structure is much more annoying, especially if your code is more prone to bugs/errors.

Be sure you structure your missions with multiplayer locality in mind from the start. It is much more time-consuming to convert a single-player mission into a multiplayer mission.

File Structure

Now that you have your missions created, we can move on to the mod's file structure.

myModName
|--addons
   |--myCampaignAddon
      |--data
      |--functions
      |--campaign
      |  |--missions
      |  |  |--myMission01.worldName
      |  |  |--myMission02.worldName
      |  |  |--myMission03.worldName
      |  |--description.ext
      |--$PBOPREFIX$
      |--config.cpp

Red highlights indicate required files/folders

Green highlights indicate optional organization files/folders for shared campaign files

Campaign Description.ext

Location: "\myModName\addons\myCampaignAddon\campaign\description.ext"

The campaign description file will dictate how the missions are structured within the campaign menus. Unlike a single-player campaign, we are going to be ignoring the mission flow aspect of the campaign description file so that the multiplayer campaign menu functions correctly.

/* --------------------------------------------------
    Defining Templates for Inheriting Later
-------------------------------------------------- */

// Setting up no endings, cutscenes, or rewards (stuff for single-player campaigns).

class NoEndings                     // For use in chapter class and class MissionDefault.
{
    endDefault = "";
};

class MissionDefault : NoEndings    // For use in individual mission classes.
{
    lives = -1;                     // Not important with/without "Tickets" respawn template.
    noAward = 1;
    cutscene = "";
};

/* --------------------------------------------------
    Actual Campaign Class
-------------------------------------------------- */

class Campaign                                  // Contained inside CfgMissions - Holds other campaign classes such as "Apex", "Bootcamp", "EastWind".
{
    firstBattle = "Missions";                   // This will point to class Missions below which contains no information on purpose
                                                // so that the mp campaign menu will load all missions.
                                                // If info is given, no MPCampaignDisplay will be created.
    name = "$STR_CAMPAIGN_TITLE";
    briefingName = "$STR_CAMPAIGN_TITLE";
    author = "Hypoxic";
    overviewPicture = "myOverViewPicture.jpg";
    overviewText = "$STR_CAMPAIGN_DESCRIPTION";
    disableMP = 0;

    class MyCampaign : NoEndings                // Chapter class - Typically only use one chapter when dealing with MP Campaigns.
    {
        firstMission = "myMission01";
        name = "$STR_CAMPAIGN_TITLE";
        cutscene = "";
        end1 = "";

        class myMission01 : MissionDefault      // Mission class - Inherits default settings from class MissionDefault above.
        {
            end1 = "myMission02";               // Default Ending - "end1" call BIS_fnc_endMission will use this mission as next mission.
            myCustomEnd = "myMission01";        // Custom Ending - Defined in mission's class CfgDebriefing - Can be whatever you want.
            lost = "myMission01";               // You can send the lobby back to current mission on loss using this. Can also be custom.
            template = "myMission01.worldName";
        };

        class MyMission02 : MissionDefault
        {
            end1 = "MyMission03";
            lost = "MyMission02";
            template = "MyMission02.worldName";
        };

        class MyMission03 : MissionDefault
        {
            end1 = "";
            lost = "MyMission03";
            template = "MyMission03.worldName";
        };
    };

    class Missions                      // This is essentially a class with empty values. Used to invoke MPCampaignDisplay - See firstBattle above.
    {
        name = "$STR_CAMPAIGN_TITLE";
        cutscene = "";
        firstMission = "";
        end1 = "";
        end2 = "";
        end3 = "";
        end4 = "";
        end5 = "";
        end6 = "";
        lost = "";
    };
};
An error in Description.ext WILL crash your game!

Config.cpp

Config.cpp will contain all of our top level classes we want our mod to modify in-game. In our campaign's case, this will mainly be CfgPatches and CfgMissions


CfgPatches

class CfgPatches
{
    class MyCampaign
    {
        name = "MyCampaign - A Campaign That Campaigns";
        author = "Hypoxic";
        url = "https://arepublixchickentendersubsonsale.com/";

        requiredVersion = 2.10;
        requiredAddons[] = {		// Insert addons that your mod/campaign requires
            "A3_Functions_F"
        };
        units[] = {};
        weapons[] = {};
    };
};

If your campaign addon contains units/weapons/etc, add them to units[] and weapons[], just like you would with a normal mod.


CfgMissions

class CfgMissions
{
    class Campaigns
    {
        class MyCampaign
        {
            directory = "\myModName\myCampaignAddon\campaign";
        };
    };
    class MPMissions
    {
        class MyCampaign    // Campaign class from above
        {
            briefingName = "$STR_CAMPAIGN_TITLE";

            class MyMission01
            {
                briefingName = "$STR_M01_MISSION_TITLE";
                directory = "\myModName\myCampaignAddon\campaign\missions\myMission01.worldName";
            };

            class MyMission02
            {
                briefingName = "$STR_M02_MISSION_TITLE";
                directory = "\myModName\myCampaignAddon\campaign\missions\myMission02.worldName";
            };

            class MyMission03
            {
                briefingName = "$STR_M03_MISSION_TITLE";
                directory = "\myModName\myCampaignAddon\campaign\missions\myMission03.worldName";
            };
        };
    };
};

The MPCampaign Display

File:mpcampaigndisplay example filled.png
A filled out MPCampaignDisplay

Defining Values

  1. Campaign Name - Defined In Either:
    1. CfgMissions.MPMissions.MyCampaign.briefingName
    2. Campaign description.ext: Campaign.briefingName
  2. Mission Name - Defined In Either:
    1. CfgMissions.MPMissions.MyMission01.briefingName
    2. Mission description.ext: briefingName
  3. See #2
  4. Author - Defined In:
    1. Campaign description.ext: Campaign.author
  5. Mission Overview Picture - Defined In:
    1. Mission description.ext: overviewPicture
  6. Mission Overview Text - Defined In:
    1. Mission description.ext: overviewText