ax.util¶
Source: gamemode/framework/util/util_store.lua
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
Section: store
Documented functions: 16
Functions¶
ax.util:CreateStore(spec, oldStore)store:_setupNetworking()store:Add(key, type, default, data)store:Get(...)store:GetAllByCategory(category)store:GetAllCategories()store:GetAllDefinitions()store:GetData(key)store:GetDefault(key)store:HandleConfigChange(regEntry, oldValue, newValue, key)store:Load()store:Save()store:Set(key, value, bNoSave, bNoCallback)store:SetDefault(key, value)store:SetToDefault(key)store:Sync(target)
ax.util:CreateStore(spec, oldStore)¶
Creates and returns a new store instance for managing key/value settings.
A store is a self-contained object that handles registration of typed settings, persistence to a JSON file (or ax.data), optional networking between server and client, and change callbacks. The framework uses two stores: ax.config (server authority, broadcast to clients) and ax.option (client authority, synced to server for server-side reads).
spec fields:
namestring: identifier used in debug messages (e.g."config").authoritystring:"server"or"client"— only that side persists and loads values from disk.pathstring|function:DATA-relative path to the JSON file, or a function(spec, store) → stringfor dynamic paths.nettable: net channel names used for networking:init(bulk sync),set(single key update),sync(option bulk upload),request(server asks client to sync).datatable (optional):{ key, options }forax.data-backed persistence instead of raw JSON.legacyPathstable (optional): array of older paths to migrate data from on first load.
When oldStore is provided (hot-reload scenario), registry, defaults, values, and networkedKeys are copied from it before the new store is configured, preserving runtime state across live code reloads.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
spec |
table |
The store specification (see above). |
oldStore |
table\|nil |
An existing store to migrate state from, used during hot-reload to avoid losing in-memory values. |
Returns
table: The new store object with all methods attached.
Usage
local store = ax.util:CreateStore({
name = "config",
authority = "server",
path = ax.util:BuildDataPath("config"),
net = { init = "ax.config.init", set = "ax.config.set" }
})
store:_setupNetworking()¶
Internal: wires up all net channel receivers and lifecycle hooks.
Called once during store initialisation. If ax.net is not yet available, defers via timer.Simple(0, ...) and retries on the next frame.
Registers the following depending on store type and realm:
- config/server:
PlayerReadyhook (sends initial values to joining clients);spec.net.setreceiver (admin-only remote config changes). - config/client:
spec.net.initreceiver (bulk initial values);spec.net.setreceiver (individual key updates from server). - option/server:
spec.net.syncreceiver (bulk preference upload);spec.net.setreceiver (single key updates);PlayerDisconnectedhook (cleans up SERVER_CACHE); exposesstore.RequestPlayerSync. - option/client:
spec.net.requestreceiver (triggersSync);InitPostEntityhook (auto-syncs after 2 seconds).
Also registers a ShutDown hook on the authority side to call Save.
This is an internal method — do not call it directly.
Realm: shared
store:Add(key, type, default, data)¶
Registers a new key/type/default definition in the store.
After registration, the key is available for Get and Set. The initial value is loaded from persisted data (if available and on the authority side), coerced to the registered type, and stored. If persisted data is absent or fails coercion, the default is used.
Keys are automatically added to store.networkedKeys unless data.bNoNetworking = true.
data fields:
categorystring: grouping label for UI (default"general").bNoNetworkingboolean: exclude this key from network sync.bServerOnlyboolean: (config only) value lives only on the server and is never transmitted to clients. ImpliesbNoNetworkingand skips registration entirely on the client side, soax.config:Geton the client returns the caller's fallback rather than a misleading default.min/maxnumber: clamp bounds applied when the type isax.type.number.decimalsnumber: decimal precision for number clamping.choicestable /populatefunction: valid values forax.type.array.populate()is called to build the choices list dynamically.OnChangedfunction: callback(oldValue, newValue, key)fired when the value changes (unlessbNoCallbackis set inSet).
Returns false (with a debug message) when any required parameter is nil.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
key |
string |
The unique setting key. |
type |
any |
An ax.type constant (e.g. ax.type.number, ax.type.string). |
default |
any |
The default value used when no persisted value exists. |
data |
table\|nil |
Optional metadata table (see field descriptions above). |
Returns
boolean: True if registered successfully, false on invalid input.
store:Get(...)¶
Retrieves a value from the store with optional fallback.
Normal call: store:Get(key, fallback) — returns the stored value for key, or store.defaults[key], or fallback (in that priority order).
On the client, config values are served from the local CONFIG_CACHE (populated by server sync) rather than store.values.
Special call for option stores on the server: store:Get(player, key, fallback) — reads a per-player option value from SERVER_CACHE (populated when the client sends its preferences). If no cached value exists for that player, the registered default is used.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
... |
any |
Either (key, fallback) or (player, key, fallback). |
Returns
any: The resolved value, or the fallback when no value is found.
store:GetAllByCategory(category)¶
Returns definitions for all keys whose category matches a filter string.
Matching is performed by ax.util:FindString — case-insensitive substring match. For example, "gen" will match "general". Keys with no category fall under "misc" for the purposes of this filter.
The returned map contains deep copies of the matched registry entries.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
category |
string |
The category string to filter by (partial match). |
Returns
table: Map ofkey → { type, default, data }for matched keys.
store:GetAllCategories()¶
Returns an array of all unique category names in the registry.
Iterates all registered keys and collects their data.category field.
Keys without an explicit category are counted under "general".
The returned array contains each category string exactly once, in arbitrary order. Useful for building category tabs in a settings UI.
Realm: shared
Returns
table: An array of unique category name strings.
store:GetAllDefinitions()¶
Returns a deep copy of all registered setting definitions.
Each entry in the returned map is a copy of the registry entry (type, default, data) keyed by the setting key. Modifying the returned table does not affect the live registry. Useful for introspecting all available settings, e.g. for building a settings panel or exporting documentation.
Realm: shared
Returns
table: Map ofkey → { type, default, data }for all registered keys.
store:GetData(key)¶
Returns a copy of the metadata table for a registered key.
Returns a deep copy so callers cannot accidentally mutate the registry.
Returns nil when key is not a string or is not registered.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
key |
string |
The setting key to look up. |
Returns
table|nil: A copy of thedatatable provided when the key was registered, or nil if the key is unknown.
store:GetDefault(key)¶
Returns the registered default value for a key.
This is the value passed as default to store:Add, or subsequently updated by store:SetDefault. Returns nil when key is not a string or is not registered.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
key |
string |
The setting key. |
Returns
any: The default value, or nil if the key is unknown.
store:HandleConfigChange(regEntry, oldValue, newValue, key)¶
Invokes the OnChanged callback for a key if one is registered.
Called by the networking layer after a config value arrives from the server (on the client side). The callback is called via SafeCall so errors in user-defined callbacks do not break the networking flow.
oldValue may be nil when this is the initial sync (no prior value).
regEntry being nil or having no OnChanged function is safe — the call is silently skipped.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
regEntry |
table\|nil |
The registry entry for the key (from store.registry[key]). |
oldValue |
any |
The previous value of the key, or nil on first sync. |
newValue |
any |
The newly received value. |
key |
string |
The setting key that changed. |
store:Load()¶
Loads persisted values from disk into the store.
Only executes on the authority side (spec.authority): server stores load on SERVER, client stores load on CLIENT. Calling from the non-authority side is a no-op that returns false.
Clears the persisted data cache first (InvalidatePersistedCache), then loads from the primary path (or ax.data if configured). If the primary path is absent, falls back to any spec.legacyPaths entries and migrates the data to the primary path on success.
Each loaded key is coerced to its registered type; keys that fail coercion are skipped (debug message only). After loading, fires either hook.Run("OnConfigsLoaded") or hook.Run("OnOptionsLoaded").
Realm: shared
Returns
boolean: True if values were loaded successfully, false if no data file exists or the store is on the wrong realm.
store:Save()¶
Persists the current store values to disk.
Only executes on the authority side (spec.authority). No-op on the non-authority side. Serialises store.values and writes it to the primary path via ax.data:Set (if configured) or ax.util:WriteJSON.
On success, updates the persisted cache so subsequent Add calls can read back the correct initial value without re-reading the file.
A warning is printed (but false is returned silently) if the path is invalid or the write fails. This function is called automatically by Set (unless bNoSave is true) and on ShutDown.
Realm: shared
Returns
boolean: True if values were saved successfully, false otherwise.
store:Set(key, value, bNoSave, bNoCallback)¶
Sets a value in the store, triggering coercion, callbacks, and networking.
The full pipeline when setting a value:
- Coercion: value is sanitised to the registered type via
ax.type:Sanitise. Numbers are additionally clamped and rounded usingdata.min,data.max, anddata.decimals. Array values are validated againstdata.choices/data.populate. - Change check: if the coerced value equals the current value, returns false immediately (no-op).
- Callbacks (unless
bNoCallbackis true): regEntry.data.OnChanged(oldValue, newValue, key)if defined.hook.Run("OnConfigChanged", ...)orhook.Run("OnOptionChanged", ...).- Persistence (unless
bNoSaveis true): callsstore:Save(). - Networking (if the key is in
networkedKeys): broadcasts the new value via the appropriate net channel for the store type and realm.
Returns false (silently, with a debug message) for unknown keys or invalid values. Returns true when the value was actually changed.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
key |
string |
The setting key to update. |
value |
any |
The new value (will be coerced to the registered type). |
bNoSave |
boolean\|nil |
When true, skips writing to disk. |
bNoCallback |
boolean\|nil |
When true, skips OnChanged and hooks. |
Returns
boolean: True if the value changed, false otherwise.
store:SetDefault(key, value)¶
Updates the registered default value for a key without changing the current value.
Modifies both the registry entry's default field and store.defaults[key]. The live value in store.values is only changed if it is currently nil — existing values are preserved. Useful for overriding defaults set during initial registration, e.g. when a gamemode wants to change framework defaults.
Returns false when the key is not registered.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
key |
string |
The setting key whose default should be changed. |
value |
any |
The new default value. |
Returns
boolean: True on success, false if the key is unknown.
store:SetToDefault(key)¶
Resets a key's value to its registered default.
Convenience wrapper around store:Set(key, default). Goes through the full Set pipeline including coercion, callbacks, persistence, and networking — the reset is treated the same as any other value change.
Returns false when the key is not registered, or when the current value is already equal to the default (no change).
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
key |
string |
The setting key to reset. |
Returns
boolean: True if the value was changed, false otherwise.
store:Sync(target)¶
Synchronises networked key values across the network.
Behaviour depends on the store type and current realm:
configon server: collects all keys instore.networkedKeysand sends them viaspec.net.inittotarget(a player or table of players). Whentargetis nil, broadcasts toplayer.GetAll(). This is called automatically onPlayerReadyto initialise new clients.optionon client: collects all networked option values fromstore.valuesand sends them to the server viaspec.net.sync. This is called automatically 2 seconds afterInitPostEntityand when the server sends arequestnet message.
Does nothing in other realm/store combinations.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
target |
Player\|table\|nil |
For config syncs: the recipient player(s). Defaults to all players when nil. Ignored for option syncs. |