Hi everyone!
I’m attempting to create a Story-line system that tracks the players progress through the story, aswell as unlocking new areas & involving cutscenes etc.
I was thinking Modules would be a good idea to do so? Wondering if anyone else has any ideas. A perfect example of my idea is shown in PBB for those that remember it.
This would more likely come down to a list of check-points which, depending on the player’s save state (e.g., “Tutorial”) - would determine which part in the story line to load.
For example:
local checkpointState = "Tutorial"
if checkpointState == "Tutorial" then
-- Load the Tutorial section
-- Poisition the player at the tutorial spawn locaiton
-- etc...
elseif checkpointState == "Episode1" then
-- etc...
Granted its something I’ve never really looked into, and there’s probably way better methods for this sort of thing.
To be quite honest, I haven’t come across many games on Roblox that have a story line, so I’m very curious where you’re heading with this!
Keep us posted. =)
Modules would be a good way to create convenient repeatable functions for you to use to do your cutscenes and whatnot, but I think the best way would be some sort of variable to track progress.
Paper Mario TTYD uses a system called sequence, which a lot of other story games utilize.
Essentially it enables and disables different states in different areas (the LZ is a different phase for the same room/map I believe).
Depending on what the player does, you add more of a number to your sequence. It can be finicky, and definitely is the easiest for a more linear game. If you want something more like Super Mario Odyssey - sequence still works, but you’d instead tether the moon pickups to the sequence.
I like this idea, also liking the sequence concept too by @cloakedyoshi
How would I go about triggering these?
Ofc they’ll be Client based as the individual progresses through the story,
So the Core scripting being a LocalScript, where’s the best place for the modules? Was thinking a Subfolder containing them all etc. But was also thinking of inserting them inside of the Sequence Trigger Blocks, so if the Players current Sequence matches that of the touched block, it triggers it that way? Just thoughts.
I wouldn’t recommend you have this completely Client-based, especially if in this story, people have the ability to interact with others. This opens up the opportunity for exploiters to skip past through the story and mimick that they are much further ahead than they really are - which, if this is a multiplayer-centered game, may affect the rest of your playerbase.
I’m not saying don’t use LocalScripts at all, in fact, you should use it for the majority of handling the parts of the story; however, in terms of determining what current point you are in on the story, you should do this on the server.
Basically:
Client: Retrieve current level player is on from the server
Client: Play through this current story level until completed
Client: When completed, send this information back to the server
Server: Verify that the user has actually completed this part of the story, then bump up their level by one and return it back to the Client
If the Client hasn’t actually completed the level, the Server should just ignore it an the Client shouldn’t go to the next level.
Aside from this, for your modules which you plan on using, I (personally - up to you) would put them into a folder in ReplicatedStorage, so that both the Client and Server could access them, and then label it with the corresponding label of the Sequence Trigger Block. Yes, if you put them into the Trigger Block, they can still both access them - however, personally, I think its easier to have them grouped together so you can quickly edit them as you need to.
As for the exploiting issue, as you mentioned verifying with the server - Is there any way to implement this into the DataStore when I get onto that?
Because if the Player edits their sequence, it’ll only be visible on client - Through the Datastore would I be able to check if their Client sequence matches their Server sequence and if so, engage the save else fail?
I would store the player’s current level on the server, either by storing it in a dictionary:
players = {
[Player1.UserId] = 1 -- Currently on level one
}
or by using an IntValue or otherwise inside the player - if the player attempts to change it, it will only be visible on the client like you said.
Therefore, when it comes to moving up a level, I would say that the client should send the current level they think they are at too. If it doesn’t match the level stored on the server, ignore it, if it does, check if the level has actually been completed, then move up a level. - DONT purely rely on the client to tell you which level they are on, store it on the server yourself and check it.
And yes, you can definitely save this all into a Datastore. Using either of the ways I said above, or any other one you come up with, it will all be on the server - so it will be verified and safe to save.
This is the current layout of the Story-line sequences -
Adding the NumberVal helps as my game will depend on individual chunk loading along the players travels, and upon loading a new chunk if the isSequence Value is less than that of the Player’s then it’s automatically removed upon loading.