Loot Manager - A module for your Random Events and Loot (Loot Cases and more)

Hello, I’ve seen a lot of people trying to make loot tables and I decided to come up with a flexible and easy to use module, just so developers can approach the situation stress free.


Summary
  • This module can optionally use probabilities between 0 and 1 (total percentages of all items must always add up to 100%)

  • This module can optionally use Weights (any number that you want including decimals, essentially allowing you to use odds/fractions/ratios by giving each item a ‘weight’)

  • This module can help convert odds to probabilities and vice versa.

  • This module can handle any event that depends on probabilities/odds. (but most people will probably use it for loot crates and similar constructs)


Source code

LootManager Module - Pastebin.com


Media

Console results (high weights have a higher chance, low weights have a lower chance)
https://gyazo.com/d049710161f8f3ad68d7aa42c2c1d463

Fortune Wheel, Credits to @BladianMC and @DEV_Sm
https://gyazo.com/3f49867efd004a9086250b44a192ec5c


Current Version

LootManager Module


Old Versions

First Version : Very Unoptimized


Fortune Wheel tips

Click Here






Below is a quick concept using a jelly bean jar as an example, we’ll use probabilities and odds (but either one is optional and can be converted into one another if needed.)

You will need a decent understanding of Dictionary Tables.


Rules

When creating your jelly bean jar, it MUST contain a nested table with a key named “Weight” OR “Chance”, after that you can add any other keys that you need.

Example using odds
--red bean odds are 1/11 (11,000 total, but only 1,000 possible) - (0.09% probability)
local jar = {
    RedBean = {
        Weight = 1000, --must contain this value called "Weight"
        Whatever = "Blah" --your own values that you may need
    },
    BlueBean = {
        Weight = 10000,
        Whatever = "Blah"
    }
}
Example using probability
--red beans probability of being chosen is 25% (or 1/4 odds)
local jar = {
    RedBean = {
        Chance = 0.25 --must contain this value called "Chance"
        Whatever = "Blah" --your own values that you may need.
    },
    BlueBean = {
        Chance = 0.75
        Whatever = "Blah"
    }
}

Quick Tutorial

  • Step TWO

    Require the module
     local LootMananger = require(game.ServerScriptService.LootManager) 

  • Step THREE
    Create your jar


    Create your jar of jelly beans using Weights
        --use any number you want
        local jar = {
            RedBean = {Name = "MrRedBean",  Weight = 50}, --50 red beans
            GreenBean = {Name = "MrGreenBean",  Weight = 1000}, --1000 green beans
            BlueBeen = {Name = "MrBlueBean",  Weight = 0.5} -- 0.5 blue beans 
        }

    Create your jar of jelly beans using Percentages
        --all chances must add up to 100% in order to calculate correctly. 
        local jar = {
            RedBean = {Name = "MrRedBean",  Chance = 0.25}, --25% of the jar is red beans
            GreenBean = {Name = "MrGreenBean",  Chance = 0.7} -- 70% of the jar is green beans
            BlueBeen = {Name = "MrBlueBean",  Chance = 0.05} -- 5% of the jar is blue beans
        }

  • Step FOUR

    Get a random jelly bean out of the jar.
        local selectedBean = LootManager:GetRandomSlot(jar)
        print(selectedBean.Name .. ":" .. (selectedBean.Weight or selectedBean.Chance))

  • Step FIVE

    Compare the name to a list of rewards/items (and other things)
        local beanReward = beans[selectedBean.Name]:Clone()
        beanReward.Parent = player.Backpack --lol bean tool

That’s all folks, if you have any questions please post them here.

Thanks for reading and enjoy!

40 Likes

Thanks.
A picture’s worth a thousand words. Please include a sample video in your post, thank you.

5 Likes

Quick question about your random selection system.

You appear to be adding a lot of values to a central table, then randomly selecting a value from that table, which while working fine at 100 values, if we want a highly detailed system with potentially 10,000 total values that can create a huge performance spike.

Im just interested in why you chose this over a weight based system?


Edit: has been changed

5 Likes

If OP isn’t sure how to create a good weight based system, here is one I wrote…

RarityManager.RegularCaseRarityValues = {
	{Rarity = 1, Chance = 60};
	{Rarity = 2, Chance = 25};
	{Rarity = 3, Chance = 14};
	{Rarity = 4, Chance = 0.9};
	{Rarity = 5, Chance = 0.1};
}

RarityManager.PremiumCaseRarityValues = {
	{Rarity = 3, Chance = 50};
	{Rarity = 4, Chance = 45};
	{Rarity = 5, Chance = 5};
}

function RarityManager.GetCaseRarityValue(premium)
	local targetTable = premium and RarityManager.PremiumCaseRarityValues or RarityManager.RegularCaseRarityValues

	local selectedNumber = math.random(0, 100)/10

	local counted = 0
	for _, chanceData in pairs(targetTable)do
		counted = counted + chanceData.Chance
		if counted >= selectedNumber then
			return chanceData.Rarity
		end
	end
end

This is just pulled out of a random project of mine. The random logic for selectedNumber which returns a random number from 0-100 to a decimal point of 1 could be improved, but otherwise this is a clean and efficient way of handling a weighted probability issue.

It works like so… If an item has a 30% chance of being one, the code will “allocate” the first 30 numbers of 1-100, RNG comes up anywhere from 0-29, you win the 30% item. The next item, which is say 20%, will be allocated the numbers 30-50, and if the RNG throws up a number between 30-50, you win the 20% item

14 Likes

5 posts were split to a new topic: LootTable (Private Discussion)

It wasn’t meant to be passive aggressive, and sorry if it came off that way!!

I was just trying to help, as I thought it’d improve your module, thats all :slight_smile:

1 Like

Hello, i want to know what’s the difference between this module and Quoteory’s one?

I would like a list with pros and cons :+1:.

Thanks. I am a real beginner and I appreciate this!

UPDATES
Update 7/27/2020

Fixed the miscalculation between Chances

Added a GetChances() function to convert Weights into percentages. (for visualization purposes and more)


Update 7/26/2020

I renamed LootTable to LootManager

i’ve completely reconstructed this module, and will continue to add utilities and other useful functions, like easy to use fortune wheels and case systems (please provide suggestions)

I’ve added support for both weights and percentages directly. (weights can also use decimals now too, but don’t confuse the weight in decimal form with percentages)

Weight/Chance tables are now fully flexible and can contain custom data to help you
compare the randomly chosen element to a list of rewards. (or even comparing to angles on a fortune wheel).

Please post any bugs / suggestions you may have.

That module only works with items, and is general logic. (its NOT a bad system either, its just only used for items)

My module on the other hand can be used for ANY random type of event.

fortune wheels
simulating dice.
slot machines
mystery boxes and loot cases
and any event/action that requires random/variated results.

Hi there~ @codyorr4

Thank you for sharing your creation with us, this is very interesting stuff.

Would you kindly create a link to Source code (preferably Github and/or Pastebin) for people who want to read the source but don’t have any access to a PC or maybe want to contribute to the source

I know you provided Source code in the OP, but it’s easier to read on Pastebin

1 Like

there we go @RuizuKun_Dev, i’ve provided a pastebin link and i don’t think i’ll need github contributors just yet, the module is kinda small now compared to my old module.

thanks again for the advice.

Is there any way to use the old version?

If @codyorr4 has a GitHub repo for this you can look back through the commits and find the one you’re looking for.

1 Like

I’ll upload the old version as well, sorry. (i really do recommend the new one though)

EDIT: @TheDemoDeveloper
I’ve uploaded the old version above. ^

1 Like

Would anyone know of a good tutorial or resource that would help me script a fortune wheel like shown in the OP’s media example?

I know how to make a wheel spin with a decal on it, but not how to make it stop at the reward point.

What I have at the moment:
A wheel and click detector. Once clicked, the wheel spins and stops at a random location.

What I can do:
Once clicked, an event fires to the server. The server chooses the reward (e.g. local selectedBean = LootManager:GetRandomSlot(jar)) the player will get and sends that info back to the client.

What I still need to learn:
The client will then spin the wheel so it lands on the “reward image” associated with the reward received.

Any pointers would be much appreciated :slight_smile:

you would need to figure out how to get your wheel slots with a provided angle.

here is a really basic setup. (mine was something similar)

local slots = {
    Slot1 = {
        Angle = 0
        RewardType = "Uncommon"
    },
    Slot2 = {
        Angle = 25
        RewardType = "Legendary"
    }
}

now the server will just randomly choose one of these slots, after the server has chose a slot then it will just make the client do a spin animation that gradually slows down. Now once the wheel reaches a certain speed just make the wheel stop when it reaches the desired angle provided by the slots table.


NOTES


1). this is a ‘fixed’ spin and the reward is already chosen by the server before the wheel even starts spinning on the client.


2). Its way easier to compare angles to a ImageLabel (in a SurfaceGui or ScreenGui) then it is to compare angles to a parts orientation (atleast it was for me)


3). If you want to play fast sounds locally for the wheel spin then you need this (or some sort of custom method)


4). if you don’t want a ‘fixed’ spin then you could also try to emulate some physics of a spinning wheel but I couldn’t really imagine how that is done, and it would have to be handled by the server (so people can’t exploit the spin) which wouldn’t be smooth.

1 Like

Thank you so much! I’ll try to implement your suggestions :slight_smile:

no problem, goodluck. :ok_hand: