Randomizing the Randomizer

So I have a function that causes different objects to spawn randomly in different rooms. Thing is, it only spawns one of them in. I could manually tell the function the add more than just 1, but then it'd spawn in the exact number I typed in every time that object has been chosen to spawn in. How do I get Quest to randomly decide whether it will spawn in 1, 2, 3, etc.of the same object rather than just one?


I noticed it has a dice roll function. Could that be helpful?


Spawn then inside a loop:

for (i, 1, GetRandomInt(1, 3)) {
  SpawnThing
}

(sorry, this post ended up being longer than I intended. Feel free to ignore. Also, edited for typo)

There are different ways to generate a random number. And different ways might "feel" more random to the player in different situations. I normally end up trying different methods until I hit on the one that seems natural. Here's some of the ones I've used:

while (RandomChance(60)) {
  code that spawns a thing goes here
}

↑ Means there's a 60% chance of getting one or more objects, 36% of getting 2+, 21.6% change of 3+, and so on.

Or with independent items:

if (RandomChance(50)) {
  CloneObjectAndMove (stick, room)
}
if (RandomChance(30)) {
  CloneObjectAndMove (stone, room)
}
if (RandomChance(3)) {
  CloneObjectAndMove (gold nugget, room)
}

The system I'm currently poking on my own has an unreachable room called "prototypes" containing all the objects that I might want to clone into the forest; and I've given them an attribute "spawn_chance_forest" that determines their chance of showing up in any given room, and "spawn_multiple" which governs the chance of showing up more than once in the same room. Then I use:

foreach (room, list_of_forest_rooms) {
  possible_objects = NewObjectList()
  objects_created = 0
  foreach (o, GetDirectChildren(prototypes)) {
    if (HasInt(o, "spawn_chance_forest")) {
      list add (possible_objects, o)
      if (not HasInt(o, "number_spawned")) {
        o.number_spawned = 0
      }
    }
  }
  while (ListCount(possible_objects) > 0) {
    objects_created = objects_created + 1
    object = PickOneObject(possible_objects)
    list remove (possible_objects, object)
    count = o.number_spawned
    if (object.spawn_chance_forest < GetRandomInt(count, 15*objects_created)) {
      o.number_spawned = count + 1
      CloneObjectAndMove (o, room)
      if (HasInt(object, "spawn_multiple")) {
        if (RandomChance(object.spawn_multiple)) {
          list add (possible_objects, object)
        }
      }
    }
  }
}

... that's a pretty complex way to do it, but efficiently handles scattering multiple objects through multiple rooms.


This is how my function looks like:

  CloneObjectAndMove (Large Leaves, player.parent)
}
if (RandomChance(50)) {
  CloneObjectAndMove (Stones, player.parent)
}
if (RandomChance(50)) {
  CloneObjectAndMove (Sticks, player.parent)
}
if (RandomChance(10)) {
  CloneObjectAndMove (Aloe Vera, player.parent)
}
if (RandomChance(10)) {
  CloneObjectAndMove (Sap Tree, player.parent)
}
if (RandomChance(10)) {
  CloneObjectAndMove (Boar, player.parent)
}
CloneObjectAndMove (Trees, player.parent)
if (RandomChance(50)) {
  CloneObjectAndMove (Worm, player.parent)
}
if (RandomChance(10)) {
  CloneObjectAndMove (Thorn Bush, player.parent)
} 

Mrangel, are you saying I should do while (RandomChange(60)) {in the room itself, and then add then call this function within it?


On the random chances, changing "if" to "while" will allow more than one of the same item to appear, in a way that can feel like a natural distribution. There are more complex ways to do it, but you might find that's all you need.


Yes but, what else? Are you saying I should do while (RandomChange(60)) {in the room itself, and then add then call this function within it?


wow, ingenious use of 'while' with 'RandomChance', that's really cool, never knew this could be done!

the RandomChance continues, so long as its successful, that's really cool!


another simple use of the randomization functions:

(the common 'item drop' functionality in rpgs)

use 'GetRandomInt' to select an item from a list, and then you can use 'RandomChance' to determine whether you actually get that item or not.


Yes but, what else?

I don't think there is any else.

I posted a couple of different methods. Now that I've seen your original code, I think the simplest one is going to be changing "if" to "while". So you get something like:

while (RandomChance(50)) {
  CloneObjectAndMove (Stones, player.parent)
}
while (RandomChance(50)) {
  CloneObjectAndMove (Sticks, player.parent)
}
while (RandomChance(10)) {
  CloneObjectAndMove (Aloe Vera, player.parent)
}
while (RandomChance(10)) {
  CloneObjectAndMove (Sap Tree, player.parent)
}
while (RandomChance(10)) {
  CloneObjectAndMove (Boar, player.parent)
}
CloneObjectAndMove (Trees, player.parent)
while (RandomChance(50)) {
  CloneObjectAndMove (Worm, player.parent)
}
while (RandomChance(10)) {
  CloneObjectAndMove (Thorn Bush, player.parent)
} 

What does changing one word do though?


While = doing everything at the same time.

Minor, but important difference!


Changing 'if' to 'while' just means it can happen more than once. Imagine tossing a coin for it; every time you get heads, you add a stone and flip again. When you get tails, it's time to move on to the next type of item.

While = doing everything at the same time.

Not in programming.


But how does it know what the chance of spawning in more than 1 of the same item is?


Same as the chance of spawning the original. It keeps on using the same RandomChance.
You can make them different if you want, it just takes a little more code.


for example:

while (RandomChance(50)) {
  CloneObjectAndMove (Stones, player.parent)
}

you got a 50% chance ('effectively a coin toss') of the 'cloneobjectandmove' happening, and so long as you're successful, it'll keep doing the 50% chance ('coin flip') for more chances of doing the 'cloneobjectandmove', but the moment it fails (the 50% chance / 'coin flip' fails to do the 'cloneobjectandmove'), it ends, no more 'flipping of the coin'.

so, if you had godly-luck, it'd keep succeeding forever... and crash quest as an infinite loop, lol.


My mistake.

Why would you do it multiple times, though?


Oh! I see now. Wow such a simple and clever solution.


Log in to post a reply.

Support

Forums