Important Message

You are browsing the archived Lancers Reactor forums. You cannot register or login.
The content may be outdated and links may not be functional.


To get the latest in Freelancer news, mods, modding and downloads, go to
The-Starport

**Tutorial** - making Story missions

Here you find the different tutorials on editing and MODing Freelancer

Post Wed Apr 21, 2004 10:38 am

**Tutorial** - making Story missions

Hi guys

This tutorial is for making your own story missions - either replacing or modifying existing ones. Note that this is not the solution to the commonly asked question of "how do I get the random missions to work?", that's something else entirely.

Firstly, a warning - making story missions is a big undertaking, there's a lot that has to be done to make one work. And that's just one - it appears to be hardcoded into the game that there are 13 exactly, so unless your first story mission "conveniently" ends up on Pittsburgh, you'll be left drifting aimlessly for ever, not being able to gain another level. As Hovis says, "and you don't wanna do that"

Anyway, to the tutorial proper. First, as a sort of reference section, a list of important things and their usage:

These conditions and actions are basically "If X occurs, do Y"

There are 42 different Conditions:

Cnd_True
Cnd_Destroyed
Cnd_CommComplete
Cnd_SpaceEnter
Cnd_Timer
Cnd_SpaceExit
Cnd_BaseEnter
Cnd_LocEnter
Cnd_RTCDone
Cnd_PopUpDialog
Cnd_CharSelect
Cnd_MsnResponse
Cnd_BaseExit
Cnd_ProjHit
Cnd_DistShip
Cnd_WatchTrigger
Cnd_PlayerManeuver
Cnd_TLEntered
Cnd_TLExited
Cnd_DistVec
Cnd_NPCSystemEnter
Cnd_LaunchComplete
Cnd_DistVecLbL
Cnd_HealthDec
Cnd_ProjHitShipToLbl
Cnd_InSpace
Cnd_SystemExit
Cnd_CargoScanned
Cnd_LootAcquired
Cnd_LocExit
Cnd_HasMsn
Cnd_SystemEnter
Cnd_JumpInComplete
Cnd_PlayerLaunch
Cnd_TetherBroke
Cnd_InTradelane
Cnd_WatchVibe
Cnd_InZone
Cnd_DistCircle
Cnd_ProjHitShiptoLbl
Cnd_EncLaunched
Cnd_DistVecLbl

And 86 Actions:

Act_ActTrig
Act_NagDistLeaving
Act_Invulnerable
Act_MarkObj
Act_PlayerCanTradelane
Act_ChangeState
Act_DeactTrig
Act_SendComm
Act_PlayerCanDock
Act_PlayMusic
Act_SpawnShip
Act_SetVibe
Act_SpawnSolar
Act_GCSClamp
Act_RandomPop
Act_MovePlayer
Act_CallThorn
Act_PlaySoundEffect
Act_StartDialog
Act_GiveObjList
Act_Destroy
Act_SetVibeLblToShip
Act_Cloak
Act_RelocateShip
Act_LightFuse
Act_SetVibeLbl
Act_ForceLand
Act_SetShipAndLoadout
Act_AddAmbient
Act_AddRTC
Act_NNIds
Act_Popupdialog
Act_SetNNObj
Act_RemoveRTC
Act_SetOffer
Act_SetTitle
Act_RemoveAmbient
Act_NagOff
Act_RpopAttClamp
Act_PobjIdle
Act_NagClamp
Act_LockDock
Act_SpawnFormation
Act_SetVibeShipToLbl
Act_NagGreet
Act_EtherComm
Act_EnableManeuver
Act_RevertCam
Act_Save
Act_PlayerEnemyClamp
Act_AdjHealth
Act_SpawnLoot
Act_LockManeuvers
Act_HostileClamp
Act_DisableTradelane
Act_NagDistTowards
Act_SetLifetime
Act_AdjAcct
Act_SetNNState
Act_SetNNHidden
Act_GiveNNObjs
Act_EnableEnc
Act_DebugMsg
Act_RandomPopSphere
Act_SetVibeShiptoLbl
Act_SetInitialPlayerPos
Act_StaticCam
Act_SetVibeOfferBaseHack
Act_NNPath
Act_PopUpDialog
Act_SetOrient
Act_RemoveCargo
Act_SetRep
Act_DisableFriendlyFire
Act_SetLifeTime
Act_SetVibeLbltoShip
Act_Jumper
Act_Ethercomm
Act_GiveMB
Act_Lightfuse
Act_SetPriority
Act_PObjIdle
Act_RpopTLAttacksEnabled
Act_DockRequest
Act_Forceland
Act_DisableEnc

Most of them are self explanatory, I'll explain how to use them as we come onto them. Now, a mistake I made was to try to 'alter' the first mission into what I wanted. Big mistake. It's FAR easier to start from scratch. So, we'll do that. Get yourself an open Notepad document and head it up as follows:

[Mission
mission_title = 1
mission_offer = 1
reward = 2000 <-- Change this for a different payout at the end...cheater
npc_ship_file = missions\m01a\npcships.ini

That identifies it as a mission. The next thing to do is to declare NPCs that will appear in the mission. Here's a typical NPC entry:

[NPC
nickname = transport1_m01a <-- this is important to spell right in the rest of the file
affiliation = co_me_grp <-- faction the ship belongs to
npc_ship_arch = MSN01a_Large_Transport <-- what ship they fly NOTE: this is NOT in shiparch.ini
space_costume = li_hatcher_head, pl_female2_peasant_body, prop_neuralnet_E_right <-- what you'll see in the little box if they talk to you
voice = pilot_f_leg_f01 <- the associated voice
individual_name = 216008 <-- the name they'll have

Now, bear in mind that you can use NPCs as many times as you want. The next thing is to declare the ship they fly. The associated entry from above:

[MsnShip
nickname = transport1 <-- this is the name you'll need to refer to in the actual mission
NPC = transport1_m01a <-- name of the NPC
label = transports <-- this is a label, read about them below
label = transportleadlabel
label = us

Labels are very useful and allow you to manipulate large groups of ships very precisely. A single ship can have as many labels as it needs, there's no limit. Usually, there is an "us" label, which identifies ships that fly with the player.

Now, to make your mission seem "living", you'll want to declare a good number of Mission Ships, friends, foes and neutral wanderers alike. You only need to create one NPC per class of ship you include (LF, HF, FR, gunboat etc), but you need to enter a MsnShip for every ship that appears in the mission. Less than about 20 and your mission is likely to seem empty. Bear that in mind. Having declared ships, do the same for Solars (stationary objects). A typical entry would be like this:

[MsnSolar
nickname = base <-- refer to it later by this moniker
string_id = 216120 <-- this is its name
faction = fc_lr_grp <-- faction affliated with
system = Li01 <-- the system this Solar is in
position = 57147, 0, -52081 <-- its position in the system
archetype = d_depot <-- what it looks like
loadout = depot <-- the weapons it's armed with
pilot = MSN01b_Weapon_Platform <-- the pilot (ie weapon skill)
base = Li01_01_Base <-- not sure about this, becaus that line means Manhattan...
label = lbl_base <-- labels
radius = 0 <-- not sure about this
visit = UNKNOWABLE <-- this means it will not appear on your nav map

It's not necessary to include Solars, it depends on what your mission will involve. For example, a mission where you attack something will likely feature Weapon Platforms, or a station, but an exploring mission might not feature anything of the sort. These are all things to consider.

Whew. Enough for one post. There'll be more later.

EDIT - feedback welcome, also if you want to know how to make a certain kind of mission, post here and I'll adapt the tutorial


"There are 10 kinds of people in this world: those who understand binary and those who don't"

Edited by - Darkstone on 4/21/2004 11:45:43 AM

Post Wed Apr 21, 2004 11:03 am

Part 3...here goes

This will be more of a reference section, because I don't know what you'll want your story missions to be about. I'll cover here how to set up the events most likely to occur in your mission. If you want a particular event covered that I haven't done, post and I'll do it.

1) Using Jumpholes/Gates

Firstly, make sure that the ships that will jump with the player, if any, have the attribute "jumper = true" in the MsnShip entry. To make them join formation with the player when he meets them, use this:

[ObjList
nickname = enter_player_formation
MakeNewFormation = fighter_basic

[Trigger
nickname = join_formation
system = *system*
Cnd_DistShip = inside, Player, *ship*, 10000
Act_GiveObjList = *allies' label*, enter_player_formation

Making the jumping bit is easy. Set an NNObjective as a rep_inst on the hole/gate and give it the appropriate "Take the Jumphole to the Chugoku system", text or whatever system you use. Set it like this:

[Trigger
nickname = at_jumphole
Cnd_DistShip = inside, Player, *jumphole/gate name*, 2000
Act_SetNNObj = take_jumphole <-- use whatever you named that objective

Simple as that. The ships that are in formation with you will automatically jump, provided they have jumper = true in the ship entry.


2) Destroying bases/big ships + their escort

This is fairly easy to accomplish. Make sure you have all the ships you're fighting named under a common label. Then, use the Cnd_Destroyed:

[Trigger
nickname = ships_destroyed
Cnd_Destroyed = *label name*, *no of ships*, EXPLODE
Act_SetNNObj = *next objective*

If you want a "break and run, they're too strong" scenario, lower the number in the condition line to however many have to be destroyed.

3) Winning

Can't believe I didn't mention this before To make the mission succeed, simply place Act_ChangeState = SUCCEED in the Trigger(s) that must be fulfilled. Equally, put Act_ChangeState = FAIL in Triggers you have to prevent from happening, like mission-critical ships being destroyed

4) Moving the player

What I mean here are places like in the 10th mission, you embark on the Osiris in the Hamburg system, but without leaving the ship, you magically appear in Texas. (yes, it's a ship that can move, but I'm speaking from a coding viewpoint here) If your mission involves moving like this, there are a number of options you have available.

Act_ForceLand = *base name* -- this will land you on a base of your choosing. The difference between this and RelocatePlayer is that with this one you see the landing sequence - an important difference in some places.

Act_RelocatePlayer = *base room name* -- this will place you in a specific room of a specific base. This is how the Osiris works.

Act_MovePlayer = *coordinates* -- different from the other two, this works within a system. It's rarely useful but is often used after a thorn file which features the player moving so you don't appear back where you were.


I don't claim this is a comprehensive tutorial, because story missions are immensely complex things. I have, however, included a list of all the conditions and actions. Most of them should be self explanatory, but also have a look in the mission ini files to see how they're used.

This isn't finished, and probably never will be, but if you want to know how to make something happen in a story mission that I haven't covered, just ask


"There are 10 kinds of people in this world: those who understand binary and those who don't"

Edited by - Darkstone on 4/23/2004 11:44:35 AM

Post Wed Apr 21, 2004 11:03 am

Right, second instalment

Having declared ships, NPCs and Solars, there are a couple more things to do. MsnFormations, which allow you to spawn groups of ships at once, rather than inputting a load of SpawnShip lines. Typical entry:

[MsnFormation
nickname = gmg_patrol <-- name of formation, used when spawning it
position = 49560, -12, -77300 <-- where it spawns, if not overridden
orientation = 1, 0, 1, 0 <-- not sure about this one
formation = fighter_li_lsf <-- the arrangement of ships, use fighter_basic if unsure
ship = gmg_leader ship = gmg_wing1 <-- the ships in the formation, as listed under MsnShip
ship = gmg_wing2 /

You also need to set objectives, so the player knows what to do. Typical objective:

[NNObjective
nickname = nn_searchpt1alt <-- name, for later use
state = HIDDEN <-- initial state, almost always should be HIDDEN
type = navmarker, Li01, 22025, 25025, 55160, -800, -67782 <-- the type of objective

There are several different types that objectives can take:

ids = *string value*, simply displays text
navmarker = sets a waypoint. Use it *system* *string value* *er...other string value* *coordinates*
rep_inst = places a mission waypoint as a ship, do the same as "navmarker" but add another bit on the end, the name of the ship

Unless you're going to be using objectives which are exactly the same as existing ones text-wise, you'll need to use fled-ids to create the text strings.

Now, once you're happy you've included enough ships, NPCs and Solars, and grouped them into formations, you need to set things called ObjLists. These are basically instructions to NPCs, like "join formation with player", which occurs quite frequently, or "fly to point X", like in missions where you part company with someone. Now, there are a LOT of different ObjLists you can enter. I'll list some of the more useful ones, take a look at the mission ini files, search for "objlist", and you'll see what else you can use them for. Make an ObjList like this:

[ObjList
nickname = ol_goto_prisonship <--give these instructions to NPCs with this name
GotoShip = goto, prisonship, 800, true, -1 StayInRange = prisonship, 750 <--- the instructions
BreakFormation = no_params /

Some common ObjList instructions:

GotoShip = goto, *MsnShip/Solar name*, *distance of ship to come within*, true, -1 -- this will cause an NPC to fly to the selected ship/solar

StayInRange = *MsnShip/Solar name*, *range* -- this will prevent an NPC from moving outside a specified range of a ship/solar

MakeNewFormation = *formation name* -- this will make the ships it's applied to form up in the specified way

BreakFormation = no_params -- this will make the NPCs break their formation, no matter what it is

Dock = *base/gate/hole/lane name* -- do I really have to explain this one?

There are more, but those are the essential ones if you want to make the NPCs really seem alive. Now it's time to move onto the 'Main Course', as it were, the Triggers. These are what will make your mission work (eventually). They're also very fickle, because a mission is generally one long chain of triggers, if you make a typo somewhere, the entire chain is broken and your mission will simply stop working at that point.

The first triggers to make are the ones that are active all the time throughout the mission, like escorting critical ships or key characters like King and Juni and the general state of the mission. The first Trigger should be something like this (this is taken from the first mission, after landing on Pittsburgh):

[Trigger
nickname = general_triggers
system = Li01 <-- make sure to enter this correctly. Is important
Cnd_True = no_params <-- this basically means "this is always active"
Act_PlayerCanTradelane = false <-- disallows the player from using tradelanes
Act_MarkObj = escort, 1 <-- this trigger marks "escort" (King) as Important on the Contact list
Act_Invulnerable = escort, true, false, 0.900000 <-- gives King a certain amount of invulnerability
Act_ActTrig = king_dies <-- this is an ActTrig, see below
Act_RandomPop = false <-- this turns off random encounters, so you only fight what you're meant to
Act_NagDistLeaving = std, escort, escort, 22195, 5000, NAG_IN_COMBAT <-- not sure

There are a few vital Conditions and Actions which it's essential you understand how to use properly

Cnd_True = no_params -- this basically announces Actions which are always active, no matter what

Cnd_Destroyed = *label/MsnShip name*, *number destroyed*, EXPLODE -- this will come into effect when a specified number of ships of a label are destroyed. If you use an MsnShip name, the number must ALWAYS be 1.

Cnd_SpaceEnter/Exit = *system name* -- when the player takes off/docks

Cnd_SystemEnter/Exit = *system name* -- the player uses a jumpgate/hole

Act_ActTrig = *trigger name* -- This forms the basis of the chain trigger system. You have to use this in your Triggers to activate others, or the others will remain passive even if the conditions are fulfilled. This might sound really unnecessary, but in practice it's quite useful

Act_DeactTrig = *trigger name* -- exactly the opposite of above. For example, if you accept a mission, the Trigger for declining the mission is disabled.

Act_SpawnShip/Solar/Formation = *Ship/Solar/Formation name* -- does exactly what it says on the tin. You'll need to use this frequently, ships won't appear at all without it.

Act_SetNNObj = *objective name* -- this will cause an objective to flash up on the screen, and the waypoint, if any, to appear.

Those are all the ESSENTIAL ones that you'll almost definitely need to use. The next Triggers to make are the ones that fail the mission if certain ships are destroyed. Make them on this model:

[Trigger
nickname = king_dies
system = Li01
Cnd_Destroyed = escort, 1
Act_ChangeState = FAIL, 22196

Set those up for your principal characters. The next ones to make are those concerning the mission offer and the player accepting it or rejecting it. This bit is rather thorny (experienced modders will get the sheer cheese of that), and it's probably best, at least in the short term, to pike a mission offer from another story mission. If your mission takes place on a base other that ones in the story, you can always use RelocatePlayer to put yourself there only for that bit. Anyway, here's the Mission 2 Briefing, you can always use fled ids to change the text

[Trigger
nickname = lce_bar_li01_01
Cnd_LocEnter = Bar, Li01_01_base
Act_AddRTC = missions\m02\M002_s009a_Li01_01_offer.ini
Act_ActTrig = mrp_reject
Act_ActTrig = mrp_accept
Act_ActTrig = write_mission_log
Act_DeactTrig = entered_the_system
Act_DeactTrig = meet_on_manhattan
Act_SetNNObj = talk_to_juni

[Trigger
nickname = mrp_reject
Cnd_MsnResponse = reject
Act_RemoveRTC = missions\m02\M002_s009a_Li01_01_offer.ini
Act_AddRTC = missions\m02\M002_s009d_Li01_01_reoffer.ini, repeatable

[Trigger
nickname = mrp_accept
Cnd_MsnResponse = accept
Act_RemoveRTC = missions\m02\M002_s009d_Li01_01_reoffer.ini
Act_AddRTC = missions\m02\M002_s010x_Li01_01_nrml.ini
Act_ActTrig = spe_li01_01
Act_SetTitle = 22200
Act_SetOffer = 22205
Act_SetNNObj = first_launch
Act_DeactTrig = mrp_reject
Act_RandomPopSphere = -30642, 0, -29671, 6000, off
Act_RandomPop = false
Act_ActTrig = exit_base
Act_DeactTrig = beginning_ether
Act_NNIds = 30205, HISTORY
Act_ActTrig = entering_cityscape
Act_DeactTrig = keep_door_open

Now you can't use exactly that because your Objectives and so forth have different names, but if you look at it, you'll see that you need to set up 3 triggers. Act_NNIds is a Log entry, and RTCs are reserved spaces in the bar for main characters so you can talk to them again if you reject the mission. I may update this section later, but for now it's a real fog to me

I've covered all the essentials, now on to putting them together to form a mission. After your mission accept/reject triggers, you'll want to put a Cnd_LaunchComplete trigger in, and have it spawn the ships that are there immediately with either SpawnShip or SpawnSolar. Also use another useful Trigger, SetVibeLblToShip. Use it like this:

Act_SetVibeLblToShip = *label of ships*, Player, REP_FRIEND_THRESHOLD. This will ensure that the ships show up as green. When you meet enemies, put these three actions in:

Act_SetVibeLblToShip = *label of enemies*, *label of allies*, REP_HOSTILE_THRESHOLD
Act_SetVibeLblToShip = *label of allies*, *label of enemies*, REP_HOSTILE_THRESHOLD
Act_SetVibeLblToShip = *label of enemies*, Player, REP_HOSTILE_THRESHOLD

Enough for now. More soon

Edited by - Darkstone on 4/22/2004 12:30:40 PM

Post Sun Apr 03, 2005 8:24 am

Did you ever get new story mission to work properly?

Post Sun Apr 03, 2005 8:38 am

I went through the first mission after reading this tutorial and now I have a few questions:

1. How are camera movements and cuts done?
2. A lot of thn files are referred to, what exactly do they do? Are they responsible for camera movements? Or do they do something else?
3. How are the conversations on a planet between two persons done? For example the Manhattan bartender and Trent.

Post Tue May 17, 2005 7:59 am

1. Thorn Files *.thn
2. Use this program to decompile them perfectly. Click here
3. See #1

Edited by - LaneHacka on 5/17/2005 9:01:23 AM

Post Fri May 27, 2005 1:16 am

I see. Well I suppose those camera-THN's just contain information how the camera has to move. But it must somehow be defined, exactly where in the current scene the camera is located.

As far as I can see, the conversations on planets are the most difficult part of the whole story-mission scripting, because of the complex animations of the bodies, which I think are only usable by the character, that already used it in the original missions. However, it could also be the case, that every body has the same "animation hardpoints" and every model can perform the same animations. Anyway, it still seems to be a tricky thing, getting fluid animations.

Post Sat Jul 16, 2005 11:55 am

There is one very important aspect which I think was not mentioned here. How are the missions triggered? What tells the game to start Mission 1a now? Is it hardcoded? Well, it obviously has something to do with the pilot's level, that's for sure, but how exactly does it work?

Post Sun Jul 17, 2005 4:52 pm

THN's are used in many cut scenes. The most common places they are used include:

Single Player Story Cut Scenes
The various Intro screens you get playing in the background of the menu
Any 'room' on a planet or station
Any docking and landing scenes that occur

Sometimes one scene can have as many as four THN's (as in the case of planetary landing scenes: There is the ambient THN for lighting and special effects including background traffic (or was that a seperate file, I can't remember clearly at this time of morning), hardpoints (where everything appears in the scene including the scenerio, the player ship etc...), a landing animation THN and a take off THN). It is not just Camera movements defined in the THN's but more importantly, it does dictate the start and stopping points (or what the camera is following and where to begin from). The same applies to any animations as well.

Freeworlds Mod Developer
Author of Modular Station

'There is no Good nor Evil in the universe, just perceptions and circumstances.'

Post Mon Jul 18, 2005 4:38 am

Thank you, but that was not really my question. Maybe I should specify it. How does the game know to start m01a.ini now, at the beginning of the game? And how does it know to start m01b after that?

Post Mon Jul 18, 2005 8:49 am

Because of the following entry in the newplayer.fl

[StoryInfo
Mission = Mission_01a
MissionNum = 1
delta_worth = -1

Edited by - Louva-Deus on 7/18/2005 9:55:30 AM

Post Fri Jul 22, 2005 10:28 am

Ah, great. And now of course the folowing question is: How is defined which mission comes after the first one? Is it maybe defined at the end of the script of the first mission?

And with the question "What is initialized?" the question "When is it initialized?" remains. Ah and of course where the missions are listed. Cuz in m01a.ini, the term "Mission_01a", referred to by the newplayer.fl, actually never appears. Thus there must be a file or entry in which all missions are defined and given their ini-files. Where is this located?

And another one, about IDs this time: The mission title and description at the very beginning of the script lead to empty strings, like the objective IDs to as well. Any idea what's going on here?

Post Fri Jul 22, 2005 10:38 pm

All of that is handled by the content.dll file as far as I know.

Post Thu Mar 23, 2006 10:32 am

Thanks come first, Darkstone!
Then questions...:-)
I'm trying to make a mod that acts like an open sp until you do something like docking to FP7 or reach a particular level, then you trigger the intro movie (FP7 destruction) and all of the original story missions.

The idea is to leave the entire m01a dormient until you have:

Cnd_BaseEnter = FP7_01_Base ; if I'm right

and when it occurs you have something like:

ActTrig = "start mission 01a" ; well... ,-)

But don't know how to proceed, I need a complete explanation of how those mission.ini files (and all Conditions & Actions) work. Do you know of a link to that?

by 1001

Post Sun Mar 26, 2006 11:58 am

I'll keep this short as it isnt really the place to be holding discussions - The actual triggering of a mission (m01a, 01b etc) is hardcoded in content.dll so you can't add a new one. What you will need to do is add content to 01a so you start at leeds, get wp's to FP7 then trigger the anim sequence when you land For further q's on this please use General Editing forum

+++ out of cheese error - redo from start +++

Return to Freelancer Editing Tutorial Forum