• Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

Level Design How To Make A Story Map

Alex_KF

Grizzled Veteran
May 17, 2006
319
8
Hey guys!


So as some of you are aware I've been developing a Story gametype for Killing Floor. It dawned on me that there's currently no documentation on how to actually use this mode in a map. So i'm here to shed a little light on that :) Please note - this is not an unreal mapping tutorial. I am assuming that if you are reading this you already understand the basics of using the editor and putting a level together (bsp, playerstarts, etc)


Things you'll need :


1. The StoryMode code/content. you can find the latest version in this thread. Extract it to your root KillingFloor folder.

2. You'll need to modify your KillingFloor.ini file to get it to load the story scripts in the editor. To do this, open up the afformentioned file and scroll to the 'editPackages' section (beneath Editor.EditorEngine) You should add an entry for KFStoryGame. it would look like so :

Code:
[B]EditPackages=KFStoryGame[/B]

Last step would be to delete your 'User.ini' file (after making sure the DefUser.ini from the StoryMode zip file is in your system folder. This will enable key-binds necessary for story mode.

Done all that? Alright! You're now ready to start story mapping! :D


The main components of a story mission​

Story mission gameplay is built using several different actors to create a web of conditions and events that can tell the game when to spawn enemies, open doors, save player progress, and so on . The main actors you will be using in your missions are as follows :

  • KF_StoryCheckPointVolume
  • KF_StoryZombieVolume
  • KF_StoryObjective
  • KF_LevelRules_Story

KF_StoryObjective

This is the most important component of a story mission as it defines what a player's goals are and what is required of him to complete the mission (or fail it). Every story map should have at least one of these actors. You can find them in the actor browser under 'navigation point'


KF_LevelRules_Story

This actor defines some broad gameplay rules in your map . Things like the maximum number of zombies that are allowed at once... or the amount of cash players lose when they die. Every map should have ONE of these actors, no more.

KF_StoryCheckPointVolume

This volume is used to save players progress as they work their way through the mission. If they die, they will respawn from the last activated checkpoint, and the game state will reset itself to closely resemble what it was at the time that checkpoint was reached. Most story maps will have multiple checkpoints. Note that it is possible to stack checkpoint volumes on top of one another, if you want to save progress without having players actually move through the level. More on that later.

KF_StoryZombieVolume

This one should be fairly self explanatory. It is a modified version of the default 'ZombieVolume' used in the Vanilla KF Game mode, with additional features to give level designers control over when and how zombies should spawn.


Creating a Simple Mission

Now that I've covered the boring stuff, i'm going to skip right ahead to practical application of these actors. We're going to be putting together a simple map with a type of gameplay quite similar to the regular KF survival GameType. The twist is - As you defeat specimens new areas of the map will unlock and you will have to progress through each area to the final one before you can win.

Let's get started :D



This is the map you will be making

This tutorial map is very simple. it is 3 long corridors separated by doors. Players spawn at one end and progress to the other end. The doors unlock as each 'wave' is completed. All of which is triggered by the Objectives you will be placing.

The very first step in making a story map should be to place a starting checkpoint. You must ensure that there is at least one playerstart inside any checkpoint you place or it will not function correctly. In my example, I have added six (because it is the KF max player count).


Next you need to adjust a few properties. in the 'StoryCheckPoint' rollout, set 'bStartEnabled' to true , and then give the checkpoint a name. bStartEnabled means that when the match begins your team will spawn at one of the playerstarts inside the checkpoint volume. If your team dies, it will restart from that spot. Each story map should only have *one* checkpoint marked bStartEnabled, otherwise the game will get confused about where to place you.

The next step is to add a levelRules actor. Story maps require these to work correctly. You can find this actor here :
Code:
 Info-->LevelGameRules-->KFSPLevelInfo---->KFLevelRules_Story

The level rules actor has a bunch of cool properties, but the most important one by far is the 'Objectives' tab. Open that one up and you will see an empty array. This is where you will be setting up a list of all the objectives in your map and the order they must be completed in. An Objective at index 0 is to be completed before an objective and index 1, for example.



This map will have seven objectives. They should proceed in a similar order to what I show in the above screenshot, with a wave timer followed by a wave, followed by a progression into the next area.

So let's take a look at the very first objective in that list - 'WaitForWave1'


The first thing you will notice is that there are *alot* of properties in objective actors. Don't worry about it. 90% of them won't apply to the objective you are making. I have highlighted the key ones in Red. ObjectiveName is important because this is how the LevelRules actor identifies it and puts it in the Objective que. Whatever you enter for 'ObjectiveName' *must* match what you put in the LevelRules , or it won't work.

The next important property would be the 'SuccessCondition'. This is what determines how this objective must be completed. For our 'WaitForWave1' objective, it's nothing too complex - We just want abit of time to pass before the first wave begins, so we set the Success condition to OBJ_Timed, and the duration to 10 seconds (in the OBJ_Timed rollout).

Next, note the 'SuccessAction'. This is what tells the game what should happen when this objective has been completed. The default behavior is to just proceed to the next objective on the level rules list. We'll leave that unchanged because the next objective is the first specimen wave, and we want it to start immediately once the time is up.

Finally, there is the 'HUD' rollout. This is not crucial, but it provides the player with some idea of what the objective is all about, so it would be a good idea to fill it in. Here's how I set mine up :


So after all that, here's how the first objective would look when we start the mission up :


Alright, so that's it for the timer - But now we need to figure out how to spawn some zombies and start the 'wave' for real.

To do this, we first need to place a KF_StoryZombieVolume.


Again, lots of properties here. By default any zombie volume you place will just spit out zombies automatically. to prevent this, you need to set 'bTimerStartsDisabled' so that it can be activated at an opportune time. The 'SpawnTypes' array controls the type of ZED this volume spits out, and the chance of it being one type of ZED or another. I won't get into that in too much detail ... suffice it to say, you need *something* in there for the volume to spawn.

Next , take a look at the 'Tag' and 'ZombieEvent' properties in the Events rollout. These are very important. To get your volume to start/stop spawning zombies you need to trigger it & that's what the tag is for. The 'ZombieEvent' is an event any Zombie spawned by this volume fires off when he dies. We will be using this event to increment our second Objective, a way of letting it know that we're killing stuff and completing our goal.

Speaking of that second objective - Let's take a look at how it's set up.



Our 'SuccessCondition' for this objective is a 'Counter'. Counters are used for ... you guessed it, counting. Each time an objective with that type of success condition is triggered, it will increment the counter by one. So we match the tag of our counter objective with the 'ZombieEvent' property from our ZombieVolume ... and suddenly, killing zombies will bring us closer to completing this objective.

The Objective Events tab is also relevant here. There are separate arrays of events you can fire off at different times. the 'Activation Events' array is fired off at the moment when that objective becomes your goal in the mission. The Completion events fire off when the objective is successfully finished. As you can see, 'Wave1Zombies' (the tag from our zombie volume) has been added to both arrays. This means that when the Counter objective starts, it will activate the Zombie volume, and when it finishes it will shut the Zombie volume off.

Here is how the finished result looks in-game.


I'm going to skip over the part about the Door Movers , because I'm sure everyone here knows how those work. The Completion event from our counter objective causes the door to lower so you can move to the next area.

Which brings us to the next Objective in the list 'GoToNextRoom'. This objective has a 'Triggered' Success condition - which means that it will be considered complete whenever it is the recipient of an event. We will be using a second Checkpoint volume in the next room to fire off that event and tell the game that all the players are inside.

This is how the second checkpoint in the map looks :



As you can see it spans the entire length of the corridor. This was intentional. When you enter the second room the door will close behind you so you can't escape the next wave. But in a multiplayer game it would be possible for one player to enter the next room while the rest of his team stayed in the first room. They would then be locked out. That's where the large volume size and 'bRequiresWholeTeam' flag comes in handy. A checkpoint with that flag will not activate until all living members of a team are inside the volume's bounds.

When everyone is safely inside the second checkpoint's bounds, it will activate and trigger the event 'GoToSecondAreaObj' (this is GoToNextRoom's tag). At this point the team's progress will have been saved (if they die they will now restart from this checkpoint, not the starting one) and the next wave timer objective will be starting its countdown in preparation for the second attack.

The methods I have been describing are more or less duplicated in the final corridor of the map, so I won't go into much detail on that. There is one notable difference however.

With the final wave, I wanted to add abit more difficulty (other than including harder zeds) so I added a 'FailureCondition' to the final wave's counter objective. Failure conditions are the counterparts to Success Conditions. Essentially, they represent a way in which the player can screw up an objective. A common FailureCondition is a Time Limit. I decided that for the Final wave players would have to kill 60 Specimens in 60 seconds, or they would fail the entire objective and be forced to restart from the last checkpoint!

Here is how the failure condition looks for the final wave objective


It is important to note that Objectives do not need to have Failure conditions. In fact, most of the objectives in the maps you create probably won't. It's simply a way of putting abit of additional pressure on players and possibly creating a more interesting type of objective. Failure conditions and Success conditions can be mixed and matched without any problem. The only exception is that you can't have a TimeLimit failure condition with a Timed Success condition. I hope it's obvious why that wouldn't work :p

Here is how the final objective looks (with failure condition) in-game



When the last objective in the level rules list is completed, the game will end in victory. Unless that objective is not marked MissionCritical, or it has a SuccessAction of DoNothing. As you will probably notice (if you manage to kill 60 zombies in 60 seconds!) you will win the mission.


Anyway, I hope that all made some sense and I am really looking forward to seeing what kind of cool story maps you guys can come up with using these methods. If anyone has any questions at all, don't hesitate to add me on Skype (A_Jim_Quick) or leave a post either here, or in the main story mode thread. The more feedback I get and the more people who use my code in their maps, the more awesome I can make it :)


Note : You can find the map used in this tutorial in the latest story mode .zip file over here

it is called : "KFS-TestmapB" ( super imaginative, I know)
 
Last edited:
Hi there. Sorry for what may seem like a silly question, but I have been reading trying to work out what I need to make an Objective map and have some questions.
Firstly do I need to download anything and do the ini thing since the objective maps are now part of the official game? Many of the keypoints listed are in the actor browser without me downloading anything special.
Also of note there is no KF StoryZombieVolume, but when I open frightyard I see the zed spawns are triggered by tag instead.
Lastly I was seeing KF StorySquadDesingner and WaveDesigner many things that showed up once I opened an Objective map... is it safe to assume I can just use these actors in my maps without jumping through download and ini hoops? Thanks in advance, any info would help.
 
Upvote 0
This is the old story mode. You can check some objective mode video tutorials from Alex in this thread
http://forums.tripwireinteractive.com/showthread.php?t=93610

Also, you can find more detailed tutorials in the wiki.

Thanks a ton for this... sadly the only wikis I found didn't have much info... KFwiki had a page for it but it was empty. His vids are brilliant and easy to follow, I wish he did one on the traders... hint hint.. lol.

I think I have a lot of it figured out now but the traders, I'm not so sure of, it seems like you need one trader controller in the start to select initial trader but need a scripted trigger to actually activate the shop volume that works the doors/teleports in the normal way. An "allow perk swap" routine along with cash need to be inserted. But what has me wondering is the "ActivateCheckpoint#" ... is that need to be tagged someplace or is it understood by the SDK knowing what place it is in? I see in StoryObjective Properties Objective_Events - Activation Events but I have not found a tag for it anywhere. Thanks again for the response
 
Upvote 0
Basically you need first a StoryTraderController to select one shop and then another to open the current shop selected.

Is quite hard to explain for me since English is not my native language.

Here, this map should help you. I always make these type of maps for me because it's helpful in the future if I forget how to make something.

https://dl.dropboxusercontent.com/u/10986702/KFO-Objective_Traders.rom

By the way, the wiki I wanted to say is the official tripwire wiki.
http://wiki.tripwireinteractive.com/index.php?title=Objective_Mode_(Killing_Floor)
 
Last edited:
Upvote 0
Brilliant, Thank you so much for the map, exactly what I needed.
One question though, the Traders shop volumes ... properties Events - event - (name of trader) in the traditional way... but it seems there is no need to put this event in anyplace as it is triggered by shop volume number... I guess it needs a name but is not used as an event itself? - OH derp I get it now <edit>

Also I went to that link and sadly the trader section is lacking in information, if you can add to that wiki I'm sure more people would find your map helpful too.. Thanks again!!
 
Last edited:
Upvote 0
The 'KF_StoryCheckPointVolume' controls the 'PlayerStart' actors inside them. If you are looking FrightYard as an example, notice that all 'PlayerStart>bEnabled' are set to false.

The 'KF_StoryCheckPointVolume' in the spawn area has 'bStartEnabled' set to true, in order to spawn there at the begining.

The rest are enabled using the Tag of the 'KF_StoryCheckPointVolume', e.g: One of the completion events of 'EnterFreightyard' objective is 'ActivateCheckpoint1' that's the tag of the next 'KF_StoryCheckPointVolume' located down the road after you cross the fence.
 
Upvote 0
I can't thank you enough for all your help, including the help on this thread from Alex too. I have plenty of questions still but I am going to post the beta version in that thread. I am working on a sort of logic diagram that breaks down the elements into easier to grasp bits for my own "cheat sheet".. I'll add a link when it's done.

http://steamcommunity.com/sharedfiles/filedetails/?id=357491760
 
Last edited:
Upvote 0