How would I make a luck system?

Hello developers!

I’m wondering how to make a luck system (for an egg hatching system, chest opening etc…) but all the solutions I’ve came through so far are too confusing for me. Can anyone give me a simple idea for this? Thanks!

4 Likes

I would take advantage of tables

local Table = {
    ["Egg1"] = {
        ["Pet1"] = 20,
        ["Pet2"] = 30,
        ["Pet3"] = 50
    },
    ["Egg2"] = {
        ["Pet1"] = 20,
        ["Pet2"] = 30,
        ["Pet3"] = 50
    }
}

you could make the table however you want, whatever works with the game best

it doesn’t have to be structured like my table at all

3 Likes

How would you get the pets though? Do I have to make a loop?

1 Like

well it would depend on how you structure the table

1 Like

I would use your table structure since I like organized stuff. How would it work with your design?

1 Like

Weighted Chance System. Please research before making a thread/post. :slight_smile:

2 Likes

Just doing this will land you one of the pets:

local random = math.random(100)

Then you could loop through the table, and see, if a pets chance is lower than or equal, to the random.

1 Like

Thanks, this is just what I needed!

2 Likes

One of the most basic “luck” systems would simply be a random number based on chances.

local Items = { -- This is a list of items with Names and Chances. Chance is based on a number from 0 to 100. The lower the Chance, the less likely you will attain the item.
	{ Name = "Duck", Chance = 100 },
	{ Name = "Baseball", Chance = 20 },
	{ Name = "Diamond", Chance = 1 },
}

local function GetRandomItem()
	local number = Random.new():NextInteger(1, 100) -- We get a random number between 0 and 100.
	local chosen = nil-- The item that will be chosen.
	
	for i, item in ipairs(Items) do -- Iterate over each item
		if number < item.Chance then -- If the number is less than the Chance, this is the chosen item.
			chosen = item
		end
	end
	
	return chosen
end

local item = GetRandomItem()

print(item.Name)
3 Likes

That’s a good idea too. Thanks!

Here’s some advanced information if you’re used to luck systems.

There are 2 main methods of choosing items.

  1. Weighted: Add up the weight of every item and choose a random time using that weight. This always guarantees that an item will be picked. The downside is that chances for every item will change and it gets difficult to tell the exact chance of items without calculating them.

  2. Percentage Chance: This is the most basic and common way for random items to be chosen. Choose a random number, usually up to 100, and if the number is lower than the item chance (ex 40), then return the item. The only minor downside is that this has a chance of giving nothing at all.

From my experience, the best method for chance systems is to use a combination of weighted and chance. Take, for example, Terraria. They use both weighted to guarantee a drop from an item pool (ex special boss weapon) and chance to give the randomness fun of repeatedly fighting the same boss.

local Max = 1000
local Table = {
    ["Egg1"] = {
        ["Pet1"] = 100,
        ["Pet2"] = 100,
        ["Pet3"] = 300,
        ["Pet4"] = 500,
        ["Pet5"] = 700,
        ["Pet6"] = 900
    },
    ["Egg2"] = {
        ["Pet1"] = 100,
        ["Pet2"] = 100,
        ["Pet3"] = 300,
        ["Pet4"] = 500,
        ["Pet5"] = 700,
        ["Pet6"] = 900
    }
}

function GetRandomPet(Egg)
    local RandomNumberMin = Random.new():NextInteger(0, math.floor(Max / 2))
    local RandomNumberMax = Random.new():NextInteger(0, Max)
    local RandomNumber = math.abs(RandomNumberMax - RandomNumberMin)
    
    local RarityTable = {}

    for Name, Rarity in pairs(Table[Egg]) do
        if Rarity <= RandomNumber then
            table.insert(RarityTable, Name)
        end
    end

    if #RarityTable == 0 then
        return GetRandomPet(Egg)
    end

    return RarityTable[Random.new():NextInteger(1, #RarityTable)]
end

print(GetRandomPet("Egg1"))

don’t have much experience with making rarity type things, so I tried making this as good as I could

others will have better suggestions then this most likely

1 Like

Not if you add Nothing as an item and avoid giving the player an item if Nothing is rolled. :smiley:

I love LootPlan as far as weighted chance goes. The tutorial in the solution uses numbers 0-1 but that feels too restricting. LootPlan allows any range of numbers and it handles all the rolling for you. You’d just be responsible for handling the outcome of a loot roll.

Looks like the same as my loot system, just more restrictive (also OOP-based scripting makes me cry in confusion).

My system adds a “Luck” factor that can change the chance of drops. You can also just feed it 1 big table and it automatically detects whether to use weighted or single chance. Finally, you can change the flat 100 chance for single loot if you use a different system like 256 or something.

Also, I made it so weighted tables can also have a chance of dropping nothing (or multiple amounts of what is inside to be added…).

Agreed, to each their own.

I’m not sure if by “more restrictive” you referring to LootPlan, but I would disagree if that’s the case. LootPlan’s only purpose is to handle the weighted chance algorithm for you; it doesn’t proclaim itself to do any more or less than that and it does it very well. It’s been holding up very well for my experience, we just have LootPlan manage our chances and then do the rolling/distribution ourselves.

As for the OOP, I think it’s justified in this case because plans are stateful mainly due to the accumulated weighting by adding or removing objects. The API is helpful and clean, unlike most abuses of OOP. I get the whole “ew OOP!” argument and I’m on that boat too but it doesn’t hold up for every situation and LootPlan is not one of those cases where I think “ew OOP!”.

To each their own though.