whats up guys, i just want to know how the devs controls the Story of their games
by story i mean the events of the game, what happened, what happening, what will happpen
There are multiple ways and it depends on the scale of your game as well as what you plan on doing. So really to even answer this question you have to be more specific. Are you talking about things like dialogue trees and dialogue choices? Or keeping track of things like perks etc. that you can get after you make specific choices or side with factions?
im talking about dialogues, tasks and cutscenes
for example; in order for a certain cutscene to run, the player has to meet some requirements, such as collecting an item and talking to a certain NPC to release a cutscene that will only pass once, releasing other parts of the story, I see a lot in horror or sandbox games
![]()
In that case simple integers and booleans would work fine believe it or not, it’s just a matter of using some sensible naming conventions and having your code react when the player changes them in runtime. So for example if you were to keep track of a key you would have a “IsRoom106KeyPickedUp” boolean and because it would be something of a quest item you wouldn’t even need to deal with any inventory stuff unless you have a reason for that. If the boolean is true, then have a door elsewhere suddenly become unlockable as you go near it with a raycast when you press E for example.
I think people at times even perhaps veteran programmers underestimate how powerful booleans and integers are if you know how to use them properly. I take a lot of inspiration from Fallout 2 and how they seem to deal with integers in their game, they use them to keep track of perks, faction reputation and so on. It also makes life a lot easier keeping track of everything as your project grows in size, I regularly make use of tons of integers and booleans in my own project to keep track of player ownership of villages.
I take your point but in 2022 I think far more people underestimate how powerful strings are.
The limiting cost in game development is often your own ability to debug what you have created.
If I have a big old world with a bunch of cities, and one particular city Esgaroth has a bunch of main story quest lines, I would WAY rather see the dialog config and save data have the word “Esgaroth” in there instead of having to remember that Esgaroth is 37.
The only major drawback of strings is typos. This is easily addressed in code. Here’s three possible ways:
Method 1: make ScriptableObjects representing each city.
using UnityEngine;
[CreateAssetMenu]
public class CityName : ScriptableObject { }
and then just create disk assets for each one, and use the name of the file directly.
Method 2: use const strings
public static class CityName
{
public const string Esgaroth = "Esgaroth";
public const string Rivendell = "Rivendell";
}
Method 3: use enums and .ToString() them:
public enum CityName
{
Esgaroth,
Rivendell,
// etc.
}
The last method is the LEAST desirable, because you must also consider this if you directly serialize the enum (eg, not doing a .ToString() on it):
Enums are bad in Unity3D if you intend them to be serialized:
https://discussions.unity.com/t/809088/4
https://discussions.unity.com/t/817068/2
It is much better to use ScriptableObjects for many enumerative uses. You can even define additional associated data with each one of them, and drag them into other parts of your game (scenes, prefabs, other ScriptableObjects) however you like. References remain rock solid even if you rename them, reorder them, reorganize them, etc. They are always connected via the meta file GUID.
Yep, strings too for sure, I do need to see if I can find more information on this sort of thing because of how many changes are happening in the way engines work now because I do get the argument about strings which is something I’ve brought up in previous threads on this sort of topic regarding optimisation. What was considered bad practice only 5 years ago is now considered totally normal and acceptable now and it’s something I’ve been having to learn a lot with 3D modelling for example.
I dunno about that 5 year thing… all the kool kids have been using strings a lot longer than that!
Are you aware that Quake used strings for almost all semantically-relevant data flows internally as far back as the early 1990s?
Here’s the Quake commands:
https://github.com/id-Software/Quake/blob/master/QW/cmds.txt
Here’s some of the internal Quake “cvars” used to configure the game:
cvar_t cl_upspeed = {"cl_upspeed","200"};
cvar_t cl_forwardspeed = {"cl_forwardspeed","200", true};
cvar_t cl_backspeed = {"cl_backspeed","200", true};
cvar_t cl_sidespeed = {"cl_sidespeed","350"};
cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"};
cvar_t cl_yawspeed = {"cl_yawspeed","140"};
cvar_t cl_pitchspeed = {"cl_pitchspeed","150"};
cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5"};
If it’s good enough for Quake… ![]()
The reality is, processing a few strings every frame is never even going to show up on your profiler charts. The CPU can handle that stuff without even breaking a sweat.
As always:
- implement
- profile
- optimize
starting by the easiest implementation first, don’t complicate stuff early