I have this set of settings for weather, and I’m tryna pick a random set of weather.
local WeatherSettings = {
Normal = {
Brightness = 1.25,
FogColor = Color3.fromRGB(192, 192, 192),
FogEnd = 800,
FogStart = 250,
},
Rain = {
Brightness = 0,
FogColor = Color3.fromRGB(50, 50, 50),
FogEnd = 500,
FogStart = 0,
},
Snow = {
Brightness = 0,
FogColor = Color3.fromRGB(255, 255, 255),
FogEnd = 500,
FogStart = 0,
},
}
spawn(function()
while wait(5) do
local RandomWeather = WeatherSettings[math.random(#WeatherSettings, 1)]
print(RandomWeather)
end
end)
The print returns nil
1 Like
math.random(minValue, maxValue) requires the minValue to be smaller than the maxValue. I believe you have the parameters of math.random() the wrong way round, and an error doesn’t show because it’s inside spawn()
You also can’t get the length of a dictionary, or get which order the key/values are stored in, so try changing the weather dictionary to a table instead, as right now it won’t work even with the arguments for random the right way round!
Like mario118118 said, you’ve switched up the MinValue to MaxValue. I did print(#WeatherSettings) and got 0 in return so I decided to change the values (e.g. Normal etc.) to numbers and it printed 3 afterwards.
local WeatherSettings = {
[1] = {
Brightness = 1.25,
FogColor = Color3.fromRGB(192, 192, 192),
FogEnd = 800,
FogStart = 250
},
[2] = {
Brightness = 0,
FogColor = Color3.fromRGB(50, 50, 50),
FogEnd = 500,
FogStart = 0
},
[3] = {
Brightness = 0,
FogColor = Color3.fromRGB(255, 255, 255),
FogEnd = 500,
FogStart = 0
}
}
Errors still show in spawns (as shown here)
spawn(function()
while wait(5) do
local RandomWeather = WeatherSettings[math.random(1, #WeatherSettings)] -- ERROR
print(RandomWeather)
end
end)
[bad argument #2 to ‘random’ (interval is empty)]
1 Like
Rename the values in your dictionary like in my previous reply.
Read the second part of my post, as I edited it! You cannot get the length of a dictionary as the values are not stored in any particular order. You also need to use numbers as the index for each list, making it an array, otherwise the values still wont get returned.
E.g
local dic = {}
dic["hi"] = 1
dic["bye"] = 2
print(dic[1]) -- nil, as no key is equal to 1.
Using a array:
local dic = {"hi", "bye"}
print(dic[1]) -- returns "hi" :)
1 Like
Sure, but I still think it’s useful to think of dictionaries and arrays as two seperate things, and in other languages they are literally two separate data types. I wasn’t being incredibly specific because I didn’t think it was relevant to help the OP, and doesn’t really make and difference to this scenario
How do I go about making it weighted then?
local WeatherRaritySet = {}
for i, weather in pairs(WeatherSettings) do
local Rarity = weather.Rarity
for i = 1, Rarity do
table.insert(WeatherRaritySet, weather.Type)
end
end
local RandomWeather = WeatherRaritySet[math.random(1, #WeatherRaritySet)]
So that way it isn’t 1 in 3 of getting either weather. If Normal has a Rarity of 50, Rain has a rarity of 25 and Snow a rarity of 10. That way it’s most likely gonna be normal, etc.
1 Like
To make it weighted, you could give each weather condition a weight, then get the total weight by looping through each weather setting and grabbing the weight for each, adding it to a variable. Choose a random number between 1 and the total, and then find which weather setting fits that random number. Bit confusing? I’ll try and explain below:
-- Define weathers and their respective weights
local WeatherSettings = {
{
Name = "Normal",
Rarity = 50,
Brightness = 1.25,
FogColor = Color3.fromRGB(192, 192, 192),
FogEnd = 800,
FogStart = 250
},
{
Name = "Rain",
Rarity = 25,
Brightness = 0,
FogColor = Color3.fromRGB(50, 50, 50),
FogEnd = 500,
FogStart = 0
},
{
Name = "Snow",
Rarity = 10,
Brightness = 0,
FogColor = Color3.fromRGB(255, 255, 255),
FogEnd = 500,
FogStart = 0
}
}
-- Loop through and get the total "weight"
local maxAmount = 0 -- set variable for total weight
for _,value in next, WeatherSettings do -- loop through each setting
maxAmount = maxAmount + value["Rarity"] -- add the weight to the total
end
local function getWeather()
-- Choose a random weather
local randomNum = math.random(1, maxAmount)
-- Loop through the table and find the appropriate setting
local currentWeight = 0
for _,value in next, WeatherSettings do
if randomNum >= currentWeight and randomNum <= currentWeight + value["Rarity"] then -- is it bigger than the previous weight, but smaller than the current weight?
return value -- yay
end
currentWeight = currentWeight + value["Rarity"] -- add the weight to the temporary value
end
return nil -- just in-case? :shrug:
end
-- To get a weather
local weather = getWeather()
if weather ~= nil then
-- "weather" is the table from the WeatherSettings
end
Hopefully this works, and hopefully it helps!
2 Likes