Storyline Mission Tutorial

  • Storyline missions is what i'm the best at. It's my favorite part of modding.


    I think that first i'll cover your basic NPCShips.INI file.


    [NPCShipArch]
    nickname = MSN01b_King
    loadout = MSN01b_King
    level = d1
    ship_archetype = li_fighter
    pilot = MSN01b_King
    state_graph = FIGHTER
    npc_class = lawful, FIGHTER


    This is King from Mission 1b.
    Nickname is the name used to reference the ship arch during ship declarations in the mission file.
    Loadout is the loadout as defined in loadouts.ini, loadouts_special.ini, and loadouts_utility.ini
    Level is the Difficulty you see when you target the ship in-game.
    Ship Archetype is the ship the NPC uses.
    Pilot is, put simple, the pilot's style of flying the ship.
    State Graph has something to do with the way the pilot flies the ship. Default is FIGHTER for smallships, GUNBOAT for gunboats, CRUISER for cruisers and battleships, TRANSPORT, etc.
    NPC Class is how the ship is classified. Default is lawful, and FIGHTER, elite_fighter, GUNBOAT, CRUISER, battleship, etc.


    [NPCShipArch]
    nickname = hostile_fighter
    loadout = fc_lr_pi_fighter_loadout01
    level = d1
    ship_archetype = pi_fighter
    pilot = pilot_pirate_easy
    state_graph = FIGHTER
    npc_class = lawful, FIGHTER


    This is a basic enemy fighter.


    Now, we take a look at the actual mission file.


    Here is the beginning of the file for Mission 1b:


    [Mission]
    mission_title = 22000
    mission_offer = 22005
    npc_ship_file = missions\m01b\npcships.ini


    Mission title is the ID for the mission title.
    Mission offer is the ID for the description you see during offers.
    NPC ship file is the npcships.ini we covered earlier.


    I'll show you a basic NPC entry:


    [NPC]
    nickname = escort_m01a
    affiliation = li_lsf_grp
    npc_ship_arch = MSN01b_King
    individual_name = 216100
    voice = king
    space_costume = li_scrote_head, li_scrote_body, comm_li_hatcher


    Nickname is the name used to reference.
    Affiliation is the faction the ship is associated with. (Use fc_uk_grp so you only see the name)
    npc ship arch is the [NPCShipArch] in npcships.ini.
    Individual name is the ID for the name of the ship.
    Voice is the pilot's voice, used during comms.
    Space costume is the head, body, and optional commhelmet or prop seen during comms.


    [NPC]
    nickname = hostile
    affiliation = fc_lr_grp
    npc_ship_arch = hostile_fighter
    individual_name = 1


    If there is no voice or costume like in this one, it will generate a random one via factionprop.ini


    Here is a MsnShip entry:


    [MsnShip]
    nickname = escort
    NPC = escort_m01a
    rel_pos = 90, Player, 200
    label = escort
    label = us
    radius = 150


    Nickname is... oh, for crying out loud, you know what it does ;)
    NPC is the [NPC] we declared earlier in the file
    Rel_pos tells the game to spawn this ship 200m in front of the player. -90 would be behind, etc.
    But if you want a specific position use something like position = 20000, 500, -10000
    Orientation is the odd thing about coding missions. It's not your usual x, y, x axis parameters, instead it's... weird...
    All I know about orientations is that if you do 0, 0, 0, 0 then the ship doesnt show and causes lots of slowdown. (Only In some cases, though, and may not occur for you).
    If you do 1, 0, 0, 0. Then it will rotate the ship around the Y axis. Same for 1, 0, 1, 0 and 0, 0, 1, 0.
    I'm still not completely sure how it works...
    Labels... labels are fun little... things. They allow you to manipulate groups of ships at once. 'us' is usually used for ships flying with the player.


    [MsnShip]
    nickname = baddie1
    NPC = hostile
    position = 20000, 400, -10000
    label = hostiles


    [MsnShip]
    nickname = baddie2
    NPC = hostile
    position = 20100, 500, -10000
    label = hostiles


    I tend to leave out radius and don't experience a crash, feel free to experiment. ;)


    IF you use the above two msnships, in-game they will have no name. That's because we didn't tell the ship to use a random name. We ought to fix that, right?



    [MsnShip]
    nickname = baddie1
    NPC = hostile
    position = 20000, 400, -10000
    label = hostiles
    random_name = true


    [MsnShip]
    nickname = baddie2
    NPC = hostile
    position = 20100, 500, -10000
    label = hostiles
    random_name = true


    One more method of spawn is making a ship launch from a base! Can you see why I love doing missions? You control everything!


    [MsnShip]
    nickname = baddie3
    NPC = hostile
    arrival_obj = base
    label = hostiles
    random_name = true


    [MsnShip]
    nickname = baddie4
    NPC = hostile
    arrival_obj = base
    label = hostiles
    random_name = true


    Arrival_obj replaces position and orientation and defines what MsnSolar (or solar in the system) the NPC launches from. Are you getting the hang of it?


    There's our MsnShips!
    It can now be spawned during the missions via Act_SpawnShip = name.


    Here is a basic Objective:


    [NNObjective]
    nickname = null
    state = HIDDEN
    type = ids, 21660


    If this is set, the objective will be: AWAITING MISSION OBJECTIVE


    Another:


    [NNObjective]
    nickname = killhostiles
    state = HIDDEN
    type = ids, 22095


    This one says: DESTROY ALL THE HOSTILE FIGHTERS


    Neat, huh?


    One more:


    [NNObjective]
    nickname = gotobase
    state = HIDDEN
    type = rep_inst, Li01, 22040, 22040, 57418, -571, -68763, base


    This puts a waypoint at the base then tells the player: FLY TO THE WAYPOINT
    (OPTIONAL depending on the Mission you want to make)
    A MSNSolar:


    [MsnSolar]
    nickname = base
    string_id = 216120
    faction = fc_lr_grp
    system = FP7_system
    position = 20000, 500, -10000
    archetype = d_depot
    loadout = depot
    pilot = pilot_solar_ace
    base = Li01_01_Base
    label = lbl_base
    radius = 0
    visit = UNKNOWABLE


    I won't go into it deeply but archetype is the type of base, label is the label, visit should be left UNKNOWABLE.


    Objective lists are useful for making ships do certain things.


    [ObjList]
    nickname = ol_followp1
    Follow = Player, 1000, 0, 50, -100


    Now we will play with our new toys!


    Our first trigger should look like this


    [Trigger]
    nickname = tr_init
    InitState = ACTIVE
    Cnd_True = no_params
    Act_ActTrig = next_tr


    Isn't it cool? It lets the game know this is the trigger to start with.
    Act_ActTrigger triggers another trigger.


    [Trigger]
    nickname = next_tr
    system = FP7_system
    Cnd_Timer = 1
    Act_SpawnShip = escort
    Act_GiveObjList = escort, ol_followp1
    Act_Invulnerable = escort, true, false, 0.990000
    Act_SpawnSolar = base
    Act_SetNNObj = gotobase
    Act_ActTrig = closetobase


    This spawns King, gets him into formation with the player and makes him invulnerable up to 99% of his health.
    Spawns the base, and sets the Objective to goto the base


    [Trigger]
    nickname = closetobase
    system = FP7_system
    Cnd_DistShip = inside, Player, base, 3000
    Act_SpawnShip = baddie1
    Act_SpawnShip = baddie2
    Act_SetVibeLblToShip = hostiles, Player, REP_HOSTILE_MAXIMUM
    Act_SetNNObj = killhostiles
    Act_ActTrig = mark_hostiles1
    Act_ActTrig = spawn_more


    [Trigger]
    nickname = mark_hostiles1
    system = FP7_system
    Cnd_DistShip = inside, Player, base, 1000
    Act_MarkObj = baddie1, 1
    Act_MarkObj = baddie2, 1


    [Trigger]
    nickname = spawn_more
    system = FP7_system
    Cnd_Destroyed = hostiles, 1, ALL
    Act_SpawnShip = baddie3
    Act_SpawnShip = baddie4
    Act_ActTrig = mark_hostiles2
    Act_ActTrig = hostiles_dead


    [Trigger]
    nickname = mark_hostiles2
    system = FP7_system
    Cnd_DistShip = inside, Player, base, 1000
    Act_MarkObj = baddie3, 1
    Act_MarkObj = baddie4, 1


    [Trigger]
    nickname = hostiles_dead
    system = FP7_system
    Cnd_Destroyed = hostiles, -1, ALL
    Act_LightFuse = base, pirate_base_explode_fuse
    Act_ActTrig = d_piratebase


    [Trigger]
    nickname = d_piratebase
    system = FP7_system
    Cnd_Destroyed = base, 1, ALL
    Act_ActTrig = tm_succeed


    [Trigger]
    nickname = tm_succeed
    system = FP7_system
    Cnd_Timer = 4
    Act_ChangeState = SUCCEED


    This is not a very big mission but it's just for demonstration.
    I'll explain the Cnd_Destroyed a little bit
    The first parameter is the ship, or label ( :D ), that we are watching for fatalities.
    When the number specified in the second parameter, die because of what is specified in the third parameter, the trigger acivates.
    ALL means if they dock, explode, disappear, jump to a system other than the one specified in system = #, or just generally don't exist anymore.
    Another is ALL_IGNORE_LANDING. If one docks with a base, the counter doesn't decrement.
    I tend to always use ALL.


    Cnd_DistShip is useful when a certain ship enters range of a certain object.
    You can also use Cnd_DistVec when you want to specify coordinates instead of a ship.


    The example mission provided goes as follows:
    You spawn in FP7_system, along with King. You are given the waypoint to a Rogue base, and once you get within 3000m, two Rogue ships attack you.
    When one of them is destroyed, two more launch from the base.
    When the last are destroyed, the base explodes, completing the mission.


    I DID NOT TEST THIS MISSION PERSONALLY. IT IS FOR EXAMPLE ONLY.


    I also want to tell you about Clamps. I recently started using them to a minimal extent in prototype missions. As far as I know...


    Act_RpopAttClamp = true will not allow random spawning of ships affiliated with a faction hostile to the player (if RandomPop = true)
    Act_PlayerEnemyClamp = true will allow random spawning of ships affiliated with a faction hostile to the player... but initially spawn them as neutrals. Just like at the beginning of a random mission.
    Act_HostileClamp = true will turn randomly spawned npcs of a faction hostile to the player neutral... like in random missions
    Act_RpopTLAttacksEnabled = false will disable random tradelane disruptions (from pirates)
    Act_RandomPop will enable random NPC spawns


    I will occasionally update this tutorial.


    Happy coding!


    Can you all tell me if this tutorial is any good... it is my first tutorial and I may have screwed up along the way.

  • Quote from "rasauul"


    [MetaBehavior]
    nickname = goto_guide_to_frankfurt_jumpgate
    MB_GotoGuide = Player, 0, 0, 100, 92421, 0, -16577, 4000


    Thanks, i'll figure out what it does.

  • Quote from "JONG"

    Does this tutorials can use at MP storyline mission?


    Yes, the same rules apply for missions coded for multiplayer except you need to be careful because it is buggy and undocumented.

  • Ok, I must say that this is a great tutorials for me, thanks for your share.


    but as I know, the MP players always spawned in base, if I need players spawned in space, how to do it?


    I mean is:


    When a new player join a server, he will not start in a base, he will fly in space and has a few NPCs follow him (NPC want to kill him), is it possible?

  • Hehe figured out one of the unused commands (im kinda proud of this :D )


    The unused commands you mentioned:
    First one actually seems really interesting, and im pretty sure i have guessed what this one does, hehe.


    Act_SpawnShipRel


    What this does is spawn a ship at your designated coords and makes it enter into formation with you in one command line, and here is a working example:
    Act_SpawnShipRel = Dokai_Surabaya, Player, 500, 500, 500, 500, true


    Also check out the trial and error bonus that makes a ship spawn inside the player (below), maybe this could be usefull for something


    Trial and error:
    Spawn a ship relating to another object, for example another ship, this would be real practical when doing spacebattles, since you wouldnt have to worry about the location of the player. Just drop the spawnies relating to the location of the player.


    Im gonna try for an example:
    first the command,
    then =,
    then the ship we wanna spawn,
    then the ship/solar we wanna spawn near
    (use PLAYER cause thats the only reason to create a command like this)
    then X, Y, Z (as in formation),


    Act_SpawnShipRel = 1500, a_ship, Player
    nothing happens


    Act_SpawnShipRel = Dokai_Surabaya, 1500, Player
    spawns at coords unrelated to player


    Act_SpawnShipRel = Dokai_Surabaya, Player, 1500, true
    spawns inside player


    Act_SpawnShipRel = Dokai_Surabaya, Player, 1500, -50, 0, 100
    spawns at coords unrelated to player


    Act_SpawnShipRel = Dokai_Surabaya, 1500, -50, 0, 100, Player
    spawns at coords unrelated to player


    Ha ha, i was wrong, what this does is spawn a ship and makes it enter into formation with you in one command line, and here is a working example:


    Act_SpawnShipRel = Dokai_Surabaya, Player, 500, 500, 500, 500, true

  • correction, you designate the formation coords not the spawn coords, i guess this is why they didnt use it.


    If u use this remember to set invulnerability in case your ship spawn too close to a sun/planet

  • hey Milkman heres my thoughts about the unused commands you found:


    Here we go trying to figure em out:
    Act_SpawnShipRel <<<<<<< done that :D


    Act_SetFlee
    i bet this sets a ship to flee at certain amount of damage
    Possible example:
    Act_SetFlee = juni, 0.700000


    Act_RepChangeRequest
    Why would we need a request? we have all the commands we need for changing reps


    Act_RelocateForm
    This sounds like the Group/formation variant of the MovePlayer order
    maybe; Act_RelocateForm = some_formation, -14500, -13100, 1150, true


    Act_PlayerForm
    this sounds like an enter formation order for the player, like an objlist formation order but for player
    maybe; Act_PlayerForm = ship_name, -1400, 100, 150, -200


    Act_PilotParams
    I reckon this could be about switching pilot AI's, or it could be about changing the target.


    Cnd_CmpToPlane
    Sounds like its talkin about cmp files, maybe not?


    Cnd_JumpgateAct
    this one being a CND aka trigger-starter, i reckon it will fire the trigger when you do something related to a designated jumpgate, maybe:
    Cnd_JumpgateAct = Dock, St01_to_st02_hole



    Cnd_RumorHeard
    this being a CND aka trigger-starter, i reckon it will fire the trigger when you have heard a particular rumor´, maybe like this:
    Cnd_RumorHeard = 393427


    gogo mate, trial and error the helloutta these guys! :D


    Have fun.
    Rasauul

  • Quote from "rasauul"

    hey Milkman heres my thoughts about the unused commands you found:
    Act_RepChangeRequest
    Why would we need a request? we have all the commands we need for changing reps


    I think Act_RepChangeRequest might change the faction for a certain ship. I'll try it out later this weekend.

  • Ive a challenge for you... lets say you want someone to dock with "X" jumpgate but undock from "Y" jumpgate (which happens NOT to be a destination of "X" Jumpgate?


    The reason I ask is... I have a reworked Li05 which is used in my multiplayer mod. Due to certain minefields and changed locations of various objects in the system, it is impossible for the Jacobi Rescue to occur. IF I were to have the mission ini set up so the player would dock with the Li01_to_Li05 jumpgate but instead of entering the Li05 system (my multiplayer system)... I'd have them spawn at the Li05SP_to_Li01 jumpgate in the Li05SP system. Is this possible using singleplayer mission scripting? If so, could you give a fella some tips? :P

  • Don't think so. The destination is part of the jump gate object, nothing to do with the script. What you might be able to do, though, is simply relocate everyone immediately upon entering the system.

  • Hello to the Freelancer community! :D


    I have a question to people about the mission scripting.


    The issue I am experiencing is that when a gotovec command under [Objlist] is given to a battleship, it moves correctly and accordingly, however there is a problem:


    The battleship is a hostile to my ship and as it moves, it will not fire and instead point the weapons at me. Only until it has stopped at its destination position that the gotovec specifies will it's turrets attack my ship. It's when the [Objlist] gotovec command is given and the ship is in motion it doesn't fire.


    I noticed too the strangest thing is that if hostile ships come within firing range of the ship in the subject before the [Objlist] gotovec command is given then the issues of the battleship firing defensively are eliminated.


    It's only when the [Objlist] gotovec command is initiated before any hostiles to the moving ship come within firing range will it hold it's fire while in motion until it has reached it's position destination specified in gotovec.


    Do any of you know the answer to this problem? I will greatly appreciate your help and I am eager to show you all what I have been working on.