I need some help with this custom "Pet" system that typical simulators use

Hey! I’m currently just experimenting for my own purposes but I’ve encountered 2 things which I have no idea how to combat;

Firstly, I’m experiencing this:

https://gyazo.com/be93b33b00db0b0c865ece1ddf14a475

Here’s the code for that:

--// Services \\--
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

--// Variables \\--
local Player = Players.LocalPlayer

--// Events \\--
local Events = ReplicatedStorage:WaitForChild("Events")
local RemoteEvents = Events['RemoteEvents']
local RemoteFunctions = Events:WaitForChild("RemoteFunctions")

local ClientEffects = RemoteEvents.ClientEffects
local getPlayerData = RemoteFunctions.getPlayerData

local function Follow(Pet, Position, BodyGyro, BodyPosition)
	spawn(function()
		RunService.RenderStepped:Connect(function()		
			BodyGyro.CFrame = Player.Character.HumanoidRootPart.CFrame
			BodyPosition.Position = (Player.Character.HumanoidRootPart.CFrame * CFrame.new(Position)).p - Vector3.new(0, Player.Character.HumanoidRootPart.Size.Y / 2, 0) + Vector3.new(0, Pet.Size.Y, 0)
			wait()
		end)
	end)
end

local function GetPointOnCircle(CircleRadius, Degrees)
	return Vector3.new(math.cos(math.rad(Degrees)) * CircleRadius, 0, math.sin(math.rad(Degrees)) * CircleRadius)
end

local module = {
	Summon = function()
		local PlayersData = getPlayerData:InvokeServer()
		for index, value in pairs(PlayersData.Equipped) do
			if Player.Character:FindFirstChild(PlayersData.Equipped[index].Name) then return end
			local Pet = ReplicatedStorage.Pets:FindFirstChild(PlayersData.Equipped[index].Name):Clone()
			Pet.Parent = Player.Character
			
			local BodyPosition = Instance.new("BodyPosition")
			local BodyGyro = Instance.new("BodyGyro")
			
			BodyGyro.D = 750
			BodyGyro.MaxTorque = Vector3.new(25000, 25000, 25000)
			BodyGyro.P = 5000
			
			BodyPosition.D = 400
			BodyPosition.MaxForce = Vector3.new(1250, 10000, 1250)
			BodyPosition.P = 6500
			
			BodyGyro.Parent = Pet.PrimaryPart
			BodyPosition.Parent = Pet.PrimaryPart
			
			Follow(Pet.PrimaryPart, GetPointOnCircle(5, (360/#PlayersData.Equipped) *index), BodyGyro, BodyPosition)
		end
	end
}

return module

Secondly, I’m struggling to handle the actual pets and their creation on the client to reduce the stress and resource consumption placed on the server but I have no idea how to make all of the pets appear for a player who has joined after the pets get loaded;

Here’s the code for that:

--// Services \\--

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local ServerScriptService = game:GetService("ServerScriptService")

local Players = game:GetService("Players")

--// Events \\--

local Events = ReplicatedStorage:WaitForChild("Events")

local RemoteEvents = Events:WaitForChild("RemoteEvents")

local RemoteFunctions = Events:WaitForChild("RemoteFunctions")

--// Remotes \\--

local ClientEffects = RemoteEvents:WaitForChild("ClientEffects")

local getPlayerData = RemoteFunctions:WaitForChild("getPlayerData")

--// Variables \\--

local Datastore = require(script:WaitForChild("Datastore"))

--// Scripting \\--

--// Data \\--

Players.PlayerAdded:Connect(function(Player)

Datastore.setupData(Player)

Datastore.loadData(Player)

--print(PlayerData.Equipped[1].Name) Works

Player.CharacterAdded:Connect(function(Character)

local PlayerData = Datastore.getData(Player)

ClientEffects:FireAllClients({

Module = "Pet Manager",

Function = "Summon",

Data = {["PlayersData"] = PlayerData}

})

end)

end)

Players.PlayerRemoving:Connect(function(Player)

Datastore.saveData(Player)

Datastore.endData(Player)

end)

getPlayerData.OnServerInvoke = function(Player)

return Datastore.getData(Player)

end
1 Like

dunno mate, hope you find a solution

For the first one, I dont know.
But what do you mean in the second one? Do you want to have the pets only locally or do you want the ability that others can see the pets aswell?