Weighted Table not working correctly

Problem: Weighted system does not return the correct item in range properly

I have a weighted table system where if the randomised number is within the range of the counter then it will return the item’s name, however some items let says in this case, a common item can still be returned even though the randomised number is like “40” which should return a rare item

Here are some examples of what i mean:

image --See how it returns a “Roffy” item ? even though the randomising value was 40 which in this case is within the range of a rare item as shown in the items table module:

local WeightedChance = { --The numbers applied to it are the chances, 125 common, 50 is rare, 3 is super rare
	Items = {
		["Rohklea"] = 125,
		["Kahruto(Kid)"] = 125,
		["Roffy"] = 125,
		["Ikigoh"] = 125,
		["Kokyu"] = 125,
		["Yuru"] = 125,
		["Zakuse(Kid)"] = 125,
		["Picohloh"] = 125,
		["Vegehtah"] = 125,
		["Chah"] = 125,
		["Kahruto(TS)"] = 50,
		["Zakuse(TS)"] = 50,
		["Vegehtah(SSJ)"] = 50,
		["Ace"] = 3,



This is the code i use:

function RandomiseItem(TotalWeight, Stats) --Receives the total chances (This function decides the weighted system)
	local Counter = 0
	--local RarityGroup
	local Randomising = math.random(1,TotalWeight)
	for CharName, CharChances in pairs(Module.GetMainBanner()) do
		--local RarityChance = CharChances --CharChances.Rarity.Chance
		Counter = Counter + CharChances
		if Randomising <= Counter then
			--RarityGroup = CharName
			local UnlockedItems = CharName --Chances.Items
			return UnlockedItems

Module.GetMainBanner() returns a live module consisting of the items available in the “Shop”
–Here is the screenshot
image -See how i printed it here ?

And finally!

This is where i call the RandomiseItem function

	local MainBanner = Module.GetMainBanner() --getting the banner as shown in picture above
	for Name, Chance in pairs(MainBanner) do
		TotalMainBannerWeight = TotalMainBannerWeight + Chance --Adding the total chances
		local Characters = RandomiseItem(TotalMainBannerWeight) --Sending the chances

Please, i appreciate if anyone can help or could show me a better way of doing it, Thank You

Isnt this supposed to be in code review then?

I dont think it is i explained the problem with it at the top

I have made the issue more clear now Thank You

There is no reason to move this to code review, this would fall under the scripting support category too.

Answered on disc

function module.NormalBanner()
    return    {
        Common = {
            Chance = 125,
            Items = {


        Rare = {
            Chance = 50,
            Items = {

        SuperRare = {
            Chance = 3,
            Items = {

local function shallowCloneArray(tbl) -- the other function
  return {unpack(tbl)}

function module.getUniqueRandom(type, amount) 
    local picked = {}
    local banners = shallowCloneArray(module.GetTableType(type))
    for i = 1, amount do
      picked[i] = table.remove(banners, math.random(#banners))
    return picked

function module.StartRandomBanner() 
    local pickedCommon = module.getUniqueRandom("common", 3)
    local pickedRare = module.getUniqueRandom("rare", 2)
    local pickedLegendary = module.getUniqueRandom("legendary",  1)

     module.UpdateMainBanner({common = pickedCommon, rare = pickedRare, legendary =  pickedLegendary }) 

local function getChance(type)
  return banners[type].Chance

local function pickItem(tbl)
  local randWeight = math.random(125 * 3 + 50 * 2 + 3) -- you can leave like this or make it function which actually calcs that
  for type, items in pairs(tbl) do
      for _, item in ipairs(items) do
        local chance = getChance(type)

        if randWeight <= chance then
           return item
          randWeight -= chance

function module.updateMainBanner(tbl)
   local pickedItem = pickItem(tbl)
   -- ... other stuff