Chance of Success

Perhaps this is covered elsewhere, but I have wasted a lot of time searching and have only found copy/paste code for specific combat systems. What I would like to know is how to make a simple check, governed by the roll of a (metaphorical) die; the result of which is compared to a numerical value that represents difficulty, (or anything else I need it to,) in order to determine if the action is successful. Attacking, Climbing, Swimming; these are the types of things I imagine using the check for, along with possibly determining whether a random event occurs or not. I want to understand how to make simple checks so that I have a foundation to work off of. From there I hope to be able to incorporate modifiers, such as those added by items or potions etc.


Io

Here's a basic dice roll, 1-20 inclusive, with success being 12 or more, with the player having the attribute GenericBonus, an integer attribute equal to 3. If the basic roll is 20, you get critical success.

Roll=GetRandomInt(1,20)
if(Roll=20){
//Critical success stuff goes here
}
else if(Roll+Player.GenericBonus>=12){
//Success stuff goes here
}
else{
//Failure stuff goes here
}

Add other features as need be.


The code above is a pretty good example for doing stuff with stats. But if you just want a fixed chance of success, you can use the RandomChance function, which rolls a 100-sided die and compares it to the target number you specify.

Example!

msg ("You only have a 17% chance of success at this task!")
if (RandomChance (17)) {
  msg ("But you make it!")
}
else {
  msg ("so nobody is surprised when you fail!")
}

Thank you! That helps a lot!


You can also simulate dice.

As an example,
player.dice = DiceRoll("1d4")
Would return a number between 1-4. It also works for simulating rolls one might make in a game based around your typical d20 rulesets, like;

player.dice = DiceRoll("3d6")

-- Which would be between 3 and 18. Because it simulates each dice, the weighing of the resulting number is far greater towards the middle results, with lower and higher results rarer.


there's 4 built-in Randomization Functions:

https://docs.textadventures.co.uk/quest/functions/corelibrary/diceroll.html
https://docs.textadventures.co.uk/quest/functions/corelibrary/randomchance.html
https://docs.textadventures.co.uk/quest/functions/getrandomint.html
https://docs.textadventures.co.uk/quest/functions/getrandomdouble.html

with the 'DiceRoll', you don't get to change the sides' values (always: starts at 1 for first side and increments by 1 for each additional side) directly, but you can have the rest of the expression, along with the 'DiceRoll' value, to produce the same effect as if the sides' values were different, as there's no limit to what you can do with the expression/equation/formula) itself, of course

integer_variable = DiceRoll ("1d6") // a normal die: 1 die with 6 sides (values: 1 to 6)

boolean_variable = RandomChance (75) // 75% of being 'true' // input bounds: 0 to 100  // (0% to 100%)

integer_variable = GetRandomInt (0,100) // randomly selects a (inclusive, I think) value of: 0 to 100

double_variable = GetRandomDouble () // randomly selects a (exclusive, I think) value of: 0.0 to 1.0

for a common example in RPGs, you can especially combine the 'GetRandomInt' and the 'RandomChance' for doing item drops:

// creating the items (Objects) for this example:

create ("candy")
create ("chocolate")
create ("honeyjar")
create ("cupofwishes")

// creating a new/blank Object List Variable VARIABLE and storing/adding the reference/pointer/address (the items/Objects aren't actually moved into the list: think of lists as a PE class' or a classroom's roll call list on paper of the students' names, but the students themselves physically aren't actually on or inside of the paper list, lol) of the items (Objects) into an Object List Variable VARIABLE:

item_objectlist_variable = NewObjectList ()

list add (item_objectlist_variable, candy)
list add (item_objectlist_variable, chocolate)
list add (item_objectlist_variable, honeyjar)
list add (item_objectlist_variable, cupofwishes)

// randomly selecting one of the items (Objects), using the Object List Data Type's features, and then creating a clone (Object) of it, and lastly, storing that cloned object into an Object Variable VARIABLE:

viable_integer_variable = GetRandomInt (0, ListCount (item_objectlist_variable) - 1)

cloned_item_object_variable = CloneObject (ObjectListItem (item_objectlist_variable, viable_integer_variable))

// randomly (based on the player's luck stat), decided whether they actually get that selected item or not:

boolean_variable = RandomChance (player.luck) // for this example, all stats (like 'luck') would have the bounds of: 0 to 100

// the actual handling of if they get the item, or not:

if (boolean_variable) {
  cloned_item_object_variable.parent = player // moves the cloned item object to the player's inventory (within the default 'player' Player Object)
  msg ("You got the randomly selected item: " + GetDisplayAlias (cloned_item_object_variable) + ", as a dropped item")
} else {
  destroy (cloned_item_object_variable.name) // due to the laziness/quickness/simpleness of my example, I have to deal with the clone not being used, meaning I need to destroy it, if I used a better example, this could be avoided (like not creating the clone if it's not going to be used in the first place, lol)
  msg ("You failed to get a dropped item")
}

the above example is a more complex example, but it should give you some ideas... on the various ways that you can use the 4 built-in Randomization Functions


but if you want more simple uses, some examples:

if (RandomChance (player.sneak)) {
  player.sneaking = true
} else {
  player.sneaking = false
}

------------------------------

create ("katana")

katana.damage = 50

player.weapon = katana

player.damage = player.weapon.damage + player.weapon.damage * GetRandomDouble ()

// hopefully using doubles with integers won't cause any errors, and instead truncation just occurs, but hopefully you do understand the issues/complexity of working with integers and doubles together: when/where does rounding occur, and what type of rounding occurs... preciseness gets complicated when using doubles and integers together... (also, doubles are much more operations internally than with integers, so, along with the rounding complications, in general, if you can, you want to avoid using doubles, unless you have to do so, and try to just use integers, as it usually just makes things easier for you, and also internally its more efficient/faster to use integers as they require less operations than do doubles, but it can be complicated in terms of the math in how to produce the same effect with just integers, than in just simply using doubles, and/or doubles with integers, lol. Basically, it really depends on your skill/knowledge in math, lol. I hate math... laughs)

// or:

player.damage = player.weapon.damage + DiceRoll ("3d12") // the dice roll would add: +3 (3 dice x 1 value) to +36 (3 dice x 12 value) damage

// or:

player.damage = player.weapon.damage + player.weapon.damage * player.strength / 100

// just like math, you can use parenthesis to force priority, but it should (I hope) work correctly, as multiplication and division has higher priority over addition and subtraction, but you can always add in parenthesis regardless if you want to do so:

player.damage = player.weapon.damage + (player.weapon.damage * (player.strength / 100))

// but, when you need to do so, you need to do so, for example:

x = 4 * (2 + 6)
x = 4 * (8)
x = 32

// is very different from:

x = 4 * 2 + 6 // x = (4 * 2) + 6
x = 8 + 6 // x = (8) + 6
x = 14

// so, when it matters in what you want, make sure your parenthesis are correct, lol

----------

player.strength = player.strength + GetRandomInt (1,5) // +1 to +5 strength increase

-----------

if (RandomChance (GetRandomInt (0,100))) {
  // true/success, do whatever scripting
} else {
  // false/failure, do whatever scripting
}

I prefer to do it this way.

roll = GetRandomInt(1, 20)
if (roll > 15) {
  msg ("You got a critical hit!")
  this.hipoints = this.hitpoints - 10
}
else if (roll > 5) {
  msg ("You hit it!")
  this.hitpoints = this.hitpoints - 5
}
else{
  msg ("You missed.")
}

I prefer...

chance = 55
if (player.variable="variablehere") {
  chance = chance + 15
}
switch (player.variable) {
  case (2,3) {
    chance = chance + 3
  }
  case (4,5,6) {
    chance = chance + 6
  }
  case (7,8,9,10) {
    chance = chance + 9
  }
}
if (game.variable=True) {
  chance = chance - 30
}
if (RandomChance(chance)) {
  // success.
  ClearScreen
  msg ("<br/>")
}
else {
  // failure
  ClearScreen
  msg ("<br/>")
}

Something like this?

roll = GetRandomInt(1, 20) + GetInt(weapon, attackatt) - target.defence
if (HasInt(weapon, damageatt)) {
  damage = GetInt(weapon, damageatt)
}
else {
  damage = DiceRoll(GetString(weapon, damageatt))
}
damage = damage * (100 - target.armour) / 100
if (damage < 1) {
  damage = 1
}
if (roll > 15) {
  damage = damage * 3
  msg (CapFirst(attacker.alias) + " attack " + target.alias + " and get a critical (" + damage + " hits)!")
  target.hitpoints = target.hitpoints - damage
}
else if (roll > 5) {
  msg (CapFirst(attacker.alias) + " attack " + target.alias + " and hit (" + damage + " hits).")
  target.hitpoints = target.hitpoints - damage
}
else {
  msg (CapFirst(attacker.alias) + " attack " + target.alias + " and miss...")
}

This is something like what you said.
Edit:
I just saw Anonynn responded to an old thread. Hi Anonynn!


Heya Jmnevil :D


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums