Help me with my code for module

When you’re unloading you’re not removing the old position CFrame, you have both the void and ‘default’ in the same table.

Update the old CFrame when unloading (currently you’re pushing a new one)

1 Like

As i said i tried working with attributes, attribute stored original cframe and it was static i checked, but again, it unloaded the part and never loaded it back. But I will try

What happens is that when load and unload the same object before a update the table is not cleared, this makes so there’s 2 registers of the same part before the update.

Load → Adds the position and part to the table
Unload → Also adds the unload position and part to the table

edit: you should check in the unload function, to see if the part was added already to the table and if so edit the cframe to the void one

1 Like

like so?

for i, movingPart in ipairs(self.MovingParts) do
		if movingPart == Part then
			self.MovingCFrames[i] = self.unloadCFrame
			return
		end
	end

изображение
no worky
изображение
изображение
изображение

изображение

Ok we have some movement right here, now both parts disappear:

-- Created by 1Xayd1
local RenderCache = {}
RenderCache.__index = RenderCache

export type RenderCacheType = {
	MovingParts: {BasePart},
	MovingCFrames: {CFrame},
	OriginalCFrames: {CFrame},
	unloadCFrame: CFrame,
	Updating: boolean,
	new: () -> RenderCacheType,
	Register: (self: RenderCacheType, array: {BasePart}) -> (),
	Update: (self: RenderCacheType) -> (),
	Load: (self: RenderCacheType, Part: BasePart) -> (),
	Unload: (self: RenderCacheType, Part: BasePart) -> ()
}

function RenderCache.new(): RenderCacheType
	local self = setmetatable({}, RenderCache)
	self.MovingParts = table.create(10_000)
	self.MovingCFrames = table.create(10_000)
	self.OriginalCFrames = table.create(10_000)
	self.unloadCFrame = CFrame.new(2^24, 2^24, 2^24)
	self.Updating = false
	return self
end

function RenderCache:Register(array: {BasePart})
	for _, part in ipairs(array) do
		table.insert(self.OriginalCFrames, part.CFrame)
	end
end

function RenderCache:Update()
	if self.Updating then warn("Tried to update while updating, skipping.") return end
	self.Updating = true
	workspace:BulkMoveTo(self.MovingParts, self.MovingCFrames, Enum.BulkMoveMode.FireCFrameChanged)
	table.clear(self.MovingParts)
	table.clear(self.MovingCFrames)
	self.Updating = false
end

function RenderCache:Load(Part: BasePart)
	local index = table.find(self.MovingParts, Part)
	if index then
		self.MovingCFrames[index] = self.OriginalCFrames[index]
	else
		warn("Part not registered in cache!")
		return
	end
	table.insert(self.MovingParts, Part)
end

function RenderCache:Unload(Part: BasePart)
	local index = table.find(self.MovingParts, Part)
	if index then
		self.MovingCFrames[index] = self.unloadCFrame
	end
	table.insert(self.MovingParts, Part)
	table.insert(self.MovingCFrames, self.unloadCFrame)    
end

return RenderCache

Lemme add queue like in Object Cache

Queue didnt help either:

-- Created by 1Xayd1
local RenderCache = {}
RenderCache.__index = RenderCache

export type RenderCacheType = {
	MovingParts: {BasePart},
	MovingCFrames: {CFrame},
	RegisteredCFrames: {[BasePart]: CFrame},
	unloadCFrame: CFrame,
	Updating: boolean,
	LoadQueue: {BasePart},
	UnloadQueue: {BasePart},
	new: () -> RenderCacheType,
	Register: (self: RenderCacheType, array: {BasePart}) -> (),
	Update: (self: RenderCacheType) -> (),
	Load: (self: RenderCacheType, Part: BasePart) -> (),
	Unload: (self: RenderCacheType, Part: BasePart) -> ()
}

function RenderCache.new(): RenderCacheType
	local self = setmetatable({}, RenderCache)
	self.MovingParts = table.create(10_000)
	self.MovingCFrames = table.create(10_000)
	self.RegisteredCFrames = {}
	self.unloadCFrame = CFrame.new(2^24, 2^24, 2^24)
	self.Updating = false
	self.LoadQueue = {}
	self.UnloadQueue = {}
	return self
end

function RenderCache:Register(array: {BasePart})
	for _, part in ipairs(array) do
		self.RegisteredCFrames[part] = part.CFrame
	end
end

function RenderCache:Update()
	if self.Updating then 
		warn("Tried to update while updating, skipping.") 
		return 
	end
	self.Updating = true

	for _, part in ipairs(self.LoadQueue) do
		table.insert(self.MovingParts, part)
		table.insert(self.MovingCFrames, self.RegisteredCFrames[part])
	end

	for _, part in ipairs(self.UnloadQueue) do
		table.insert(self.MovingParts, part)
		table.insert(self.MovingCFrames, self.unloadCFrame)
	end

	workspace:BulkMoveTo(self.MovingParts, self.MovingCFrames, Enum.BulkMoveMode.FireCFrameChanged)
	table.clear(self.MovingParts)
	table.clear(self.MovingCFrames)
	table.clear(self.LoadQueue)
	table.clear(self.UnloadQueue)
	self.Updating = false
end

function RenderCache:Load(Part: BasePart)
	if not self.RegisteredCFrames[Part] then
		warn("Part not registered in cache!")
		return
	elseif self.Updating then
		warn("Cannot load | unload objects while updating.")
		return
	end
	table.insert(self.LoadQueue, Part)
end

function RenderCache:Unload(Part: BasePart)
	if not self.RegisteredCFrames[Part] then
		warn("Part not registered in cache!")
		return
	elseif self.Updating then
		warn("Cannot load | unload objects while updating.")
		return
	end
	table.insert(self.UnloadQueue, Part)
end

return RenderCache

The self.Updating logic doesnt seem required in the given code. Since you are doing the update in a single frame (without yielding) anyway other code logic wont even notice the change.

Also, I was unable to reproduce the bug you were dealing with.

Here is a script Load()ing and Unload()ing a part every one fourth of a second:

Please help me understand :D

how… Give me that place right now!

local RenderCache = require(script.Parent)

local GamingCache = RenderCache.new()

local Part = workspace.Part

GamingCache:Register({Part})

game:GetService("RunService").Stepped:Connect(function()
	GamingCache:Update()
end)

while true do
	task.wait(1 / 4)
	
	GamingCache:Unload(Part)
	
	task.wait(1 / 4)
	
	GamingCache:Load(Part)
end

Just doing this with the first ever modulescript code you attached in this post.
Seems to work just fine.

I update the cache every time i unload or load the part
not every frame, hmmmm

wait actually what the hell its working

I have no idea why though, releasing the module today!

Yes this is what I was asking about!

For example if you do something like this:

while true do
	task.wait(1 / 4)

	Cache:Unload(Part)

	task.wait(1 / 4)

	Cache:Load(Part)
	
	Cache:Update()
end

The part will appear if so the part never dissapeared. (Yes! Even with the delays in between since thats how update() works)

The issue is here, you have a queue which gets processed every time :Update() is called (which uses FIFO logic but I will not go over that).

If you were to for example do

Cache:Unload(Part)
Cache:Load(Part)
Cache:Update()

The part would appear as it had never loaded out.
Which is OK!

But could cause confusion to where to use update() with, connecting it to an event like RenderStepped gives the developer an ease of use.

This is a performance concern too, what if thousands of parts load out and load in at the same time?
As far as I know BulkMoveTo() function does not check for duplicates in the table you provided it with.

This is not how i used module as you provided it. It was exactly the same as your script, so its not my fault. And I am not so dumb for you to explain it like this :skull: Edit: it was roblox’s issue

1 Like
1 Like

Thats how I usually explain stuff sorry you thought that way :sweat_smile:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.