Randomness


#1

I’ve read the warning that random factors can make testing more difficult, but I’m honestly not a very great fan of simple yes-or-no outcomes, along the lines of:

If stat X > value Y
You succeed.
else
You Fail.

What I’d like to know is if anyone has managed to come up with a solution using Choicescript to allow a random element, so that chance plays more of a part at crucial times (as it does in real life).

The ideal solution for my purposes would be to still allow a chance of failure the closer Stat X is to Value Y, even though X is greater than Y and would normally be an automatic success, and likewise still a chance of success even when Stat X is lower than Value Y and would normally be an automatic failure.

Any help with a possible “scaled” solution along these lines would be greatly appreciated.


#2

I’ve managed to do that in my game. Nine choices where the correct outcome is different every time and only 1 of them is correct. Sometimes the player will get it right first time, sometimes they will go through all 9 options. And I didn’t use any random elements at all! Sound good?

Well, it is actually a little too good to be true. The player definitely has the appearance of randomness and the outcome IS different on repeat plays, but it’s not actually random at all.

In my game, The Race, there is one stage where you need to choose one of 9 places to go to to continue the game. The correct outcome is different every time and very much has the feeling of randomness (if you’re lucky, you can get the right place straight away, if not, you could end up going to every location). However, I achieved this without using any random factors.

The secret was I used a timer. The truth is the outcome was predetermined by the players luck variable. Here’s the code so you can see… it’s long and probably not the most efficient way, but it works:

*comment The variable luckybird is always set to 1. The variable luckynumber is set depending on the players luck score. The l1 to l9 variables are used to stop the player choosing the same option repeatedly. After an option is selected, the corresponding l-variable is set to false.
*comment The line variable is simply used to change the location name that the player has gone to.

*temp luckybird
*temp luckynumber
*temp line
*temp l1
*temp l2
*temp l3
*temp l4
*temp l5
*temp l6
*temp l7
*temp l8
*temp l9
*set l1 true
*set l2 true
*set l3 true
*set l4 true
*set l5 true
*set l6 true
*set l7 true
*set l8 true
*set l9 true
*set luckybird 1

*comment This part sets the luckynumber variable. the higher the players luck, the lower the luckynumber is.

*if luck < 20
*set luckynumber 9
*goto taskbegin
*elseif luck < 25
*set luckynumber 7
*goto taskbegin
*else
*if luck < 30
*set luckynumber 6
*goto taskbegin
*elseif luck < 35
*set luckynumber 5
*goto taskbegin
*else
*if luck < 40
*set luckynumber 4
*goto taskbegin
*elseif luck <50
*set luckynumber 3
*goto taskbegin
*else
*set luckynumber 2
*goto taskbegin

*page_break

*comment This is text the player will see. They will initially have 9 choices of location to go to.

*label taskbegin
Your task is to find the clue which will tell you where to go next. You have a map showing 9 different objects which were created by the Nazca civilization over 1500 years ago.
One of them has been temporarily altered somehow. You need to find the correct one.
The nine choices are listed below. Which one will you instruct the pilot to fly to first?

*comment The code below shows the nine choices the player can go to. The choice the player makes is actually irrelevant. What is really being checked is the luckybird number. If the luckybird variable is the same as the players luckynumber variable, then the player has gone to the right place. If not, then it must be lower (as luckybird starts at 1 and luckynumber starts at a minimum of 2) so the player has to choose another place to go to, and the luckybird number is increased by 1. Every time the player chooses a location, the number increases by 1. Once they match, REGARDLESS of where the player has gone to, the player has ‘picked’ the right place and can progress in the story.

*label choiceoflines
*if luckybird > 1
You decide to fly to one of the other lines. Which one will you fly to now?
*goto linechoice
*else
*label linechoice
*choice
*selectable_if (l1) #The Dog
*Set line “Dog”
*set time +25
*if luckybird<luckynumber
You inspect the {line}, but can't see anything unusual about it. \*set luckybird +1 \*set l1 false \*goto choiceoflines \*else \*goto luckytime \*selectable_if (l2) #The Humming Bird \*Set line "Humming Bird" \*set time +15 \*if luckybird<luckynumber You inspect the {line}, a beautiful picture that must have been difficult to create from the ground. However, there’s no clue here.
*set luckybird +1
*set l2 false
*goto choiceoflines
*else
*goto luckytime
*selectable_if (l3) #The Heron
*Set line “Heron”
*set time +25
*if luckybird<luckynumber
You look at the {line}, but as you fly over, you see nothing unusual about it. \*set luckybird +1 \*set l3 false \*goto choiceoflines \*else \*goto luckytime \*selectable_if (l4) #The Giant \*Set line "Giant" \*set time +30 \*if luckybird<luckynumber You inspect the {line}, which looks more like an astronaut to you. However, aside from the odd name, there is nothing else unusual about it.
*set luckybird +1
*set l4 false
*goto choiceoflines
*else
*goto luckytime
*selectable_if (l5) #The Hands
*Set line “Hands”
*set time +35
*if luckybird<luckynumber
You inspect the {line}, which look more like a potted plant on it's side. However, you can't see anything unusual about it. \*set luckybird +1 \*set l5 false \*goto choiceoflines \*else \*goto luckytime \*selectable_if (l6) #The Pelican \*Set line "Pelican" \*set time +25 \*if luckybird<luckynumber You fly over the {line}, however you can see nothing unusual about it.
*set luckybird +1
*set l6 false
*goto choiceoflines
*else
*goto luckytime
*selectable_if (l7) #The Spider
*Set line “Spider”
*set time +20
*if luckybird<luckynumber
You inspect the {line}, and while it does indeed resemble a {line}, you can see nothing unusual about it.
*set luckybird +1
*set l7 false
*goto choiceoflines
*else
*goto luckytime
*selectable_if (l8) #The Condor
*Set line “Condor”
*set time +15
*if luckybird<luckynumber
You inspect the {line}, the largest of all the Nazca lines. Unfortunately, despite the size, you can see nothing else unusual about it. \*set luckybird +1 \*set l8 false \*goto choiceoflines \*else \*goto luckytime \*selectable_if (l9) #The Monkey \*Set line "Monkey" \*set time +20 \*if luckybird<luckynumber You inspect the {line}, which does actually look like a ${line} with it’s tail wrapped into a spiral. However, you can’t see anything else unusual about it.
*set luckybird +1
*set l9 false
*goto choiceoflines
*else
*goto luckytime

The good thing about this code is that every time the player plays, the outcome (lucky or not) reflects the players luck score in the game. Also, the outcome is different every time, so the player feels they really are guessing which place is the right place. The only downside is once you know how it’s coded (as I’ve just outlined here) you realise that it doesn’t matter where you click - you’ll get the right option after x tries regardless. Of course, the player will never know this secret :wink:


#3

Very creative, and doubtless gives the player exactly the impression you were hoping to achieve–nicely done!

As you say, it doesn’t exactly resolve my own problem but it certainly provides food for thought, as I can see situations in my planned storyline where something similar to this might be very useful. Thanks for sharing. :slight_smile:


#4

Hmmm… I’ve been thinking. Why not have a timer ticking up from 1 at every choice in the game. Once the player gets to the point where you want the randomness to come in, there is a check. If the timer is close or exact to a predetermined ‘lucky’ number, then the player gets a good outcome. If the timer is too far off, they are unlucky. Depending on how the player plays your game, the timer will increase at a different rate, so should be different every time they play.


#5

Well the way I’m going to be working on it (in Aeon Sage), there is going to be a Normal Mode (works the same way as most CoG games where if X>=Y, succeed, else fail), but there is also a Hard Mode. (The difference being controlled by a variable hardmode, set to either true or false.

Now, there are multiple different ways to utilize this. The easiest is the most obvious, just a straight random roll: Let’s take for example, the PC trying to flirt with someone. This would be based on both the Charisma stat. Let’s say we want a difficulty of 80 (it’s a particularly snobbish person the PC is trying to seduce). From there, we decide how much ‘randomization’ we want, in the form of what we want the maximum and minimum difficulty to be. Let’s say that seducing this woman is not important, so we want it to sometimes be impossible, but not too often. For that we want a max difficulty of 105, so we have it randomly add up to 25 to the difficulty. Lets also say that we want to keep the average difficulty at 80, so we have it also randomly subtract up to 25. The code would look something like this:*temp difficulty *set difficulty 80 *if hardmode *temp die_roll *rand die_roll 1 25 *set difficulty + die_roll *rand die_roll 1 25 *set difficulty - die_roll
Note the use of the hardmode variable above.
Then, when you want to check success or failure, you just use:*if charisma > difficulty *goto SUCCESS *else *goto FAILURE
One great boon to this is that you can (subtly) inform the player of how difficult the roll will be before hand too, with a simple, ‘*if difficulty <>=’ changing the way the scene plays out (in our example, making the woman significantly more snobbish as the difficulty goes up).


#6

Hehe–a deceptively simple solution after all, even to my inexperienced (and somewhat illogical) brain. Brilliant! It’s exactly what I was looking for and can be adapted to suit my needs perfectly. Thanks for that. :slight_smile:

As to the reason why a solution such as this was so high on my list of priorities (for the curious out there), it’s to do with replay value. As an example, there are various topics here revealing snippets of precise solutions: “How did you achieve that?” “Well, I did A, B, C, D, followed by X, Y, Z.”

For instance, I shot through ‘Choice of Broadsides’ in fine form on my very first attempt, simply because of some tips I vaguely remembered reading in these forums… (e.g. have them clean the ship first).

But it’s not just about inadvertantly reading spoilers. When replaying many of these games the precise solution becomes ingrained. If you always do A, B, C, D . . . X, Y, Z you will (almost) always get to the exact same point as before, with the exact same stats. But life sure as hell doesn’t work like that, so why should a game?

This type of random luck element, used correctly, means you can never be truly certain that the exact same choices will always end in the exact same way-- just like in real life.


#7

I agree it’s unfortunate that “deterministic” games allow for lawnmowering through all the possibilities, and for forum spoilers and walkthroughs. But randomness might break the game the other way.

Yes, life seems random. But in fiction, we streamline things. We don’t describe the boring parts, each action to eating cereal. Readers need to feel events are related and causal, or the “story” is just a laundry list of events. “The queen died. The king died,” isn’t a story, but “The queen died, and then the kind died of grief,” is, a the classic example goes.

There is good randomness, and bad randomness. Games back in the 70s and 80s would do stuff like “if you go through the left door, 50/50 the gnome kills you.” Obviously bad. You’re talking about chances weighted by variables, but still – if I’m playing through a romance for the fifth time and want to get the “Susan ending,” investing 45 minutes to have all my work destroyed by a roll of the virtual dice is NOT going to be satisfying.

Some kinds of good randomness:

  1. Atmosphere. A lot of interactive fiction (as in Zork and modern freeware titles) use random mini-events to make locations seem alive. In a forest, birds might fly by on one turn, a fox my scamper across the trail the next, a breeze pick up the next, all randomized. You could even make non-crucial side-quests available randomly, something rare that would be a cool discovery (with forum bragging rights).

  2. Multiple attempts. Most adventure games have a lot of randomness in combat. You attack, but have a chance of doing 3 to 9 points of damage, and weighted chances of missing, getting a critical, the enemy dodging, etc. But this works because in combat you’re taking a lot of swings at a lot of enemies, and even if you are unlucky, you still can make up for it by managing healing items, special attacks, etc. You’re making interesting game decisions to deal with the randomness. And the randomness evens out over play, just as poker really only works if you play many hands. In general, if you have more powerful weapons, you’ll eventually succeed. Instead of combat, why not a similar mechanism for convincing someone, hacking a computer, managing a store, etc.

  3. Harvesting resources/loot. Studies show that people and animals engage in a behavior more frequently if the rewards are random instead of constant. Hence, slot machines and loot drops in World of Warcraft. Also, getting a varied amount of resources for your effort may require the player to reshape their plans inside a time constraint, etc. Again, this isn’t limited to loot, it could be applied to relationship scores, iron ore, etc.

  4. Bidding resources. You and your 20 men need to defend the launch area and shuttle for another three days before the mothership comes. But you also need to retrieve the surveillance data canisters you came here for in the first place. And you’re running out of food. How many men do you send, how many stay? If the dangers are randomized, then risk is involved. You have to overbid if you want to be sure something will happen. You may have to sacrifice. When the mothership arrives, you could get more platinum bars aboard if you jettisoned some shuttle fuel, but drop too much fuel, and you’ll all crash. But, with too little platinum, later on you might not be able to offer a respectable bribe to the corrupt port officials in Terronia…

  5. Echo Bazaar (http://echobazaar.failbettergames.com/) does randomness interestingly. You’re only allowed a certain amount of actions per hour. You have four stats which you build up by attempting certain actions. For most actions, even if you fail, it builds up the related stat, so that next time you try it, you have a better chance at success. Some actions, though, have a penalty if you fail – you lose money, or lose the chance to pursue that storyline until it pops up randomly later, or your stats get knocked back and have to be rebuilt. So, in attempting these “serious” actions, you want to make sure your stats are high enough for success, but you want don’t want to spend all day building up stats, and not have time for anything else. So, you often get your stats pretty high, and risk it. And maybe buy an item that allows you a do-over if you fail.

Anyway, games that kill your plan randomly are unsatisfying. But randomness can be used to shape the player’s strategy and play style.


#8

An excellent analysis of the subject (and some very good tips, too! Hehe). I think you’ve hit the nail on the head perfectly, especially as regards breaking the game by using randomness in the wrong place, or for the wrong reason. Achieving the right balance will be important, but is probably much easier said than done.

My personal preference would be to use more ‘luck’ in sub-plots, unimportant to the main storyline (or the main endings) but able to assist with those in some way if successful. Done properly it needn’t be a game breaker at all, just a way of offering interesting diversions along the way and potentially different ones each time you play.


#9

Further on the general subject of ‘Randomness’ in a ChoiceScript game -

Very early in the story I am planning to have a number of small subplots (probably be 5-6), each of which puts the player in a particular situation where the choices made will result in significant stats changes (the basic stats are determined by an early choice of character background). However, I would very much like to avoid having them always be encountered in the exact same order with each replay. Ideally, the order would be completely random, but in such a way that all are still encountered, none skipped, and none repeated–after which the player continues on with the main storyline.

How would you script this?


#10

Firstly, my way which is usually the brute force method, and is certainly not the most effective. I’ll be using 4 scenes for an example, but the numbers can be raised as high as you want. I’ll also be calling the scenes red, blue, green and yellow for ease.

First, in mygame.js:
red_scene_complete: false
blue_scene_complete: false
green_scene_complete: false
yellow_scene_complete: false

In the game:`
*label random_scene_selector
*if ((((red_scene_complete) and blue_scene_complete) and green_scene_complete) and yellow_scene_complete)
*goto mini_scenes_completed
*temp die_roll
*rand die_roll 1 4
*if die_roll = 1
*if red_scene_complete
*goto random_scene_selector
*goto red
*if die_roll = 2
*if blue_scene_complete
*goto random_scene_selector
*goto blue
*if die_roll = 3
*if green_scene_complete
*goto random_scene_selector
*goto green
*if die_roll = 4
*if yellow_scene_complete
*goto random_scene_selector
*goto yellow

*label red/blue/green/yellow
*set COLOR_scene_complete true
SCENE (You’re going to need one of these for each scene.)
*goto random_scene_selector

*label mini_scenes_completed
This is what will appear after all the scenes are done.`

Now, this can easily be improved by changing the way it randomizes die_roll so that scenes that have already been selected are less likely to be rolled again, but this is a working method at the least.


#11

Thanks for that. Together with some other suggestions I’ve managed to combine the two and expand on the basic idea of what I was trying to achieve, so it’s a little less obvious than it would’ve been. Whether or not it actually adds anything to replay value, only time will tell, but it was worth a shot. :slight_smile:


#12

I am about to attempt an rpg game using CoS engine. Problem is, I am going to need to use *rand a lot for damage player and monster do, I can’t just set static damage or else it will be too predictable and rpg element will be just window dress and no actually important, yet from what I heard about *rand it should be use last.

So I am here to ask, any alternative?