Campaign making tutorial

In this forum you will find and post information regarding the modding of Star Wars Battlefront 2. DO NOT POST MOD IDEAS/REQUESTS.

Moderator: Moderators

Post Reply
YaNkFaN
Field Commander
Field Commander
Posts: 943
Joined: Sat Dec 13, 2008 8:17 am

Campaign making tutorial

Post by YaNkFaN »

So, I've decided to try my luck at making a campaign map with mission objectives and a whole lot of scripting and i wanted to share my results and ideas with the community. As a community we've bested Pandemic and Lucas Arts at skinning, map design, modeling, and side creation, but as far as i've seen we haven't bested them at making campaign maps or objective driven levels. I know that RC-1920 started a tutorial but he never finished it and it was a little confusing. Since I'm trying to make a map using objectives I will try to help new and somewhat experienced modders add mission objectives. I will reference the documentation and RC's tutorial a lot but I am going to add stuff I've discovered.

So for now I have 3 objectives...
1- go to area
2- defend cp for 2 minutes
3- go and take cp

also i will use the term "variable" a lot variable# means a number that you decide and variabletxt means the name of something that is specific to your level.
the level i am using is JFR so change that to your 3 letter mod name

So here we go
Ok let me start with the notice that I'm still figuring this out myself, and I haven't really written any Tutorials before so I'm not the best at it. Furthermore, to keep me from having to type too much and becouse loads of things allready have a great description I have used some text straight from the Doc's. Text with an asterisk(*) is straight out of the Documentation
Learning mission scripting is really a matter of comparing lua scripts in from the campaign wich can be found at 'C:\BF2_ModTools\assets\scripts' and they have a '_c' at the end of their name. For Example 'cor1c_c.lua'; the Jedi Temple mission.
The main problem is that there are many ways to get the same result in scripting and each artist has it's own way of doing things. Therefore you should always compare multiple scripts. I still don't have a clue what some things mean and what they are for, those I will update as soon as I know what they mean. For the moment there will be some empty spots.

You will need:
- a texteditor like notepad. I recommend downloading Notepad ++
- Enough time to learn
- Some good music to play while learning/scripting, trust me, it makes your modding-life a lot easyer.
Before you go wild on pasting loads of code in your own Lua, make sure you have a backup. I also recommend that you start with thinking what objectives you want. For example:

First go into zeroeditor and add a region named "goto" with properties as "goto" (remove the quotes when naming it) also add a region named "distraction" with properties as "distraction (again remove the quotes) save the map and then go to your .luas
for my map i started with CW conquest and changed it into a campaign map...so first open up the JFRc_con.lua in C:\BF2_ModTools\data_JFR\Common\scripts\JFR or wherever you have the .luas

next you must add these lines to your script

right under
ScriptCB_DoFile("ObjectiveConquest")
ScriptCB_DoFile("setup_teams")

you must add
ScriptCB_DoFile("MultiObjectiveContainer")
ScriptCB_DoFile("ObjectiveGoto")
ScriptCB_SetGameRules("Campaign")

explanation of what they do
ScriptCB_DoFile("MultiObjectiveContainer") ( i believe this one allows your level to have more than one objective)
ScriptCB_DoFile("ObjectiveGoto") (this adds the ability to have an objective that makes a player go to an area)
ScriptCB_SetGameRules("Campaign") (this sets up the level so it plays like a campaign ie players cannot change teams)

next these lines must be added

onfirstspawn = OnCharacterSpawn(
function(character)
if IsCharacterHuman(character) then
ReleaseCharacterSpawn(onfirstspawn)
onfirstspawn = nil
objectives_timer = CreateTimer("objectives_timer")
SetTimerValue(objectives_timer, 2)
StartTimer(objectives_timer)
begin_objectives = OnTimerElapse(
function(timer)
StartObjectives ()
ScriptCB_EnableCommandPostVO(0)
end,
objectives_timer
)
end
end
)

i'm not going into what they mean but they pretty much make sure objectives start when the player spawns and not the AI copy and paste this directly into your .lua after

function ScriptPostLoad()

now on to your objectives

--Head towards gunship objective #1 (attack)
Objective1 = ObjectiveGoto:New{TeamATT = ATT, -- objective made
text = "level.JFR.1", popupText = "level.JFR.1_popup", -- show objective on screen
regionName = "goto", mapIcon = "hud_objective_icon_circle", AIGoalWeight = 0}

Objective1.OnStart = function(self)
ATT_obj1_aigoal = AddAIGoal(ATT, "Deathmatch", 100)
MapAddEntityMarker("goto", "hud_objective_icon", 3.0, 1, "YELLOW", true) -- AI objective
end

Objective1.OnComplete = function(self)
ShowMessageText("game.objectives.complete", ATT)
DeleteAIGoal(Objective1.defGoal1)
DeleteAIGoal(Objective1.defendGoal1)
ATT_ReinforcementCount = GetReinforcementCount(ATT)
SetReinforcementCount(ATT, ATT_ReinforcementCount + 20)

end
the italicized variables are localization calls they pretty much tell the lua what text to display I had to create my own

i suggest you look at
http://www.gametoast.com/forums/viewtopic.php?t=971 for more info on localization
now to explain what the lines do

--Head towards gunship objective #1 (attack) (this has no value it just allows you to know what objective this is)
Objective1 = ObjectiveGoto:New{TeamATT = ATT, -- objective made (this defines teams and objectives ObjectiveGoto is a specific objective in the objective script i wouldn't change this line)
text = "level.JFR.1", popupText = "level.JFR.1_popup", -- show objective on screen
(this determines what text pops up (level.JFR.1_popup) and what text is on the minimap when you press "m" (level.JFR.1)
regionName = "goto", mapIcon = "hud_objective_icon_circle", AIGoalWeight = 0}
(this defines a region named "goto" which we added earlier and also adds a marker for in on the minimap)
Objective1.OnStart = function(self)
(this line is critical it actually starts the objective)
ATT_obj1_aigoal = AddAIGoal(ATT, "Deathmatch", 100)
(this sets a goal for the AI, a deathmatch goal pretty much means the AI will kill and attack each other nothing interesting)
MapAddEntityMarker("goto", "hud_objective_icon", 3.0, 1, "YELLOW", true) -- AI objective
(this adds a flashing arrow that marks ingame where you want the player to go)
end

Objective1.OnComplete = function(self)
(this defines what happens when the objective is met)
ShowMessageText("game.objectives.complete", ATT)
(this displays "objective complete" for the ATT team when the objective is completed)
DeleteAIGoal(Objective1.defGoal1)
(this deletes the AI goal "deathmatch"
DeleteAIGoal(Objective1.defendGoal1)
(this does the same i believe)
ATT_ReinforcementCount = GetReinforcementCount(ATT)
(this gets the number of reinforcements for the ATT)
SetReinforcementCount(ATT, ATT_ReinforcementCount + 20)
(this adds reinforcements for the ATT you can change the 20 to any # i believe)

end

this ends objective 1


Objective 2
Objective2CP = CommandPost:New{name = "cp6", hideCPs = false}
Objective2 = ObjectiveConquest:New{teamATT = DEF, teamDEF = ATT,
textDEF = "level.JFR.2",
popupText = "level.JFR.2_popup",
timeLimit = 180, timeLimitWinningTeam = ATT}
Objective2:AddCommandPost(Objective2CP)
Objective2.OnStart = function(self)
Objective2.defendGoalDEF = AddAIGoal(DEF, "Defend", 1000, "cp6")
MapAddEntityMarker("cp6", "hud_objective_icon", 3.0, 1, "YELLOW", true)
end
Objective2.OnComplete = function(self)
ShowMessageText("game.objectives.complete", DEF)
DeleteAIGoal(Objective2.defendGoalDEF)
MapRemoveEntityMarker("cp6")
DEF_ReinforcementCount = GetReinforcementCount(DEF)
SetReinforcementCount(DEF, DEF_ReinforcementCount + 20)

end
now to explain

Objective2CP = CommandPost:New{name = "cp6", hideCPs = false}
(this pretty much sets the objective and defines the command post in this case cp6 also this makes sure that cp6 is visible along with all other cps)
Objective2 = ObjectiveConquest:New{teamATT = DEF, teamDEF = ATT,
(this is a little confusing but this switches ATT and DEF so the CIS is now ATT and REP is now DEF i don't know why this line was here but i kept it anyway)
textDEF = "level.JFR.2",
(this adds the text to the map)
popupText = "level.JFR.2_popup",
(this adds popup text)
timeLimit = 180, timeLimitWinningTeam = ATT}
(this is the time limit here it is 180 seconds or 3 minutes this is how long the team DEF must keep the CP from being captured by ATT)
Objective2:AddCommandPost(Objective2CP)
(this adds the command post to the objective)
Objective2.OnStart = function(self)
(this starts the objective)
Objective2.defendGoalDEF = AddAIGoal(DEF, "Defend", 1000, "cp6")
(this tells the DEF team to defend cp6)
MapAddEntityMarker("cp6", "hud_objective_icon", 3.0, 1, "YELLOW", true)
(this adds the yellow arrow over cp6)
end
Objective2.OnComplete = function(self)
(when objective is complete)
ShowMessageText("game.objectives.complete", DEF)
(this shows "objective complete")
DeleteAIGoal(Objective2.defendGoalDEF)
(this deletes the DEF goal of defending the cp)
MapRemoveEntityMarker("cp6")
(this removes the arrow from over cp6)
DEF_ReinforcementCount = GetReinforcementCount(DEF)
(gets reinforcement count of DEF)
SetReinforcementCount(DEF, DEF_ReinforcementCount + 20)
(adds 20 reinforcements to DEF)
end


-- Objective 3 --

Objective3CP = CommandPost:New{name = "cp3"}
Objective3 = ObjectiveConquest:New{teamATT = DEF, teamDEF = ATT, text = "level.JFR.3", popupText = "level.JFR.3_popup"}
Objective3:AddCommandPost(Objective3CP)

Objective3.OnStart = function(self)
AICanCaptureCP("cp3", ATT, false)
Objective3.defGoal3 = AddAIGoal(DEF, "Defend", 3000, "cp3")
end

Objective3.OnComplete = function(self)
ShowMessageText("game.objectives.complete", ATT)
SetProperty("cp3", "CaptureRegion", "distraction")
SetProperty("cp3", "SpawnPath", "cp3_spawn")
SetProperty("cp3", "Value_DEF_CIS", "0")

end
DeleteAIGoal(Objective3.defGoal3)
DeleteAIGoal(Objective3.defendGoal3)
SetProperty("CP9OBJ", "AISpawnWeight", "1000")
ATT_ReinforcementCount = GetReinforcementCount(ATT)
SetReinforcementCount(ATT, ATT_ReinforcementCount + 20)
end

explanation

-- Objective 3 --

Objective3CP = CommandPost:New{name = "cp3"}
(defines objective as cp objective the cp involved here is cp3)
Objective3 = ObjectiveConquest:New{teamATT = DEF, teamDEF = ATT, text = "level.JFR.3", popupText = "level.JFR.3_popup"}
(not gonna repeat myself this adds the name of the objective in game)
Objective3:AddCommandPost(Objective3CP)
(adds the commandpost to the objective)
Objective3.OnStart = function(self)
(starts objective)
AICanCaptureCP("cp3", ATT, false)
(false can be changed to true, this sets if AI can capture cp3 or not here they cannot)
Objective3.defGoal3 = AddAIGoal(DEF, "Defend", 3000, "cp3")
(this sets the objective so the CIS will try and stop you from taking the cp)
end

Objective3.OnComplete = function(self)
(when objective is complete)
ShowMessageText("game.objectives.complete", ATT)
(shows "objective complete)
SetProperty("cp3", "CaptureRegion", "distraction")
(this sets a new capture region for cp3 here it is called distraction for my map i put distraction below the terrain so now cp3 is uncaptureable =D )
SetProperty("cp3", "SpawnPath", "cp3_spawn")
(sets a spawn path for cp3 here it is cp3_spawn)
SetProperty("cp3", "Value_DEF_CIS", "0")
(tells the AI that there is no point in going after cp3 anymore)

end
DeleteAIGoal(Objective3.defGoal3)
(deletes the AI goal)
DeleteAIGoal(Objective3.defendGoal3)
(does the same)
SetProperty("cp3", "AISpawnWeight", "1000")
(sets the spawn weight (likelyhood AI to spawn) really high so a lot of clones will spawn at cp3)
ATT_ReinforcementCount = GetReinforcementCount(ATT)
(gets reinforcement count)
SetReinforcementCount(ATT, ATT_ReinforcementCount + 20)
(adds reinforcements
end
(ends objective)


Now once you've added all your objectives you also need to put an extra "end" after the final objectives end. This end will end the game and display victory on the screen

Lastly you must add this line before the line function ScriptInit()

function StartObjectives()
objectiveSequence = MultiObjectiveContainer:New{delayVictoryTime = 4.0}
objectiveSequence:AddObjectiveSet(Objective1)
objectiveSequence:AddObjectiveSet(Objective2)
objectiveSequence:AddObjectiveSet(Objective3)
objectiveSequence:Start()

explanation
function StartObjectives()
(this starts your objectives)
objectiveSequence = MultiObjectiveContainer:New{delayVictoryTime = 4.0}
(this i believe delays victory being displayed on the screen for 4 seconds it does the same with defeat i believe)
objectiveSequence:AddObjectiveSet(Objective1)
(this adds objective 1)
objectiveSequence:AddObjectiveSet(Objective2)
(this adds objective 2)
objectiveSequence:AddObjectiveSet(Objective3)
(this adds objective 3)
objectiveSequence:Start()
(this starts all of your objectives

as you add more objectives just like cps you must call them here by just adding
objectiveSequence:AddObjectiveSet(Objective#)

#= the objective number

more will come to this as i figure out more objectives...
if you would like any imput to this tutorial PM me and I'll add your discoveries
Last edited by YaNkFaN on Sun Dec 28, 2008 12:55 pm, edited 1 time in total.
Master_Ben
Lieutenant General
Lieutenant General
Posts: 675
Joined: Wed Nov 12, 2008 9:50 pm
Projects :: No Mod project currently.
Games I'm Playing :: I have not listed any games yet
xbox live or psn: No gamertag set
Location: Watching your PC over your shoulder. No, the other sholder....

Re: campaign making tutorial

Post by Master_Ben »

That is extremely helpful to the general scripting community. Thanks YaNkFaN! :thumbs:
User avatar
ThePanda
Private Second Class
Posts: 74
Joined: Sat Dec 20, 2008 4:22 pm

Re: campaign making tutorial

Post by ThePanda »

I have three words for you.

I love you. so much <3.

At this point in time I'm having campaign troubles, this is sure to come in handy for myself and others :thumbs:!
YaNkFaN
Field Commander
Field Commander
Posts: 943
Joined: Sat Dec 13, 2008 8:17 am

Re: campaign making tutorial

Post by YaNkFaN »

believe me a lot of people before me did a lot of work on this i sorta just was a little creative and knew where to look for stuff so yea i really do hope this helps a lot of people out
User avatar
Maveritchell
Jedi Admin
Jedi Admin
Posts: 7366
Joined: Mon Aug 21, 2006 11:03 pm

Re: campaign making tutorial

Post by Maveritchell »

It's nice to see an attempt made at something like this, but you've jumped in far too far over the heads of where a starting point needs to be.

The best way to learn how to script campaigns is, in my experience, starting with simple event scripting and working up. You can use the stock scripts as a base (which is what you do here), but frankly, I think that they're useful in the beginning only as isolated examples for how to use certain callbacks.

If you jump right in to learning objectives like you post, then what I think will happen is that you'll learn how to do very specific things, but you'll limit yourself in terms of learning to be creative. Learn how to script objectives (we have some examples in the "everything you need" thread, and the scripting_system doc is a great point of reference) and then learn to use the stock .luas' objective setups.
Grev
Hoth Battle Chief
Hoth Battle Chief
Posts: 3132
Joined: Sun Dec 09, 2007 11:45 pm
Projects :: No Mod project currently.
Games I'm Playing :: Minecraft
Location: A Certain Box Canyon

Re: campaign making tutorial

Post by Grev »

You know that Mav is a great moderator. He sees the "we haven't excelled in Campaign" and says nothing, despite his amazing script work.

On Topic: Thanks a lot! I'm sure this will prove helpful for many generations of GT modders.

FAQ?
User avatar
ThePanda
Private Second Class
Posts: 74
Joined: Sat Dec 20, 2008 4:22 pm

Re: campaign making tutorial

Post by ThePanda »

Perhaps we could work towards a fully documented LUA section, explaining how to use certain functions and the likes, accompanied by examples.

Getting more people to work with SWBF2's LUA scripting could have a positive effect on new maps coming out! The docs are a good source, albeit confusing at times. Lack of examples, or searching through stock scripts can be boring and time consuming.
MasterSaitek009
Black Sun Slicer
Posts: 619
Joined: Wed Aug 23, 2006 4:10 pm

Re: campaign making tutorial

Post by MasterSaitek009 »

All a campaign is, is a series of events, a unit dying, an object taking damage and so on. Master the events and put several together and Voila! You have a campaign. The most useful source of information on BF2 Lua is the BF2 Scripting System doc. At first glance it may seem useless, jumbled and complicated.

But if you take more time to look at each function, each piece, each event individually you'll realize, that together, the components listed in that doc are the building blocks of any campaign. And that, for me, makes it worth it to keep trying, learning and even reading. :wink:
User avatar
DarthD.U.C.K.
Master of the Force
Master of the Force
Posts: 6027
Joined: Wed Sep 27, 2006 11:05 am
Location: Duckburg, Germany

Re: campaign making tutorial

Post by DarthD.U.C.K. »

there is a campaignscripter too...
fiddler_on_the_roof
1st Lieutenant
1st Lieutenant
Posts: 460
Joined: Wed Nov 12, 2008 5:28 pm
Projects :: No Mod project currently.
Games I'm Playing :: I have not listed any games yet
xbox live or psn: No gamertag set

Re: campaign making tutorial

Post by fiddler_on_the_roof »

What does it do, or is it just like it sounds.

Nice tutorial, even if it is jumping from beginner to moderate, I still think it is very useful. :thumbs:

@D.U.C.K-- where is that campaignscripter?
Commander_Fett
High General
High General
Posts: 847
Joined: Fri Oct 17, 2008 9:59 pm
Projects :: No Mod project currently.

Re: Campaign making tutorial

Post by Commander_Fett »

It's a tool you can find in the assets links thread that is usefull for scripting objjectives. Nice tut. lol, I was going through the Mygeeto and Geonosis campaign scripts yesterday, wondering how the heck I was suposed to understand any of it.
User avatar
Sky_216
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2086
Joined: Mon Feb 13, 2006 3:28 am
Projects :: No Mod project currently.
Games I'm Playing :: I have not listed any games yet
xbox live or psn: No gamertag set

Re: Campaign making tutorial

Post by Sky_216 »

Campaign Scripter = Good. Seriously, anyone who (a) doesn't understand lua well and (b) is making a campaign, get it.

http://www.gametoast.com/forums/viewtop ... 64&t=12029

PS: nice tut Yankfan.
Commander_Fett
High General
High General
Posts: 847
Joined: Fri Oct 17, 2008 9:59 pm
Projects :: No Mod project currently.

Re: Campaign making tutorial

Post by Commander_Fett »

Holy [Diet Dr. Pepper]! That Campaign Scripter is good! With this tut and that tool, new campaigns here we come!
User avatar
ThePanda
Private Second Class
Posts: 74
Joined: Sat Dec 20, 2008 4:22 pm

Re: Campaign making tutorial

Post by ThePanda »

Skyhammer_216 wrote:Campaign Scripter = Good. Seriously, anyone who (a) doesn't understand lua well and (b) is making a campaign, get it.
AKA me :).

I have no prior experience with LUA that I can remember, but combining the scripts created with the tool with snippets from stock scripts, I've already managed to create a series of objectives for the first map in a series I'm working on!

Yankfans' tutorial has also helped me to fine tune and add to my objectives, with timers and such, so many thanks to him :).
fiddler_on_the_roof
1st Lieutenant
1st Lieutenant
Posts: 460
Joined: Wed Nov 12, 2008 5:28 pm
Projects :: No Mod project currently.
Games I'm Playing :: I have not listed any games yet
xbox live or psn: No gamertag set

Re: Campaign making tutorial

Post by fiddler_on_the_roof »

Can this be FAQ, it is really helpful.

Nice job, Yankfan
Post Reply