Learn SugarBeginner

Random choices and dice

Use the Rand namespace to choose random numbers or text, add percentage chances, and roll dice.

Randomness lets the same Item action or Boop produce different results each time. You have already seen that Rand is a namespace and :: accesses one of its functions. This lesson combines that knowledge with the ranges and lists introduced earlier.

Choose a whole number

Rand::pick(1..=100)

1..=100 is a range that includes every whole number from 1 through 100. Rand::pick() chooses one of them.

The range matters. This call chooses any whole number from 1 through 100:

Rand::pick(1..=100)

This different call chooses either the exact value 1 or the exact value 100:

Rand::pick(1, 100)

Use it directly inside a message:

text "@1 and @2 are {}% compatible." with Rand::pick(1..=100);

Choose one option

Rand::pick("Truth", "Dare", "Double Dare")

Rand::pick() also returns one of the individual values you give it. It works well for short prompt lists and alternate wording.

text "@1 {} @2." with Rand::pick("kisses", "teases", "pulls closer");

Every option passed to Rand::pick() is equally likely. Repeating an option can imitate simple weighting, but it quickly becomes difficult to read. Use Rand::weighted() when options need different chances.

Give options different weights

Rand::weighted(
  7 => "COMMON",
  2 => "UNCOMMON",
  1 => "RARE",
)

Each entry uses weight => value. Sugar adds the weights together, then gives each value its share of that total. In this example, "COMMON" has 7 of the 10 total parts, so it is chosen about 70 percent of the time.

Weights are relative. These two choices describe the same probabilities:

Rand::weighted(3 => "DAY", 1 => "NIGHT")
Rand::weighted(75 => "DAY", 25 => "NIGHT")

A weight may be any number expression, so current state can influence a choice without repeating values:

let rareWeight = if luck > 80 then 4 else 1;

let reward = Rand::weighted(
  8 => "COINS",
  rareWeight => "CROWN",
);

Weights must be non-negative numbers, and at least one weight must be greater than zero. A zero-weight entry cannot be selected.

Give something a percentage chance

Rand::chance(25)

Rand::chance(25) gives true about 25 percent of the time and false the rest of the time.

Use the short if form to choose text:

text "@1 opens the chest and finds {}." with if Rand::chance(10) then "the rare prize" else "the regular prize";

Roll dice

Rand::roll("1d20")

This rolls one 20-sided die, returns the total, and shows JOI’s dice result.

text "@1 rolled {}." with Rand::roll("1d20");

Dice expressions can include more dice and a number to add:

Rand::roll("2d6+3")

This rolls two 6-sided dice and adds 3 to their total.

Pass false as the second argument when you want the number without the visible dice result:

text "@1 takes {} damage." with Rand::roll("2d6+3", false);

Keep one random result for later

Two separate random calls can choose two different results. Save one result in a let variable when a program needs to reuse it:

text {
  let roll = Rand::pick(1..=20);
  "@1 rolled {roll}. The target was {}." with roll + 5
}

Sugar chooses roll once. Every later use of that variable reads the same number.

The next lesson introduces Date values and the related Date and Duration namespaces.