1

In my simulator egg hatching system i have a problem. I want to return a random index of a dictionary rank (??) but when I want to clone the returned object value but the it says:

Attempt to index nil with "Clone"

So the returned Value must be nil, I think...

I have a module script called PetModule. There are two tables, the rarity table and the pets table. There is a function called "ChooseRandomPet" I listed these functions and tables here:

-PetsTable

petmodule.pets = {
    
    ["Chocolatary"] = {
        "Chocolate Golem"
        
    };
    
    ["Insane"] = {
        "Choco Demon"
        
    };
    
    ["Mythical"] = {
        "Light Choco Bat"
        
    };
    
    ["Epic"] = {
        "Choco Bunny"
        
    };
    
    ["Rare"] = {
        "Choco Fox"
        
    };
    
    ["Common"] = {
        "Choco Mouse"
        
    };
    
    ["Poop"] = {
        "Choco Bear"
        
    };
    
}

-Rarity table

petmodule.rarities = {
    
    ["Chocolatary"] = 1;
    
    ["Insane"] = 2;
    
    ["Mythical"] = 4;
    
    ["Epic"] = 8;
    
    ["Rare"] = 14;
    
    ["Common"] = 38;
    
    ["Poop"] = 33;
    
}

-Choose Random Pet function

petmodule.chooseRandomPet = function()
    

    
    
    local randomNumber = math.random(1,100)
    
    local   counter = 0
    
    for rarity, weight in pairs(petmodule.rarities) do
        
        counter += 1
        
        if randomNumber <= counter then
            
            local rarityTable = petmodule.pets[rarity]
            
            local chosenPet = rarityTable[math.random(1, #rarityTable)]
            
            return chosenPet
            
        end
    end
    
end

I do not know what could be wrong. If I want to access it in my local script, a buy script (the module script is in RepStorage) and then run a function if the event is fired it says the returned value is nil.

-The buy script (local)

local debounce = false
local cost = 20

local Player = game.Players.LocalPlayer

local petmodule = require(game:GetService("ReplicatedStorage"):FindFirstChild("PetModule"))


script.Parent.MouseButton1Click:Connect(function()

    if Player.leaderstats[" Money "].Value >= cost then
        
        if not debounce then
            debounce = true


            game:GetService("ReplicatedStorage"):FindFirstChild("ChangeMoney"):FireServer(tonumber(Player.leaderstats[" Money "].Value - cost))
            local player = game.Players.LocalPlayer
            local petName = petmodule.chooseRandomPet(player)
            
            local petVal = Instance.new("StringValue", Player.PetInventory)
            


            game.ReplicatedStorage.HatchEgg:FireServer(petName)


            
            wait(3)
            debounce = false
        end

    end

end)

-The hatch script (local)

game.ReplicatedStorage.HatchEgg.OnClientEvent:Connect(function(petName)

        
    camera.CameraType = Enum.CameraType.Scriptable
    
    camera.CFrame = studio.CamPart.CFrame
    
    wait(1.5)
    
    for i = 1, 50, 1 do
        studio["Meshes/egg"].Size = studio["Meshes/egg"].Size + Vector3.new(0.2,0.2,0.2)
        wait(0.01)
    end
    
    local explosion = Instance.new("Explosion")
    explosion.BlastRadius = 15
    explosion.BlastPressure = 0
    explosion.Position = studio["Meshes/egg"].Position
    explosion.ExplosionType = Enum.ExplosionType.NoCraters
    explosion.DestroyJointRadiusPercent = 0
    
    explosion.Parent = studio["Meshes/egg"]
    
    studio["Meshes/egg"].Transparency = 1
    local pet = game.ReplicatedStorage.Pets:FindFirstChild(petName)
    local petclone = pet:Clone() -- Here it errors

1 Answers1

3

I believe your problem is in how you are choosing the rarity. Let's use some real numbers and step through your code:

    local randomNumber = math.random(1,100)
    local counter = 0
    
    for rarity, weight in pairs(petmodule.rarities) do
        counter += 1
        if randomNumber <= counter then

When iterating over the rarities table, let's track the counter value, and let's assume our random number returned 14

#loops rarity weight counter escape case
1st Chocolatary 1 1 14<=1 (false)
2nd Insane 2 2 14<=2 (false)
3rd Mythical 4 3 14<=3 (false)
...
7th Poop 33 7 14<=7 (false)

Then, with no more items in the rarity table to iterate over, the loop exits, and nothing is returned. The problem is that you are only increasing the counter by one every time. counter needs to increment by the weight of each item in the list. Otherwise, you'll never get a pet unless your random number is less than the number of items in the rarity table.

counter += weight

When properly weighted, this is how the values shake out as it loops :

#loops rarity weight counter escape case
1st Chocolatary 1 1 14<=1 (false)
2nd Insane 2 3 14<=3 (false)
3rd Mythical 4 7 14<=7 (false)
4th Epic 8 15 14<=15 (true)
Kylaaa
  • 6,349
  • 2
  • 16
  • 27
  • Thanks Kylaaa! I think it worked properly a few weeks ago, but then I had a bug that is fixed now (not this one) and I tried to change Values and then I made +1 i think...But I'm glad you helped me!! Sorry for my english by the way... – Google Donut Oct 31 '22 at 09:43