Skip to main content

1.4.x — Key system & premium tier

Released across v1.4.0 – v1.4.4.


Key system

Add a keySystem block to src/layout.ts to gate the entire UI behind a key:

keySystem: {
title: 'Key Required',
note: 'Get your free key from our Discord',
saveKey: true, // persist key to executor filesystem
getKeyUrl: 'https://discord.gg/example',

// Option A — static list (client-side):
keys: ['FREE_KEY_1', 'FREE_KEY_2'],

// Option B — server-side validator (more secure):
// validatorUrl: 'https://yoursite.com/validate?key=',
},

Without a keySystem block the script runs without any key prompt — nothing changes for existing scripts.


Premium tier

A second key layer on top of the free tier. Users with a premium key get access to additional groupboxes — no re-injection required.

premium: {
keys: ['PREMIUM_KEY_1'],
// OR: validatorUrl: 'https://yoursite.com/premium?key=',
getKeyUrl: 'https://yoursite.com/premium',
},

Mark groupboxes as premium in your page files:

groupbox('left', 'Aimbot', { icon: 'crosshair', mount: 'Aimbot', premium: true })

What users see: Each { premium: true } groupbox shows a locked-state UI — a key input, a Copy Link button, a Check Key button, and a status line. When the user enters a valid premium key, all premium groupboxes across the entire script unlock live via dynamic component mounting. No re-injection. No page reload.

Premium keys also grant basic key-system access automatically — one key for everything.


Signal engine fix

Fixed a silent infinite-recursion bug in the reactive signal engine.

Root cause: the _signal() helper overrode s.set using s:set(v) — which is Lua colon-call sugar for s.set(s, v). After the override, every s.set call would call itself recursively until stack overflow. WindUI's internal pcall caught the overflow silently, so toggle widgets appeared to fire (the log line appeared before the recursive call) but had no effect on the game.

Fix: capture the original method before overriding:

local _rawSet = s.set
s.set = function(_, v) _rawSet(s, v) end
s.toggle = function(_) _rawSet(s, not s:get()) end

This is the correct pattern for all signal method overrides.


IronBrew banner auto-stripped

The --[[ IronBrew 2 ... ]] comment block that Ironbrew2 prepends to obfuscated output is now automatically removed by the build pipeline. The final build/script.obf.lua starts cleanly with the re-execution guard, as expected.


Dev tab improvements

  • Open Console button added to the Dev tab Console section — fires StarterGui:SetCore("DevConsoleVisible", true) without needing to open the Roblox menu
  • Executor detection fixed for proxy-env executors — switched from rawget(_G, "identifyexecutor") (which bypasses __index metamethods) to pcall(function() return identifyexecutor() end), fixing the "Unknown" label on some executors
  • Removed Heartbeat Monitor section and auto-scan on inject (debugging tools that shipped accidentally in 1.3.0)

New rb init scaffold

rb init my-script now scaffolds:

my-script/
src/
layout.ts ← window config + commented keySystem/premium examples
pages/
1_Combat.ts ← Combat tab: 3 free groupboxes + 1 premium Aimbot groupbox
combat/
SpeedHack.ts ← free example component
FOVChanger.ts ← free example component
Aimbot.ts ← premium example component (clearly commented)
visuals/
PlayerESP.ts ← free example component
misc/
globals.lua
remotes.lua
tsconfig.json
CLAUDE.md / AGENTS.md / PULSE_DOCS.md

Changes from 1.3.0:

  • 1_Home.ts renamed to 1_Combat.ts — "Home" is a reserved built-in tab name; user pages must not use "Home" or "Settings"
  • Aimbot.ts added — demonstrates premium component pattern with on.heartbeat at 60 fps throttle
  • layout.ts template now includes version, description, and discord fields, plus fully-commented keySystem and premium example blocks

Reserved page names

The framework creates "Home" and "Settings" tabs automatically. Do not name your pages "Home" or "Settings" — doing so creates a duplicate tab that may not behave correctly.


layout.ts new fields

export default {
title: 'MyScript',
version: '1.0.0', // shown in Home tab info card
description: 'A powerful script for MyScript.', // shown in Home tab
discord: '', // if set, shows "Join Discord" button in Home tab
// ...rest unchanged
} satisfies LayoutConfig