metauni / metaboard

Multiplayer drawing boards for sharing knowledge in Roblox.
Mozilla Public License 2.0
28 stars 6 forks source link

FrameCanvas relative positioning #68

Closed blinkybool closed 1 year ago

blinkybool commented 1 year ago

From CONTRIBUTING.md

ScreenGui caching

The FrameCanvas renders the board state using Frame instances, which are each assigned a ZIndex so that the figures are layered in the appropriate order. Putting all of the frames into the one ScreenGui would be the natural way to do things (grouped into folders per figure of course). However this introduces a performance issue, since every time a new frame is added, the Roblox Engine recalculates the z-order that it must render all of the frames in.

To solve this problem, we take advantage of the caching behaviour for ScreenGuis (read the caching note at the top of the page). We can use one ScreenGui per figure, and so we're only every recomputing the appearance of one ScreenGui at a time while drawing.

In the current code (see FrameCanvas/SectionedCurve.lua), we actually use a new ScreenGui for every 50 frames. This may not be necessary, and was written early on when Roact and its performance behaviour was a bit of a mystery (to me, Billy). Performance while drawing is being worked on, so FrameCanvas may change a lot.

Canvas positioning/sizing

An annoying consequence of using ScreenGuis per figure is that this resets the hierarchical positioning/sizing of GuiObjects. When you put Frames inside other Frames, you can set the position and size of the child Frame relative to the parent frame by using scalar values in the UDim2 objects. However if this hierarchy is interrupted by a ScreenGui (i.e. Frame > ScreenGui > Frame), the inner Frames will be positioned relative to the entire viewport, not the frame containing the ScreenGui.

This is a problem because the lines need to appear within the board, which we are displaying in a particular sub-region of the board. A natural solution would be to simply apply some numeric transformation of the viewport's coordinates to the canvas region's coordinates. This is complicated a little by the fact that the position and size of the canvas uses aspectRatio and margin contraints, but it seems possible in principle.

Historically, we have instead solved this by placing a copy of the invisible canvas region Frame (along with its sizing/positioning constraints). This has the benefit of not being ruined when you resize the Roblox window, but there is suspicion of this solution incurring a performance cost, so we might dump this benefit in favor of better performance.

blinkybool commented 1 year ago

The TODO here is to try to position the line-frames correctly without putting a copy of the canvas region frame in every single screen gui.

blinkybool commented 1 year ago

Done in 6828d1f This made a massive improvement to writing performance, especially at higher line-counts