How can I do dynamic & weighted number generation?

Say I want to create a fishing system where fish have random weight, let’s say a specific fish has a lower weight value of 5 lbs and a upper weight value of 12. When a fish is caught it will choose a random number between those, say like 6.7 lbs, 8.9, etc.

I would like to weight the random… weight. (pun intended. heh) The higher the value, the rarer the chance. I’ve tried searching and I found a few things but they either didn’t translate to me well or weren’t dynamic as I would need it to be.

So TLDR question is: How can I make a dynamic weighted random number function, where the higher the number is rarer?

A simple solution would be to subtract the weight by the highest weight, and find its absolute value

local newWeight = math.abs(weight - maxWeight)
1 Like

I have a system I use for a pet egg, where each pet “rarity” (out of 100) can be set within a table:
(pseudocode)

local pets/fish = {
    {"Salmon", 50},
    {"Cod", 35},
    {"Catfish", 15}
}

local function choose()
    local random = math.random(1.0,100.0)
    local count = 0
    for i,v in pairs(pets/fish) do
        if random >= count+1 and random <= count + v[2] then
            print("you got ".. v[1])
	end
	count += v[2]
    end
end
1 Like

Try this:

local fish = {
    {"Catfish", 8}
    {"Cod", 64},
    {"GoldFish",16}
    {"Salmon", 32},
}

local function GetHatchedPet()  --Use this function when the fish is obtained.
    local total = 0
    for _, instance in ipairs(fish) do
        total += instance[2]
    end
    local count =  math.random(1,total)

    for _, instance in pairs(fish) do
        if count >= instance[2] then
            print("You got a "..instance[1])
            break
        end
	end
end

I hope I helped you.

Basically just create a function that matches the general shape of what you want the weights to be, then pick a random x value from that function. After finding a good shape you need to translate and/or scale the function to make it fit well.

For example put in that function and have it pick an x value between 0 and 1

Then take the y value you get and multiply it by a scaling constant. Then add it to the min size of fish.

A different method I just thought of would be to use a number sequence attribute. You could use Robloxs gui to adjust the graph keypoints to match about what values you want. This way you can visually graph your randomize function without actually having to create a plugin.

When editing all that matters is how much of the graph is in what value range. If you want about 50% to stay near the middle you would have 50% of the timeline have values near the middle.

And on this [link] (NumberSequence | Roblox Creator Documentation) there is code that would get the value based on the timestamp you pass into the function. So all you would have to do is insert your random value between 0 and 1 into it, then map the output (which is between 0 and 1) to your range.

In other words

evalNS(sequenceAttribute, math.random())*(max-min) + min

I guess it’s technically the same solution, just a different implementation.

2 Likes