Hey guys i been working on a pixel based game engine for roblox for a while now and i’ve run into a few problems…
Does anyone know if there is a limit for ui objects?
As when i add too any ui object, frames buttons, images etc they being to flicker and vanish.
So if there is a limit what is it?
What type of ui object count towards it?
Does an object being invisible stop it counting towards the limit?
Is there any ways to increase the limit? (doubling it would be amazing.)
And linking me any other documentation regarding roblox’s UI system would be awesome! I’ve looked but i cant find much of the technical stuff.
Anyways hope your game is going well too… Screenshots of project below… Take it easy dudes.
I don’t think there is an actual limit, none of the documentation I’ve seen would suggest. Likely things are vanishing as the client is handling memory. A few things I could recommend though:
UI elements that are invisible remove it from the rendering pipeline, but best practice is to set their Disabled status to True when they are not needed. Benchmarking may be needed to see if there is a practical benefit.
UI elements that become “off-screen” will begin to disappear; if they are flickering, perhaps they’re right at that edge. You can see this if you scale a frame to something like (5,0,5,0) and start moving it off-screen, it will eventually disappear despite part of it being visible at that time. Whether they’re deemed off-screen or not is dependant on their AbsolutePosition as far as I am aware.
Is it right to assume every tile is its own UI element? You might look into reducing the number of instances the client has to handle by implementing some form of greedy tiling (I believe that’s the right word? Same theory as greedy meshing in voxel rendering).
Hey dude thanks for the reply… Just to correct things - I’m not using StarterGui, sprites are places within the workspace on parts. Each part has a surface gui with 1-64 frames on it depending on the shape of the sprite. So I may have kinda mislead by talking about GUI without clarifying - dunno how much that changes things tho…
Although they do appear to count towards the same limit (memory or not) i can stop the flickering by deleting parts with surface GUI’s or by setting enabled = false on Starter Gui objects.
Does anyone know what section of the Debug console GUI memory info is kept?
The property that seems to effect it as far as i can make out is SurfaceGui.Enabled and Frame.Visible…
I think im going to have to code a benchmarking program
I dont wanna lose one of my parallax scrolling layers
Yes there is actually a limit. Or at least there was at one point, I’m not sure if there still is. The limit was put into place in order to stop bad actors (mainly exploiters during the FilteringDisabled days) from generating inappropriate images using hundreds or thousands of tiny frames acting as pixels (thereby generating an image bypassing decal moderation). It may still be enforced as it could still be used that way, however the responsibility would obviously be on the game developer at that point.
Additionally, Roblox’s UI isn’t very performant. They did mention in a prior RDC that they’d be working to completely overhaul and improve it though.
Cool thanks for confirming…Although im still more of the understanding that this is an inbuilt memory limit for roblox rather than a purposeful moderation decision. as i can quite easily create pictures up to 600x600… plenty of room to create an inappropriate image…
I think if im super clever i should be able to work within the limit and keep performance up… I will have to implement a report content and quarantine system… thanks for reminding me of that.
Well it may be memory as their update was just making pixels white. This was definitely purposeful as it worked before, then stopped working (becoming white).
Really great resource… already implementing something similar… I should be able to reduce the usage of frame by most blocks by about 50% so i think thats more than enough gain to keep it running and avoid the flicker… I will have a problem with animated textures as they could still overlead the system… but i think i’ll just allow that… Like your shouldnt need every block animated and you certainly wont need ever block on each of the layer animated…
So yeah thanks guys think you helped fix this.
woop thanks guys - this is what i came up with - it only makes greedy rows but it runs so fast i can run it on every block on every tik and it saves about 60% on assets. YAY!
function module.greedySpriteFromTable(holder,spriteTable,paletteDictionary,transparency)
local holderTable = holder:GetChildren()
holderTable = quickSort(holderTable)
--go through sprite table if next item in same row is of same value then add to bundle
local rNo = 8
local cNo = 8
local rPos = 1
local cPos = 1
local greedyBundle ={}
repeat
rPos = 1
repeat
local currentCol = columns[cPos]
local currentPos =currentCol[rPos]
local colorChar = spriteTable[currentPos]
local colour = paletteDictionary[colorChar]
local length = 1
if colorChar == "z" then -- if pixel invisible
holderTable[currentPos].Visible = false
elseif spriteTable[currentPos] == spriteTable[currentPos+length] then -- if next pixel is same colour
while rPos + length <= rNo and spriteTable[currentPos] == spriteTable[currentPos+length] do -- break loop if colour check fails.
holderTable[currentPos+length].Visible = false
length = length +1-- increment length to check pixel after next
end
table.insert(greedyBundle,{length,rPos,cPos,colorChar})
rPos=rPos +length-1 --skip neighbouring pixels detected to have matching colours
else
holderTable[currentPos].BackgroundColor3 = colour
holderTable[currentPos].Visible = true
holderTable[currentPos].Size = UDim2.new(0.125,0,0.125,0)
holderTable[currentPos].Position = UDim2.new(0.125*(rPos-1),0,0.125*(cPos-1),0)
if transparency then
holderTable[currentPos].BackgroundTransparency = transparency
end
end
rPos = rPos+1
until rPos > rNo
cPos = cPos +1
until cPos> cNo
--apply greedyBundle Changes
for i,v in ipairs(greedyBundle)do
local currentCol = columns[v[3]]
local currentPos =currentCol[v[2]]
local colorChar = spriteTable[currentPos]
local colour = paletteDictionary[colorChar]
holderTable[currentPos].Size = UDim2.new(0.125*(v[1]),0,0.125,0)
holderTable[currentPos].Position = UDim2.new(0.125*((v[2]-1)),0,0.125*(v[3]-1),0)
holderTable[currentPos].BackgroundColor3 = colour
holderTable[currentPos].Visible = true
end
end
Soz dude its in a super broken state at the mo - im having to re-do everything from the ground up… Its going super well tho its like 200 times faster… means i might be able to add like 5 more parralax layers XD or double the sprite size… But i’ll try and keep you guys updated!