Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Lewis on Mon 19/11/2012 11:59:56

Title: Multiple endings based on certain criteria
Post by: Lewis on Mon 19/11/2012 11:59:56
Hi. Right. I've been trying to wrap my head around this, and have had a few ideas, but I'm looking for the best way to create multiple endings that trigger based on set criteria.

Let's say I've got four endings.

Ending one is triggered by having collected Item 1, given Item 2 to Character A, and not found Item 3 at all.
Ending two is triggered by having collected Items 1 and 2 but not having given either to Character A, and not found Item 3 at all.
Ending three is triggered by having collected Items 1, 2 and 3, but only given Item 2 to Character A.
Ending four is triggered by having collected all three items, and having given Items 2 and 3 to Character A.

Obviously I get that things just have to branch at a certain point, but it's how to check these criteria that I'm struggling to wrap my head around. Any help would be hugely appreciated.

Thanks!
Title: Re: Multiple endings based on certain criteria
Post by: Slasher on Mon 19/11/2012 12:27:51
To check throughout the game do the check in the Global (repeatedly_execute function) and check if variables/conditions are met or are true etc and if so 'Do this'or 'Do that' etc etc



Title: Re: Multiple endings based on certain criteria
Post by: selmiak on Mon 19/11/2012 12:51:21
use global variables. Either use bools and set them when your character picks up the item and/or gives it away like hasfound1 = true; given1 = true; etc. and then check with a condition for these variables. It is useful to write down a small table of all possible combinations, write conditions for the useful ones and use else for all other conditions.
Or use a simple integer variable for each item, like item1use and have it start with the value 0, so this means not found, when found set the value to 1, when given set the value to 2 and check this in a condition when needed. For this you need less variables, but maybe you have to write more confusing code for you as the variables in the condition are not 'speaking' and thus harder to reread...
Title: Re: Multiple endings based on certain criteria
Post by: Lewis on Mon 19/11/2012 14:40:46
Hey guys,

Thanks for that. Yeah, just wanted to check I was going about it the right way, really. The depth of logic was making my head spin a bit.

Just provisionally scripted the ending selector bit. Obviously this doesn't have some of the bits of code in yet, and instead have comments, but from first glance can anyone see any reason why this wouldn't work?

Code (AGS) Select
//+1 to Letters_Collected each time a letter is collected.
//Before ending, call the following:

if (Letters_Collected == 9) {
Ending_Collection=1;
}
else {
Ending_Collection=0;
}

//Then, call the following to select the right ending:


if (Ending_Collection == 1) {
if (gun_loaded == 1) {
if (toy_car == 0) {
//Start Ending 4
}
else if (toy_car == 1) {
//Start Ending 2
}
else if (toy_car == 2) {
//Start Ending 1
}
}
else if (gun_loaded == 0) {
if (toy_car == 0) {
//Start Ending 3
}
else if (toy_car == 1) {
//Start Ending 3
}
else if (toy_car == 2) {
//Start Ending 3
}
}
else if (Ending_Collection == 0) {
if (gun_loaded == 1) {
//Start Ending 3
}
else if (gun_loaded == 0) {
//Start Ending 5
}
}
Title: Re: Multiple endings based on certain criteria
Post by: geork on Mon 19/11/2012 19:15:45
It looks like it would work, but it may help to simplify a bit:

Firstly, having:
Code (AGS) Select
if (Letters_Collected == 9) {
        Ending_Collection=1;
                }
else {
        Ending_Collection=0;
                }
//then:
if (Ending_Collection == 1) {
    //endings
}
else if (Ending_Collection == 0){
    //endings
}

is essentially the same as:
Code (AGS) Select
if (Letters_Collected == 9) {
    //endings
}
else {
    //endings
}

Unless the variable Ending_Collection is affected by other code, which it doesn't seem to be. You can 'cut out the middle man' entirely (I know it has a family...but shh, efficiency calls :P)

Secondly, if you find yourself having multiple conditions which result in the same thing, it's good to find a way to combine all of them into one statement. For example:
Code (AGS) Select
else if (gun_loaded == 0) {
                if (toy_car == 0) {
                        //Start Ending 3
                                }
                else if (toy_car == 1) {
                        //Start Ending 3
                                }
                else if (toy_car == 2) {
                        //Start Ending 3
                                }
                        }

All three conditions lead to the same ending. You know that if the value of toy_car is greater or equal to 0 and less than or equal to 2, then ending 3 will play. So you could condense the line into:
Code (AGS) Select
else if (gun_loaded == 0 && toy_car >= 0 && toy_car <= 2) {
    //Start Ending 3
}

Although seeing as the value of toy_car seems to be either 0, 1 or 2, you can skip that entirely and put:
Code (AGS) Select
else if (gun_loaded == 0) {
    //Start Ending 3
}

And, as gun_loaded can EITHER be 0, OR 1 (from the impression I have), then as you have already tested to see if it's 1, you don't have to test again to see if it's 0:
Code (AGS) Select
if (gun_loaded == 1){
    //Either ending 4, 2 or 1
}
else{ //you don't have to test whether it's 0, as it can only be so if it isn't 1...
    //Ending 3
}


Also on a quick note: if something is only ever either 1 or 0, it's good practice to turn it into a boolean variable

So simplified, disregarding the bit about booleans, the code could look something like:
Code (AGS) Select
if (Letters_Collected == 9) {
    if(gun_loaded == 1){
        if(toy_car == 0){
            //Ending 4
        }
        else if(toy_car == 1){
            //Ending 2
        }
        else{ //You don't need the condition - if it's not 0 or 1, then it's 2, so you only need to put 'else'
            //Ending 1
        }
    else{ //again, if gun_loaded is not 1, then this clause executes anyway, so only put 'else'
    //Start Ending 3
    }
}
else {
   if (gun_loaded == 1) {
      //Start Ending 3
   }
   else if (gun_loaded == 0) {
      //Start Ending 5
   }
}

I've shifted the bracketing in terms of indentation a little - it doesn't really make any difference however (I just find it clearer that way)

Hopefully this'll simplify the depth of logic a little :) You can always check which bracket belongs to what under 'edit -> match brace' (or Ctrl-B)
Title: Re: Multiple endings based on certain criteria
Post by: Lewis on Tue 20/11/2012 08:07:51
Incredible!