Game storyline scripting

Hi All,

I’m looking for some guidance on a game I’m working on

I’m sorta up to the part when I want to actually implement a story line into my game

Just wondering the best/easiest way of doing it

So far I have a class with a big switch statement that looks like


switch(strGameIndex){	

case 2:
//Load a map
Game_Control.FlagMapChange("RealHouse1",-1,-1,false);
incrementIndex();
break;
				
case 3:
//Add the MC		
if(Game_Control.WhichMap().equalsIgnoreCase("RealHouse1")){
AddPC(ConfigSettings.MainCharacterName, 9, 13, "MCSet");
Camera.SetActiveCharacter(ConfigSettings.MainCharacterName);
Camera.SetCameraFollow(ConfigSettings.MainCharacterName,true);	
EntityController.SetRelations(ConfigSettings.MainCharacterName, "MC");
incrementIndex();
}
break;
}

So something is triggered then the game index is increased

A condition is checked then if true something happens and then it moves onto the next index

I can see this getting messy quickly and would like remove it from actual code.

I was also thinking of being able to have different game modes that would use a different game script.

Is this the way it should be done? Or is there better way then using a switch with a game index int.

Also will have quest system that is in another class that can be triggered from this main script

Thanks

How does what you have relate to storyline? It looks like it’s just about changing the map. If that’s the case, just change the map. I don’t understand what the deal with the script statement is. It seems like you could just have code like the following:

Game_Control.FlagMapChange("RealHouse1",-1,-1,false);
AddPC(ConfigSettings.MainCharacterName, 9, 13, "MCSet");
Camera.SetActiveCharacter(ConfigSettings.MainCharacterName);
Camera.SetCameraFollow(ConfigSettings.MainCharacterName,true);	
EntityController.SetRelations(ConfigSettings.MainCharacterName, "MC");

The AddPC line should load the settings from some sort of file rather than using constants.

Yes, the storyline shouldn’t be in the code. You need to write scripts that the program loads and then runs.

Also, you need to have separate scripts wherever you need them. You don’t just cram it all into one file with a switch statement (if that’s what you were planning on doing).

Sorry yes that may have been a bad example it was just the first part of the code.
The reason it was done like that was so that the character was added after the map had actually loaded.

What I’m really asking is

If I put that into a script would I have an int to track what part of the script should be running, sorta like the switch or is there a better way getting the code to flow from one part to another. I was thinking of breaking the scripts into chapters to reduce the amount of code in there is that a good way to go?

and the value ConfigSettings.MainCharacterName was used mainly because that value is set at the name select screen, for other characters(other then the main character) they in the map file or will be in the game script

You should definetly break up the different parts.

Maybe the stuff that happens in every map should stay in the code, and only the other stuff should go into a script. You could have a “start of map” script for each map that is executed whenever you enter the area.

Some of that stuff sounds like it should either happen in every map or only be done once when the game is started. It’s hard to tell from looking at a section of your code and trying to guess what the different method calls do.

My map files have a section for script on load so that it can run a script when the map is loaded
and I have defined scripted areas that can run scripts on enter, while in or exit (or any combo of that)

They will be for things like I flick a switch a door opens, would be in the map so that its sorta a sealed unit

What I want the game script to do is add scripted areas (as need for extra stuff) or add characters, display messages, move the camera around bring in enemies ect at certain points in the game, things that would make up the events in the game

How do I keep track of where I am in the code, other then an index value?
Otherwise I will end up with something very much like I already have but just in a external script
an example would be great

Well, you’d have a scripting language (eg, Pnuts). The scripts would be able to declare variables and functions, so they can keep track of any state they want. You can run a script when the map loads and it can look up various objects in the map and attach functions (or listeners) to them. Something like this, using Pnuts script syntax:


trapArmed = false

map.getObject("trapTrigger").addListener("enter", function () {
    trapArmed = true
})

trap = map.getObject("trap")
trap.addListener("enter", function () {
    if (!trapArmed) return
    game.applyDamageRadius(trap.x, trap.y, 5, 100)
    game.applyExplosionImpulse(trap.x, trap.y, 10, 3.5)
})

The map and game objects would be inserted by your code before the script is run, to give the script access to whatever it needs. This code might make it so if the player walks over the trapTrigger object, then walks over the trap, the trap applies 100 damage in a radius of 5, and an impulse of 3.5 in a radius of 10. Or whatever you want your script to do. As you can see, state is store in the global scope and functions are attached to objects to manipulate the state as events occur.

That does look like something that I would add into a map script but the game will be an RPG so you can go to a map more then once during the game so it may be hard putting different parts of the main code into the map scripts?

I’d recommend forgetting this whole sequential way of doing it and instead coming up with a more generic “trigger” approach (like in the Starcraft map editor). Each trigger has conditions and actions, which can be generic and implement a Condition and Action interface (boolean isMet() and void doAction()). Then every timestep you run through all the conditions to see if they’re met, and if they are you do their action.

Typically you’ll want to expose a HashMap got tracking variables, then give all the triggers access to it (also mutation). This way for something like a storyline you can just link them together by the value of a certain integer with a key that’s something like “ConversationA” and you can check the value of that as the condition for the next conversation action.

You can refine this to make it a lot more efficient in various ways, but usually you’re not going to have so many triggers that it will really matter just checking them all every single timestep.

That sounds like the sort of thing that I may need, what would be a good way to keep them in the correct order?
Since the main events will happen in a (somewhat) sequentail order

Thanks

Either your map isn’t so big and you can have one set of scripts for the whole map, or your map is too big and you’ll need to break it into pieces even if you weren’t using scripts.

I have a map for each area like say a village and each inside of a house is in a separate file

and would prefer to keep the scripts in the map file more for things like say a switch or other actions for objects on the map instead of game specific events other wise I will have bits of the game story line stored in say 100 different map files and if I want the game to return to an area later on then that map would contain early in the game code and later on in the game code.

I would perfer to have a main script that runs independant of any specific map file because as mentioned in the first post it may also be responsible for loading map files if the game requires a change of area

Maybe a file with something like


<Event>
 ID=1;
 Description=just to type in what is going on;
 Trigger=something to trigger event;
 OnEvent=do something;
</Event>

then just work through the events?

You shouldn’t define the sequential functionality on the broad level, but instead should make a Condition type that requires other Actions to have fired (which can be set by saving a variable into your HashMap). Every timestep you check through every single Condition. Say ConditionA fires once you walk onto (x,y). It shows a dialogue string, and it sets “ConditionSequence” to 1. ConditionB fires whenever ConditionSequence is 1, it displays an emote and some more dialogue, and it sets ConditionSequence to 2. ConditionC fires whenever ConditionSequence is 2, it does yadda yadda, etc.

Let me be the first to point out that there is plenty inefficient about this approach, and there are lots of better ways. But, it will almost certainly be good enough for your purposes, and it’s incredibly easy to implement.

Thanks for the idea’s I will have a bit of a play around and see what I come up with

I am quite interested in what you come up with :).

you got me thinking about this :slight_smile: