bloxlibs/betterscale

Responsive UI scaling for Roblox. Set it up once and forget about it.

BetterScale

Responsive UI scaling for Roblox. Set it up once and forget about it.

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.

local BetterScale = require(ReplicatedStorage.BetterScale)
local betterScale = BetterScale.new(yourUIScale)
betterScale:Track()

Done.


Installation

Manual — drop the module into ReplicatedStorage.

Wally — add to your wally.toml and run wally install:

[dependencies]
BetterScale = "blox-libs/betterscale@latest"

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).
InnerRatiosstring (JSON)Per-device ratio overrides.

Examples

Mobile needs bigger UI

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

Horizontal-only scaling

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

Scale down slightly on large monitors

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

How it works

On every resize event, BetterScale computes currentScreenSize / referenceResolution on the configured axis. The result is multiplied by Ratio — with any matching InnerRatios entry folded into Ratio directly — then clamped to Range.

Updates are scheduled via RunService.RenderStepped:Once so multiple resize events in the same frame produce a single scale write. When nothing changes, nothing runs.


API

-- Create an instance
local betterScale = BetterScale.new(uiScale: UIScale)

-- Start tracking (calculates immediately, then on every resize)
betterScale:Track()

-- Pause tracking without destroying the instance
betterScale:UnTrack()

-- Clean up fully when done
betterScale:Destroy()

Supported containers

ScreenGui · BillboardGui · SurfaceGui · DockWidgetPluginGui


Projects using BetterScale

ProjectLink
Squid Game TowerView
Squid Game Troll TowerView

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