bloxlibs/betterscale

A UI scaling solution for Roblox, without the headache.

BetterScale

A UI scaling solution for Roblox, without the headache.

License Wally Pesde


Roblox's built-in scaling tools have real gaps. AutomaticSize breaks layouts. AutomaticCanvasSize is unreliable. There's no built-in way to say "I designed this for 1080p, scale it accordingly."

BetterScale fixes this by managing a UIScale for you: it computes the ratio between the player's screen and your reference resolution, applies any overrides you've configured, and keeps it updated on resize.


Setup

local uiScale = script.Parent.UIScale

-- Resolution you designed at (default: 1280×720)
uiScale:SetAttribute("Resolution", Vector2.new(1920, 1080))

-- Clamp so extreme screens don't break anything
uiScale:SetAttribute("Range", NumberRange.new(0.5, 2.0))

local betterScale = BetterScale.new(uiScale)
betterScale:Track()

All configuration is done through attributes on the UIScale instance. You can set them in the Properties panel in Studio — no code required.

AttributeTypeDefaultDescription
ResolutionVector21280, 720Reference resolution you designed for.
Rationumber1.0Global multiplier on top of the computed scale.
RangeNumberRangeMin/max clamp for the final scale value.
AxisEnumXYScale by width (X), height (Y), or both (XY).
DisplayRatiosstring (JSON)Per-device ratio overrides.

Examples

Mobile needs bigger UI

uiScale:SetAttribute("DisplayRatios", '{"Small": 1.3}')

Horizontal-only scaling

uiScale:SetAttribute("Axis", Enum.ScrollingDirection.X)

Scale down slightly on large monitors

uiScale:SetAttribute("DisplayRatios", '{"Large": 0.9}')

How it works

On every resize, BetterScale computes screenSize / resolution on the configured axis, clamps it to Range, then multiplies by Ratio (with any matching DisplayRatios entry already folded in). The result goes straight to UIScale.Scale.

The initial update after Track() is deferred to the next RenderStepped frame so the UI has time to lay out first.


API

local BetterScale = require(path.to.BetterScale)
local uiScale = path.to.UIScale

-- Configure scaling attributes
uiScale:SetAttribute("Ratio", 1.2)
uiScale:SetAttribute("Range", NumberRange.new(0.5, 2.0))
uiScale:SetAttribute("Resolution", Vector2.new(1920, 1080))
uiScale:SetAttribute("Axis", Enum.ScrollingDirection.X) -- X | Y | XY
uiScale:SetAttribute("DisplayRatios", '{"Large": 0.8, "Small": 1.3}')

-- Quick usage: create + track in one call
local cleanup = BetterScale.build(uiScale)
cleanup()

-- Or manual control
local betterScale = BetterScale.new(uiScale)
betterScale:Track()

-- Force a refresh manually
betterScale:Update()

-- Type checking
if BetterScale.is(betterScale) then
	print("It's a BetterScale instance!")
end

-- Later cleanup
betterScale:Destroy()

Projects using BetterScale

ProjectLink
Squid Game TowerView
Squid Game Troll TowerView

Using BetterScale in your project? Contact PcoiDev to get listed.