My game's memory optimisation sucks. Please help

i’m going to blur this. i warn you, this is SERIOUS.

im sorry

i am sorry if you had the displeasure of unblurring that image. it hurt me too.

my game is about climbing up a ton of parts! the issue is it’s a big game. with lots of parts. 66,666 parts, actually.

i want to keep as MANY parts as possible for the best user experience while also optimising so you don’t get… THAT :nauseated_face:

here is a comparison of StreamingTargetRadius 800 vs 100:
im sorry
image
yeah, not much of a difference

-- dramatically oversimplified for viewing pleasure

task.spawn(function()
	while task.wait(1)
		-- check if user has over 100,000 distance and award badge (zero checks on whether they already have it or not)
	end
end)

while task.wait(0.1) do
	-- monitor differences between old and new position
	local dist = (new_position - old_position)
	local new_y = math.clamp(dist.Y, 0, math.huge)
	dist = Vector3.new(dist.X, new_y, dist.Z)
end

i looked at this post and followed it, but it didn’t really help.

extra context

every part is anchored
it goes in a random position between -800 and 800 (x, y, z)
it has a random size between 1 and 30 (x, y, z)
if the part is below Y 0 it is a spawn point and gets a spawn location decal
it has a random material (i removed this, nothing much changed)

the script is split up into 1,250 chunks in order to prevent crashing

-- PARTS_TO_GENERATE is 66,666
for i = 1, 1250 do
	for i = 1, PARTS_TO_GENERATE / 1250 do
		generate_part()
	end
	task.wait()
end

any help would be seriously appreciated. please. i need help. please.

3 Likes

are you spawning all the chunks on startup?

1 Like

If your part generation is deterministic (aka always has the same result whether you were to run it now or a day later), you could generate only the parts you need and only on the client. This means the server doesn’t have to send any parts via the network, and the client only stores the parts it needs (which are in view).

Could you provide more context? Are these screenshots from studio or in a public server? If your game isn’t deterministic, why not and how are you generating the parts? Could we move the generation to the client?

1 Like

yes. it all spawns at the start in mini chunks

it all uses math random, all screenshots are from studio. it’s all random every game so every player has a unique experience. for extra context on parts, read my “extra info” drop-down. this game is multiplayer, can you expand on the “creating on client” thing?

are you sure that parts are causing the high memory usage?
open the console and check the top things consuming memory
{6D7A0934-E22E-4208-98C8-6B3D94B46B3C}

also, memory usage in studio is higher than memory usage on the roblox app

2 Likes

keep it cached away, don’t do that

1 Like

There’s the issue. Try checking the memory usage in a public server, so outside of studio. When you look at the memory usage in studio, that includes the server’s usage as well.

1 Like

i’d create a hashmap cache of the chunks that actively calls math.random generation for abt 10 chunks above the player position in the hashmap and delete the 25th bottom chunk

1 Like

the size of chunks based on the player’s view,

how many people? 2? 10? 100? does all the tiles need to actively be the same?

I meant that you can generate the map on the client instead of the server so that nothing has to be sent.

You can make sure the “randomness” is the same by setting the seed of the Random object. More info: Random.new(seed)

anything 1 and above (i never set a player cap myself, default is 50 so i guess 50 players)

image
it appears to be much better! still bad, but better

thanks for the advice. will check this out later!

previous post

could you expand on how this could be done?
after converting the script to the client and using Random.new(1) the layout is still different.
am i doing something wrong? i always use math.random() lol.
thanks :wink:

i just forgot to replace some math.random()'s with random:NextInteger() :sob:

could you expand on this too? i am not sure how i can put this into a data structure suitable for my game :laughing:

local SpatialHash = {}
local SpaceMap = {}

type SpatialHash = typeof(SpatialHash) 


local CellSize = 100 -- insert size per chunk

function SpatialHash.SetSize(Input)
    CellSize = Input
end

function SpatialHash.ClearHash()
	SpaceMap = {}
end

function SpatialHash.GetHashKey(Position : Vector3) -- just Y axis in your case
	
	local Y = math.round(Position.Y / CellSize)
	
	return Y
end


function SpatialHash.AddObject(Position: Vector3, Chunks: number) 
	-- Positive chunks means up, negative means down
	
	local Key = SpatialHash.GetHashKey(Position)

	if (SpaceMap[Key] == nil) then
		SpaceMap[Key] = {}
	end

	SpaceMap[Key] = true
	SpaceMap[Key + Chunks] = true
	-- then you just loop thru SpaceMap with GetMap on which chunks to generate
end


function SpatialHash.GetValue(Position : Vector3)
	local Key = SpatialHash.GetHashKey(Position)
	return SpaceMap[Key]
end

function SpatialHash.GetMap()
	return SpaceMap
end


return SpatialHash
local ExampleChunk = {ChunkInstance}
local Cache = {ExampleChunk} -- insert stuff from old hashmap 
local SpaceMap = SpatialHash.GetMap()

local ChunkSize = 10 -- Change this to the size of each chunk
for Value, _ in SpaceMap do
	for CacheValue, _ in Cache do
		if Value ~= CacheValue then
			-- delete the old chunks
				Cache[CacheValue]:Destroy()
				Cache[CacheValue] = nil
			end
	end
end

last part is a lil pseudocode so there might be some bugs, essentially this is the main jist, i dont have time so you’ll have to figure out the other stuff yourself, may be optimizations you could do; tinker around ask chatgpt about hashmaps

1 Like

oh wow.
we’ve gone from this:
old-memory
to…
fixed-memory
this has been one hell of a journey learning how all this optimisation helps improves games

i would like to thank @enpiesie, @birbwithseed and everybody else who has commented on this thread for helping me learn how to utilize memory effectively and efficiently :heart:

3 Likes

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