classes, functions, or ???

Pages: 123
Hi everyone,

I'm learning to apply a few principles by writing a text-based story game with choices and far-reaching consequences. So far, the minor details are going well. What I need to understand is constructing branches of the story: if you select option 1 from a dialog, that branch of the story will progress. if you select option 2, maybe it's a dead end and you revisit the same dialog. option 3 will visit a completely different branch or direction. I understand what to do in my head, just not how to apply it in c++.

I'm reading about classes, objects and functions, and as I understand it, classes (and consequently, objects) are not quite what I need.

in pseudocode for ease of conversation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

int main(){

cout << dialog 1

cout << question 1

cin << insert choice 1-4

switch
     case1: execute branch 1
     case2: execute branch 2
     case3: execute branch 3
     case4: execute branch 4

branch 1 {
     new part of story with prompts, 
     some logic and more choices to execute further branches}

branch 2 {
     a different part of story with prompts, 
     some logic and more choices to execute further branches}

etc etc etc


should these branches just be wrapped up in simple, separate functions executed by the main? or should I create a "branch" class and define the different sections or branches of the story as objects or methods of the branch class and execute them that way? Perhaps I'm missing something. What is the most effective way to handle a situation like this, or is there a best way?

Thanks for any help.
ideally, you would have a way to parameterize a small number of functions with different text and choices and paths.
so an object here sounds really good to me. This is a 'tree' structure of sorts that could help:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct state
{
    string outputspew{};
    vector<state*> nextstates;
    state* process(); 
   //perhaps this would cout outputspew, then read in a response, 
   //convert that response to an array index that is legal in nextstates, and then your 
  //game would progress to that state...
};

so it looks like this..
while(game engine loop)
{
currentstate = currentstate->process();
}

and you have an 'init' function that sets up all the states. This should come from a FILE so you can modify it, not the code, IMHO.

youll have to grow it to fit your game .. eg say you want to end the game win/lose/whatever end of game text state then you add that to the while loop so it stops running when they reach one of the ender states.

but the idea here is to have just a small amount of code that navigates the story which is stored in a file somewhere .. its just a navigation engine, in other words, without any knowledge of your story! Now, if you want long lasting consequences, you can STORE the choices at each state somewhere so you can refer back to them, that would get a little fancy but same idea still works. That would not belong in this object I described, but possibly an object that has-a thing like above + additional info that can be utilized in the game loop.
Last edited on
I think you're right about having a navigation engine that goes through preprogrammed situations based on choices made, like if you progress to a certain point, but did not pick up this particular object or solve an issue when you had the chance, or you made the wrong choice and broke a mechanism by putting in the wrong power source, those states could be stored in bools and used to determine further branching options down the line, e.g. if you broke a mechanism earlier in the story, now you'll try to do a pertinent task and, well, the object is broken so you have to find another way, or possibly you ultimately fail the game in the end.

It's certainly not as complex or sophisticated like rogue or dwarf fortress, but it's a good way for me to learn program control and flow.

I think I understand what you mean about storing different sections or branches in different files, and just using the main() to sort out when each file/branch is triggered, and to store choice and state information for the duration of the game? Or should all the branches/states be stored in one file under different names, and the main() is used to call the different sections of the story branch storage file under different states?
Last edited on
depends on how big it is, and to some extent your own design decisions. If you are playing and learning, NOW is the time to royally fubar your design and learn from it. NOTHING teaches as well as trying to push onward with a bad design :)

but if it were me, keep it simple, keep the story and branch info in a file you read once at the program start and setup the data structure from it. Then you just navigate the data structure. If you allow load/save of the game, that is a different file, for each saved game and the state it is currently in.

@OP
Your so-called pseudocode is not really pseudocode. Real pseudocode is meant to be written in such a way that it is completely devoid of jargon and meant to be understood by someone who has never even heard of a computer. The audience is assumed to be intelligent but definitely not mind-readers and not even remotely aware of C++ or any other computer language.

That aside, if you take a top-down approach and concentrate on the end-user instead of implementation details, it appears - to me at least - that primarily the story unfolds depending on what position in the story the user is at. Branches have no significance. From each position the end user is at, you define number of other positions the user can go to - including back where the user came from (possibly).

So, in terms of implementation but still top-down, if you take an object (class or struct would work) approach, there you have it! A game is a pile (array, vector, tree(??) ... blah blah) of Positions. A Position object called current_position would be one of them.

A Position object could be made up of an array of can_go_to[] Positions (references or indices ... blah blah) A Position would have a Menu method based on what's available via the can_go_to array.

A Position object would also have the relevant text for that part of the story.

You'll need Start and Exit Positions.
Real pseudocode is meant to be written in such a way that it is completely devoid of jargon and meant to be understood by someone who has never even heard of a computer. The audience is assumed to be intelligent but definitely not mind-readers and not even remotely aware of C++ or any other computer language.


I don't think that is necessary. You can write pseudocode on different levels of abstractions. What is most suitable depends on your audience.
@Mandaval - have you come across state machines yet? If not, you might like to spend a little time reading up on them. This is what @jonnin in the code above is getting to. Basically you have a set of defined states. Each state has a set of defined operations which can be chosen when any are completed define the next state - which can be the same state. if you go down the state route, then first you need to define the state machine. There's loads of info around on implementing one in c++.

https://gameprogrammingpatterns.com/state.html
https://www.codeproject.com/Articles/1087619/State-Machine-Design-in-Cplusplus-2
https://thatgamesguy.co.uk/articles/modular-finite-state-machine-in-unity/
I don't think that is necessary.
Well I do. Looking at your website Peter87 I can see why you aren't able to contribute constructively as I and other people have.
@OP
Your so-called pseudocode is not really pseudocode. Real pseudocode is meant to be written in such a way that it is completely devoid of jargon and meant to be understood by someone who has never even heard of a computer. The audience is assumed to be intelligent but definitely not mind-readers and not even remotely aware of C++ or any other computer language.


Understandable. But my audience, in this particular case, are very intelligent and also, more importantly, very aware of C++ and other computer languages. I’m not asking questions about C++ implementation to people that don’t understand C++, which is why I got a little more specific without dumping my entire code on the table.

That aside, if you take a top-down approach and concentrate on the end-user instead of implementation details, it appears - to me at least - that primarily the story unfolds depending on what position in the story the user is at. Branches have no significance. From each position the end user is at, you define number of other positions the user can go to - including back where the user came from (possibly).

So, in terms of implementation but still top-down, if you take an object (class or struct would work) approach, there you have it! A game is a pile (array, vector, tree(??) ... blah blah) of Positions. A Position object called current_position would be one of them.

A Position object could be made up of an array of can_go_to[] Positions (references or indices ... blah blah) A Position would have a Menu method based on what's available via the can_go_to array.

A Position object would also have the relevant text for that part of the story.

You'll need Start and Exit Positions.


There is no map in this game, it’s purely dialog driven with choice in how the story arcs provided by conversational cues. The “location” of the player is actually you, on your computer or phone wherever you are, talking to a guy in a distant location. But even so, his location doesn’t matter because it’s purely dialog driven, hence the need for “branches” of some sort to reflect the conversational decisions made. And that’s why I’m trying to figure out how best to construct the program.
Yes - FSM. The 'branches' are the transition between the current state/dialog and the next state/dialog. The 'story' is the order the states were visited.

Have you got a sample of the dialogues?

map or not, the same design works.
the dialog could be
you are in the middle of the forest. do you go south, north, or east?
...
it can be literally any query/response pair representing whatever you need at the time.
you can even have many stories on the same engine.

I was wary of saying FSM because those are usually unaware of any state besides the current. You are in a state, and events can drive you to a new state, but the previous is forgotten and the next is unknown. Its not much to modify it to fit, but if you go googling the technical term it will take you off into the weeds and be a distraction. But yes, its either a FSM or a simple/partial graph.
Last edited on
againtry wrote:
Well I do. Looking at your website Peter87 I can see why you aren't able to contribute constructively as I and other people have.

Not sure what my website has to do with it. I guess I could have used a few more words to explain what I meant but I didn't because I didn't want to distract too much from the real discussion going on.

It is a myth that pseudocode has to follow a certain format. There is no standard for writing pseudocode so how is saying that the OP didn't write "real pseudocode" constructive? All he meant was that it wasn't real code. Personally I don't think it would have made it any easier to understand if he had written it in a less C++-like syntax.
Last edited on
It is a myth that pseudocode has to follow a certain format.
Here we go, you are so bound up in your arrogance that you are now contradicting yourself and topping that with knowing what @OP meant.

You certainly have distracted. So far you’ve made stupid contradictions on at least 3 contributors and added nothing at all. Just like your dopey website ‘games’.
@Peter87,
you haven't been around for some time so you might not be aware that you try to reason with our forum troll. Probably some silly kid in puberty
hence the need for “branches” of some sort to reflect the conversational decisions made

All the above and the surrounding stuff is beginning to sound ‘Eliza’-type. Your lack of even a sample scenario is making this an even deeper XY problem.
Personally I don't think it would have made it any easier to understand if he had written it in a less C++-like syntax
And so the hole of arrogance gets deeper. Nobody here contributes on Peter terms.
in pseudocode for ease of conversation:
All he meant was that it wasn't real code.
Really?
@againtry You have 5 posts out of 6 that are not contributing to the original query as opposed to peter87’s one out of two.

I do have samples I can post, but not until I get home from work shortly as we don’t have internet on these machines. Would everyone like the full run that I have? It’s about 100 lines. Or I can make up some more (dare I say it) “pseudo-pseudocode” to just get the point across?
@Mandavel

3 of us have come up with more or less similar good faith and fairly comprehensive responses. My interest now is to see what @Peter87 has to offer seeing he knows more about what's on your mind than even you do. He's had his bitch about terminology so it's now wide open to let us all see his talents in action without further input from you.
Mandavel, your earlier use of psuedocode was understandable. Clear and concise for discussion.

Actual code would be helpful.

Pseudo-code, no matter how you "code it" could work, though not as well as an actual short, self-contained, correct compile-able example.
http://www.sscce.org/

You should draw up a diagram (a map) showing each dialogue and its options, the branches that lead off with each option.

This doesn't have to be a "Go North from outside the White House" puts you into a forest location type map. Talking about apples doesn't go down the "there's a bomb" branch.

A tree type pattern.
Pages: 123