Support requested in creating a linear game experience (relatively lengthy)

Context & Goal

For a few months, I’ve been rolling around the idea of a multiplayer campaign game around in my head. I’m aware that the difficulty of creating campaign games is significantly higher and the market isn’t as swell as round-based games or what-have-you, but nonetheless this is something I want to pursue.

After looking at a few campaign/single-player/linear games, I noticed a common trend. Regardless of what coding approach they took, it seemed that:

  • There is a chunk of code dedicated to running the game’s story and such (mostly easy to accomplish)
  • There’s a separate thread that terminates this code if no one is alive, thus prompting the aforementioned code to re-run from the top (relatively difficult)

The Issue

I’m certain that I have everything I require to create a linear game experience. The only thing which I can’t wrap my head around is the core logic itself - the very thing that propels the game altogether. I’m able to create a linear script with little issues - enclose my game logic in a loop so that when it’s all over, it repeats itself. What I can’t grasp is how to terminate that in an instant if a condition is met, so the game can stop running and start back from the intermission or loading process.

I’ve examined several linear-based games (either in Roblox Studio or through continuous play-throughs). Some have ugly logic, but it works as far as anchoring game play to a time line goes. Some cannot, however, stop itself for conditions (i.e. pausing itself and then resuming only after a wave of enemies are cleared). At this point, I’m not so much concerned about how the coding should look as much as getting it to run with little to no errors, since no one will be seeing that code and fretting about my conventions is hampering productivity.

For the sake of brevity, I’ll keep my findings quick. A detailed analysis for these games is available in the post I linked under “Context & Goal”.

Game Core Logic Timeline Anchor Terminates on condition met Can wait until a condition is met Can begin at different points of game1
Boss Fighting Stages Unknown No Yes Yes Yes
Contamination Function, nested ifs, disables script2 Yes Yes (infrequent checks)3 No No
Contamination: The Epidemic Unknown Unknown Yes Unknown No
Escape Room Variables & Clickers No (time limit) Yes (teleport to lobby) Yes (interact w/ other items first) Yes (different maps, forcing variables)
Mission, The Forgotten City! Unknown No Yes Yes No
Reason 4 Life For Loop Yes Yes (checked every second) Not without halting entire loop No5
Undead Nation Variable4 No Yes Yes Yes6

Notes

1 Stopping at certain points isn’t necessary, but I figure that having to restart the whole game due to a failure might discourage continuation and tank playtime, whereas not doing so will keep people retrying.

2 Upon a check being met that flags the game to end, the function is stopped by a return value and it can’t move forward since the rest of the script under a nested if doesn’t have its condition met. When this happens, the script flips it’s disabled property on and off. This goes on permanently, so it’s like a pseudo-loop.

3 Due to these infrequent checks, the game continues running up until a check is performed. That means players are kept waiting if the story isn’t near a player check and that equals leaving the server.

4 Undead Nation works off of various events to determine its story - various values, bricks with Touched events, loops and conditions, so on. Despite all this, a game can end if there are no “surviving” players.

5 Between a no and a yes. Since the code here is set to run for 5 minutes anchored (for i = 1, 1800 do), setting i would effectively allow a skip to a certain placement in the story. I find this a bit hacky but there might be something to be worked out based on this. Even then, I don’t want to rely on hacky methods to accomplish my goal. If i can’t be manipulated, it remains a solid no.

6 Specifically because this game doesn’t have any anchored logic, anything can be done here. Essentially, what Undead Nation does is start a game, reset things back to the lobby if no one is alive and leaves it there. It doesn’t advance any story or anything. The map controls how the game is played, the only anchored logic is sending players over to the map and starting a session if no one’s on the map.


Why?

I’m sure someone has questioned what my business is in trying to develop for a dead market with little hope of thriving and why I’ve put so much effort to wring an answer out of someone. The answer is simple and comes in two parts.

The first reason - personal endeavour.

The first is that it’s my desire to pursue the creation of a linear game. I personally think that amidst all the technical and financial hardships this may bring, it’s personally easier for me.

If I learn how to make one linear game, I can learn how to make many. I can also finally finish a project since most of my stuff is dead, too ambitious or I lose motivation. A campaign game allows me to add chapters or pieces whenever I want and the game plays out - just like games with maps and game modes.

There’s also a lack of campaign games around Roblox and I think that making one that garners some interest will motivate me to pursue other types of games and whatnot. Furthermore, the fact that I could complete something I’ve been working towards would be satisfying and assure me that my programming pursuit isn’t in vain.

The second reason - it can form a bigger game.

Imagine being able to start up a campaign mode alongside your current multiplayer experience. Then you have people who may want to flock to the campaign with others or by themselves to explore some of the game’s lore or try something new, while other players hanker down to the multiplayer modes. Imagine Phantom Forces with a campaign mode, for example.

Campaign: Country A versus Country B and you’re part of an elite operations unit. You’re sent to infiltrate a base - furthermore the enemy country - to disrupt their operations, so yours can hold victory.
I didn’t think of that, I was making a reference to something.
Multiplayer: Your casual ranked matches with leveling and access to weapons - the PF multiplayer team-based FPS you know (and love).


In the end, this is something I’d really like to pursue. I don’t know whether I’m thinking too deeply about this or whether it’s the real challenge I heard it to be, but I know I want to accomplish this eventually.

I welcome any help to point me in the right direction for creating a linear game. At basic, I’d like to accomplish a linear experience which runs a story but can be ended and restarted if no one’s alive, but I also welcome any additional fine points to enhance the experience:

  • Being able to halt the story until conditions are met and then allowing the story to continue after (i.e. clearing a wave of enemies); the game still has to be able to end before, after and during these condition buffers
  • Being able to split up the game so that it can start at different checkpoints. This can either be splitting my game into multiple places, or splitting up the script, or whatever.
  • Where anchoring the story to a timeline is good and when it is not, or whether it should be done at all ideally in the endgame

Thanks for any help in advance. I truly appreciate pointers in the right direction.


tl;dr how to make a linear campaign game

3 Likes

Pretty broad question, and you’ll probably be horrified to find your answer is “try it yourself.” There’s no “right” way for sure.

Often things like these are kinda hard to give an answer to. I think in this scenario this is something you want to do yourself because there isn’t a good answer. Don’t be afraid of trying (talking isn’t going to do anything, after all). If your first version is bad, iterate on it and make it better. That’s what prototypes are good for, among other things.

As for some ideas in implementation you might not have thought of:

  • put each encounter’s data in a ModuleScript
  • also make each type of encounter in a ModuleScript so you can avoid duplicate code
  • use coroutines to handle stopping or pausing some sort of event (coroutines are quite limited so if this is even possible, you’ll need to use more than the built in functionality)
  • use a “global” module that means you can check stuff using the same function (e.g. player count)
  • use this global module to handle things like pausing the game in the code for the events themselves so you don’t need to take on the possibly-impossible task of handling it all in a big controller script

Mind you, I don’t have much experience with this thing specifically so maybe someone with experience could help you further.

2 Likes

Horrifying indeed, but nonetheless helpful. It reminded me of coroutines, which I assume will be very helpful throughout this experimentation process.

I’ll toy around with these ideas.

1 Like

Yeah, I was going to suggest coroutines but after some thought I couldn’t figure out how to make a good system. The primary issue in my knowledge is that coroutine.yield() can’t be used on a thread outside of that thread.

1 Like

Sorry for the bump, but I believe that I have found a solution to this at long last. I normally don’t like pestering people and it already bothers me to ping people, but I feel that overall it was worth it to reach out to someone who has created a linear game before.

So essentially, with a combination of both EmeraldSlash and Nitefal’s input (DM), I’ve devised an experiment of sorts that I wish to apply.

I will be having a primary controller that will take charge of handling the game, while outside scripts influence the control script to take on different actions. Each section of the game will be handled in a different manner.

It’s a bit hard to explain since I have multiple models going on, but I greatly appreciate the help that’s been provided to me thus far in both my campaign development threads. I’ll see how this goes, sometime.