AROYN UI LIBRARY / ADVANCED

Configuration manager

Named local JSON profiles, explicit flags and silent restoration.

Configure before registering flags#

LUAU
local window = Aroyn:CreateWindow({
    Parent = parent, Id = "preferences",
    Config = {Namespace = "my-game", AutoLoad = false, AutoSave = false},
})
local section = window:CreatePage({Name = "Settings", Icon = "settings"})
    :CreateSection({Title = "Preferences"})
local enabled = section:CreateToggle({Name = "Enabled", Flag = "enabled", Default = false})
section:CreateTextInput({Name = "Private value", Flag = "private", Sensitive = true})

local ok, info = window:SaveConfig("main")
if not ok then warn(info.Code, info.Message) end
window:LoadConfig("main") -- silent by default
Aroyn Configurations page in Roblox reporting Local files, main profile name, saved configuration selector and Save Load Delete Reset defaults actions.Open full size ↗
The local-files configuration panel in the standalone showcase. This capture shows the controls, not a persistence test.

Options#

OptionTypeDefaultMeaning
Namespacestring"default"Safe lowercase application/game identifier.
FileSystemtable?nilSynchronous adapter; nil selects available executor globals.
DefaultConfigstring?nilFallback name for AutoLoad=true and AutoSaveConfig.
AutoLoadboolean | stringfalsetrue loads DefaultConfig or main; a string loads that name.
AutoSavebooleanfalseOpt-in debounced writes after changes.
AutoSaveConfigstring?DefaultConfig or "main"Independent of the last profile loaded.
AutoSaveDelayfinite number0.750.2–60 seconds.

ConfigureConfig can initialize an existing window before any Flag. The first registration otherwise creates the default manager. A second ConfigureConfig returns AlreadyConfigured. Invalid configuration options return InvalidOptions; invalid Config passed during CreateWindow/AttachWindow can assert.

Public methods#

MethodReturnsBehavior
ConfigureConfig(options?)ok, infoBefore the first Flag; cannot reconfigure.
RegisterConfig(control, flag, options?)controlRegister an existing owned control; options Persist/Sensitive.
GetConfigState()tableIndependent JSON-compatible snapshot; does not write a file.
GetConfigStatus()tableMode, Namespace, Path, Capabilities, AutoSave, AutoSaveConfig, AutoSaveDelay, LastResult.
SaveConfig(name)ok, infoSave current registered values and valid deferred entries.
LoadConfig(name, options?)ok, infoRestore; InvokeCallbacks=false by default.
ListConfigs()ok, infoSorted names in info.Names.
DeleteConfig(name)ok, infoDelete profile; cancel pending save for its name.
ResetConfig(options?)ok, infoRestore registered defaults, clear deferred; saved files remain.
SetConfigAutoSave(enabled, name?, delay?)ok, infoEnable/disable; enabling does not write immediately.

Flags and exclusion#

Flag must be unique per Window, not per section: 1–64 ASCII letters/digits/underscore/hyphen, starting with a letter or digit. Name and construction order are not identifiers. Without a Flag, a value is not saved. RegisterConfig captures the default at registration.

Persist=false or Sensitive=true excludes that flag, including imported entries. JSON is plain text without encryption. No automatic token detection exists. Declare sensitive controls before loading; unknown valid flags are deferred until the library learns their type and exclusion policy.

Storage and schema#

File paths are relative to the executor workspace: AroynUILab/configs/<namespace>/<name>.json. Names and namespaces normalize to lowercase. Paths, extensions, periods, spaces and Windows device names are rejected. This format does not import old production Hub settings.

JSON
{
  "SchemaVersion": 1,
  "Namespace": "my-game",
  "Values": {
    "enabled": {"Type": "Toggle", "Value": true},
    "volume": {"Type": "Slider", "Value": 75},
    "mode": {"Type": "Dropdown", "Value": "Quiet"},
    "categories": {"Type": "Dropdown", "Multi": true, "Value": ["Pets"]},
    "note": {"Type": "Input", "Value": "Local note"},
    "shortcut": {"Type": "Keybind", "Value": {"Key": "H", "Mode": "Hold"}},
    "color": {"Type": "ColorPicker", "Value": {"R": 0.4, "G": 0.5, "B": 0.6}}
  }
}

Only SchemaVersion=1 is accepted. An empty single choice uses Value=false, a multi uses an empty array/table. Color channels are finite 0–1 numbers. Keybind stores the enum name or "None" and mode; it excludes active/pressed state.

Load and validation#

A missing, empty, corrupt, oversized (>256 KiB), wrong-namespace or unsupported-schema document returns an error without changing the UI. Up to 512 flags are supported. An invalid individual value is skipped with warnings; absent values retain current state. Save rejects invalid or oversized snapshots before writing.

Slider values clamp/quantize. Multi choices filter duplicates and removed options. A removed single choice falls back to an available construction default or nil. Invalid RGB, keys, modes, types and numbers are skipped. Text is limited to 16 KiB of UTF-8 bytes.

Valid unknown flags remain deferred for later registrations and round-trip through Save. A new Load replaces old deferred entries; Reset clears them. Load returns Applied, Deferred, Skipped and Warnings. Callbacks are silent unless InvokeCallbacks=true; activation is still suppressed. Changed controls receive at most one ordinary callback.

Filesystem capabilities#

CapabilityBehavior
readfile + writefileFile mode based on presence, not proof of successful I/O.
Either missingSession mode: in-memory snapshots for this window only. Destroy or rerun loses them.
isfile / isfolder / makefolderUsed when available. Without folder APIs the directory must already exist.
listfilesEnumerates relative or absolute paths. Without it, the manager uses __index.json.
delfileRequired for deletion in File mode; otherwise DeleteUnsupported.

FileSystem supplies plain synchronous functions, not methods requiring self. readfile(path) returns a string or throws; writefile(path, json), makefolder(path) and delfile(path) must throw on failure. Returning false from a custom writefile is not treated as an error. listfiles(directory) returns a table of path strings.

AutoSave and AutoLoad#

LUAU
window:SetConfigAutoSave(true, "main", 0.75)
-- Only later changes schedule a write. Loading "other" does not
-- silently change the AutoSave destination.
local status = window:GetConfigStatus()
print(status.Mode, status.AutoSaveConfig)
if status.LastResult then print(status.LastResult.Code) end

AutoSave uses one debounce task per Window. Text edits and slider/color drags update pending state without writing every event. Manual Save, Load, Reset, disabling AutoSave and Destroy cancel the pending task. Destroy does not perform a hidden final flush. Check LastResult for automatic failures.

AutoLoad runs when the manager is created, before flags, and restores deferred values on registration. Check GetConfigStatus().LastResult immediately: ConfigureConfig returning Configured is not proof that the load succeeded. Explicit Load after constructing controls is easier to handle reliably.

Results and errors#

Operations normally return ok plus info containing Success, Code, Message and Mode. Success codes include Configured, Saved, Loaded, Listed, Deleted, Reset and AutoSaveChanged. A pre-manager invalid options result may not contain Mode.

Error familyCodes
Arguments / stateInvalidOptions, AlreadyConfigured, InvalidName, InvalidState, EncodeFailed
DocumentMissing, Empty, TooLarge, Corrupt, SchemaUnsupported, InvalidDocument
FilesystemReadFailed, WriteFailed, FolderFailed, ListFailed, DeleteUnsupported, DeleteFailed
Index / operationIndexInvalid, IndexWriteFailed, Busy, OperationFailed

A partial index error can include FileSaved=true or FileDeleted=true. Inspect the full result before retrying. Do not disguise an I/O error as a successful Session-mode operation.

Reliability boundary#