i think i found out the issue, it was my StreamingEnabled, and my renderdistance system that occludes objects if they are far, when i turned StreamingEnabled off, everything fixed, was there any updates with StreamingEnabled? i believe its a memory leak or something because i did not touch my render for weeks and when i turned StreamingEnabled off, it stopped happening
here is the render script:
-- Services
local RunService = game:GetService'RunService'
local Players = game:GetService'Players'
local CollectionService = game:GetService'CollectionService';
-- Variables
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local RootPart = Character:WaitForChild'HumanoidRootPart'
local Data = LocalPlayer:WaitForChild'Data';
local Settings = Data:WaitForChild'Settings';
-- Constants
local RENDER_DISTANCE = 600 -- Adjust this value as needed (in studs)
local MIN_ROTATION_DISTANCE = 350;
local MIN_FLOATING_DISTANCE = 350;
local UPDATE_INTERVAL = 0.15 -- How often to check distances (in seconds)
local StoredCoins = Instance.new'Folder'
StoredCoins.Name = 'StoredCoins'
local function IsValidChar(char)
return char and char.Parent and char:FindFirstChild'HumanoidRootPart'
end
local function ProcessCoins(Coins, PlayerPos)
local CoinsToStore = {}
local CoinsToRender = {}
for _, Coin in ipairs(Coins) do
if Coin and Coin:IsA'BasePart' then
local Dis = (PlayerPos - Coin.Position).Magnitude
local IsTaken = Coin:GetAttribute'FullyTaken'
if Coin.Parent == workspace.Coins then
-- Store Coins that are either too far away OR have the IsTaken attribute
if Dis > RENDER_DISTANCE or IsTaken then
table.insert(CoinsToStore, Coin)
end
elseif Coin.Parent == StoredCoins then
-- Only render Coins that are within range AND don't have IsTaken attribute
if Dis <= RENDER_DISTANCE and not IsTaken then
table.insert(CoinsToRender, Coin)
end
end
end
end
return CoinsToStore, CoinsToRender
end
local function InitRenderSystem()
local CoinsFolder = workspace:WaitForChild'Coins'
local LastUpdate = 0
LocalPlayer.CharacterAdded:Connect(function(newCharacter)
Character = newCharacter
RootPart = Character:WaitForChild'HumanoidRootPart'
end)
RunService.Heartbeat:Connect(function(DT)
LastUpdate = LastUpdate + DT
local Settings = _G.Decode(LocalPlayer.Data.Settings.Value);
local CoinsChildren = CoinsFolder:GetChildren()
local FloatingObjects = CollectionService:GetTagged'FloatingObject';
local StoredFloatingObjects = CollectionService:GetTagged'StoredFloatingObjects';
local RotatingObjects = CollectionService:GetTagged'RotatingObject';
local AllObjects = {}
if Settings.PerformanceMode == false then for _, Obj in CoinsChildren do table.insert(AllObjects, Obj) end end
for _, Obj in RotatingObjects do table.insert(AllObjects, Obj) end
for _, Coin in AllObjects do
if not Coin:IsA'BasePart' then continue end
if Coin:GetAttribute'FullyTaken' then continue end
if not Coin:HasTag'Hatchet' and Settings.PerformanceMode == true then continue end
local Dis = Coin:HasTag'Hatchet' and MIN_ROTATION_DISTANCE*30 or Coin:HasTag'RotatingObject' and MIN_ROTATION_DISTANCE * 10 or MIN_ROTATION_DISTANCE
if (Coin.Position - workspace.CurrentCamera.CFrame.Position).Magnitude > Dis then continue end
if Coin:HasTag'RotatingObject' then
local Speed = Coin:GetAttribute'Speed' or 30
local Axis = Coin:GetAttribute'Axis' or 'Y'
local NegDirection = Coin:GetAttribute'NegDirection' or ''
local XRotation = string.find(Axis, 'X') and math.rad(Speed * DT) or 0
local YRotation = string.find(Axis, 'Y') and math.rad(Speed * DT) or 0
local ZRotation = string.find(Axis, 'Z') and math.rad(Speed * DT) or 0
if string.find(NegDirection, 'X') then XRotation = -XRotation end
if string.find(NegDirection, 'Y') then YRotation = -YRotation end
if string.find(NegDirection, 'Z') then ZRotation = -ZRotation end
Coin.CFrame = Coin.CFrame * CFrame.Angles(XRotation, YRotation, ZRotation)
else
Coin.Orientation += Vector3.new(0, 170 * DT, 0)
if Coin:FindFirstChild'Ring' then
Coin.Ring.Orientation += Vector3.new(0, 170 * DT, 0)
end
end
end
for _, Object in FloatingObjects do
if (Object:GetPivot().Position - workspace.CurrentCamera.CFrame.Position).Magnitude > MIN_FLOATING_DISTANCE then
-- If the object is too far, move it to StoredFloatingObjects
if Object:HasTag'FloatingObject' then
Object:RemoveTag'FloatingObject'
Object:AddTag'StoredFloatingObjects'
end
else
-- If the object is renderable, ensure it has the FloatingObject tag
if not Object:HasTag'FloatingObject' then
Object:AddTag'FloatingObject'
end
end
end
for _, Object in StoredFloatingObjects do
if (Object:GetPivot().Position - workspace.CurrentCamera.CFrame.Position).Magnitude <= MIN_FLOATING_DISTANCE then
-- If the object is renderable, move it to FloatingObjects
if Object:HasTag'StoredFloatingObjects' then
Object:RemoveTag'StoredFloatingObjects'
Object:AddTag'FloatingObject'
end
end
end
if LastUpdate < UPDATE_INTERVAL then
return
end
LastUpdate = 0
if not IsValidChar(Character) then
return
end
local PlayerPos = RootPart.Position
local AllCoins = {}
for _, Coin in CoinsChildren do
table.insert(AllCoins, Coin)
end
for _, Coin in StoredCoins:GetChildren() do
table.insert(AllCoins, Coin)
end
-- Process all Coins at once
local CoinsToStore, CoinsToRender = ProcessCoins(AllCoins, PlayerPos)
-- Update Coin parents
for _, Coin in CoinsToStore do
if Coin and Coin.Parent == CoinsFolder then
Coin.Parent = StoredCoins
end
end
for _, Coin in CoinsToRender do
if Coin and Coin.Parent == StoredCoins then
Coin.Parent = CoinsFolder
end
end
end)
end
-- Start the system
InitRenderSystem()
If you want my honest opinion, i believe its due to StreamingEnabled memory leak or something, since this script is on the client, there is no reason it should act like this…