This module is called upon a player entering the game
local MoodService = {}
local Players = game:GetService('Players')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local ServerStorage = game:GetService('ServerStorage')
local Remotes = ReplicatedStorage:WaitForChild('Remotes')
local Events = Remotes:WaitForChild('Events')
local Mood = Events:WaitForChild('Mood')
local UpdateMood = Events:WaitForChild('UpdateMood')
local PlayerData = require(ServerStorage.PlayerData)
local Updating = false
local UpdatingMood
local function update(player, active, mood)
if active == Updating then return end
Updating = active
UpdatingMood = mood
end
local function getMood(player)
local User = PlayerData[player.UserId]
if not User then return end
Mood:FireClient(player, User.Moods)
end
function MoodService:Groggy(player)
local User = PlayerData[player.UserId]
if not User then return end
local TotalMood = 0
for _, v in pairs(User.Moods) do
TotalMood = TotalMood + v
end
local Character = player.Character
if not Character then return end
local Humanoid = Character:WaitForChild('Humanoid')
if not Humanoid then return end
if TotalMood <= 100 then
Humanoid.WalkSpeed = 10
else
Humanoid.WalkSpeed = 16
end
end
function MoodService:ChangeMood(player, mood, amount)
local User = PlayerData[player.UserId]
if not User then return end
if User.Moods[mood] < 5 then return end
if amount > 0 then
if User.Moods[mood] < 100 then
User.Moods[mood] = User.Moods[mood] + amount
end
else
User.Moods[mood] = User.Moods[mood] + amount
end
self:Groggy(player)
getMood(player)
end
function MoodService:FindNearestPlayer(player)
local PlayersCharacter = player.Character
if not PlayersCharacter then return end
for _, v in pairs(Players:GetPlayers()) do
if v ~= player then
local NearCharacter = v.Character
if not NearCharacter then return end
local Distance = (NearCharacter.PrimaryPart.Position).magnitude - (PlayersCharacter.PrimaryPart.Position).magnitude
if Distance <= 10 then
update(player, {}, 'Happiness')
else
update(player, false)
end
end
end
end
function MoodService:SetUp(player)
local User = PlayerData[player.UserId]
if not User then return end
coroutine.wrap(function()
while player:IsDescendantOf(Players) do
if Updating and UpdatingMood then
MoodService:ChangeMood(player, UpdatingMood, 5)
end
wait(3)
end
end)()
spawn(function()
local i = 0
while User do
i = i + wait()
MoodService:Groggy(player)
MoodService:FindNearestPlayer(player)
if i >= 5 then
i = 0
local Elements = {}
for i, v in pairs(User.Moods) do
table.insert(Elements, i)
end
local RandomMood, RandomIndex
repeat
RandomIndex = math.random(1, #Elements)
RandomMood = table.remove(Elements, RandomIndex)
until #Elements == 0 or RandomMood ~= UpdatingMood
print(RandomMood)
if RandomMood ~= UpdatingMood then
MoodService:ChangeMood(player, RandomMood, -5)
end
end
end
end)
end
Mood.OnServerEvent:Connect(getMood)
UpdateMood.OnServerEvent:Connect(update)
return MoodService
Now I feel like this is very clunky, and will more than likely become a problem in the future.
Basically, a player has ‘moods’ (Energy, Happiness, Hunger, Hygiene) A random mood is picked every 5 seconds, and decreases that set mood (moods start at 100, lose 5 points to that when random mood is chosen)
The problems I feel will face in the future is the ChangeMood function. From the client, I have multiple ways for a players mood to go up. Code below checks for which mood should be updating.
coroutine.wrap(function()
while player:IsDescendantOf(Players) do
if Updating and UpdatingMood then
MoodService:ChangeMood(player, UpdatingMood, 5)
end
wait(3)
end
end)()
Now, I’ve just implemented a new function, which will give the player Happiness when near other players.
for _, v in pairs(Players:GetPlayers()) do
if v ~= player then
local NearCharacter = v.Character
if not NearCharacter then return end
local Distance = (NearCharacter.PrimaryPart.Position).magnitude - (PlayersCharacter.PrimaryPart.Position).magnitude
if Distance <= 10 then
update(player, {}, 'Happiness')
else
update(player, false)
end
end
end
Problem with this, is if you aren’t close enough, update gets fired to false, stopping the points from going up. Now, for example, when you sit, that fires the UpdateMood RemoteEvent, which then fires update function to give you Energy. But if the Energy is being given and then a player comes near you, it can’t give you both Energy and Happiness. And then if that player leaves while your still sitting, it’ll run
update(player, false)
Which will mean your still sitting, but you won’t be getting Energy
Is there a cleaner way I can do this? I’m guessing the use of tables or something? To somehow add like
UpdatingMoods = {}
-- and then insert/remove the speicific mood when it needs to
UpdatingMoods = {'Hunger', 'Energy'}
-- this way all 4 moods could be increased at once (if the player was doing 4 things at once to increase all 4, which will be unlikely, but at least 2 or 3 moods at once
I wouldn’t know how to implement this table system into what I have