ax.util¶
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
Documented functions: 72 · Realm: client, server, shared
Functions¶
ax.util:CreateBotCharacter(client)ax.util:GenerateBotName()ax.util:GetRandomBotFaction()ax.util:GetRandomFactionModel(faction)ax.util:ApproachAngle(fraction, startAng, finishAng, opts)ax.util:ApproachFraction(fraction, smooth, linear)ax.util:ApproachNumber(fraction, start, finish, opts)ax.util:ApproachVector(fraction, startVec, finishVec, opts)ax.util:Assert(condition, errorMessage, ...)ax.util:AssertDebug(condition, errorMessage, ...)ax.util:ClampRound(n, min, max, decimals)ax.util:DrawBlur(r, x, y, width, height, color)ax.util:DrawCircle(x, y, radius, segments, startAngle, endAngle)ax.util:DrawGradient(r, name, x, y, w, h, color)ax.util:DrawSlice(x, y, radius, startAngle, endAngle, color)ax.util:FindInCrosshair(client, target, range)ax.util:GetGradient(name)ax.util:GetGradientPath(name)ax.util:GetHeadTransform(entity)ax.util:GetMaterial(path, parameters)ax.util:GetPlayerFromAttachedRagdoll(entity)ax.util:GetProjectName()ax.util:GetServerAddress()ax.util:GetSortedEntries(entries, comparator)ax.util:GetSurfaceDataViaName(surfaceName)ax.util:GetSurfaceDataViaTrace(tr)ax.util:IsValidPlayer(client)ax.util:NameToUniqueID(name)ax.util:NormalizeColor(value)ax.util:PadNumber(num, digits)ax.util:ResolveBodygroupIndex(entity, groupID)ax.util:SafeCall(fn, ...)ax.util:SafeParseTable(tInput, bToJson)ax.util:SanitizeKey(key)ax.util:Scale(value)ax.util:ScreenScale(value)ax.util:ScreenScaleH(value)ax.util:TokenizeString(str)ax.util:UniqueIDToCamel(id)ax.util:UniqueIDToName(id)ax.util:BuildDataPath(key, options)ax.util:DetectFileRealm(file)ax.util:EnsureDataDir(path)ax.util:Include(path, realm)ax.util:IncludeDirectory(directory, fromLua, toSkip, timeFilter)ax.util:LoadEntities(path, timeFilter)ax.util:ReadJSON(path)ax.util:WriteJSON(path, tbl)ax.util:FindCharacter(identifier, allowUnloaded)ax.util:FindPlayer(identifier)ax.util:FindString(str, find, caseSensitive, startPos, usePatterns)ax.util:FindText(txt, find)ax.util:NormalizeSearchString(value)ax.util:SearchMatches(query, ...)ax.util:PreparePackage(...)ax.util:Print(...)ax.util:PrintDebug(...)ax.util:PrintError(...)ax.util:PrintSuccess(...)ax.util:PrintWarning(...)ax.util:AddSound(name, path, volume, pitch, channel, level)ax.util:CreateStore(spec, oldStore)ax.util:CapText(text, maxLength)ax.util:CapTextWord(text, maxLength)ax.util:GetTextHeight(font)ax.util:GetTextSize(font, text)ax.util:GetTextWidth(font, text)ax.util:GetWrappedText(text, font, maxWidth)ax.util:GetBranch()ax.util:GetCommitCount()ax.util:GetCommitHash()ax.util:GetVersion()
ax.util:CreateBotCharacter(client)¶
Creates a temporary in-memory character for a bot and loads it immediately.
Selects a random eligible faction via GetRandomBotFaction and a random model via GetRandomFactionModel, then constructs a character metatable instance populated with default variable values. The character is registered in ax.character.instances but is never written to the database — it exists only for the lifetime of the server session.
If the faction defines a GetDefaultName function, that name takes priority over the randomly generated one. A temporary inventory is created via ax.inventory:CreateTemporary if available; otherwise the inventory slot is set to 0 with a warning.
Returns false (with a printed warning) if the bot is invalid, has no eligible faction, or has no available models.
After loading, ax.character:SyncBotToClients is called so connected clients receive the new character's variables.
Realm: server
Parameters
| Name | Type | Description |
|---|---|---|
client |
Player |
The bot player to create a character for. |
Returns
boolean: True on success, false on any failure.
Usage
Source: gamemode/framework/util/util_bots.lua:111
ax.util:GenerateBotName()¶
Generates a random full name for a bot player.
Picks one entry at random from AX_BOT_FIRST_NAMES and one from AX_BOT_LAST_NAMES, then concatenates them with a space.
The name tables are defined as globals at the top of this file and can be extended by other modules before bots are created.
Realm: shared
Returns
string: A randomly generated "Firstname Lastname" string.
Usage
Source: gamemode/framework/util/util_bots.lua:38
ax.util:GetRandomBotFaction()¶
Returns a random faction that bots are allowed to join.
Iterates all registered factions and filters to those where either faction.isDefault is true, or faction.allowBots is not explicitly set to false. Returns nil when no eligible factions exist (e.g. every faction is whitelisted or explicitly bans bots).
Realm: shared
Returns
table|nil: A random eligible faction table, or nil if none qualify.
Usage
Source: gamemode/framework/util/util_bots.lua:50
ax.util:GetRandomFactionModel(faction)¶
Returns a random model from a faction's model list.
Calls faction:GetModels() and picks a random entry. Entries are resolved in this order: if the selected entry is a function it is called and its return value is used; if it is a table whose first element is a string, that string path is used directly. Any other value (plain string or {model, skin} table) is returned as-is.
Returns nil if the faction has no GetModels method or its list is empty.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
faction |
table |
The faction table to query. |
Returns
string|table|nil: A model path string, a{model, skin}table, or nil when no models are available.
Usage
local model = ax.util:GetRandomFactionModel(faction)
local path = istable(model) and model[1] or model
Source: gamemode/framework/util/util_bots.lua:80
ax.util:ApproachAngle(fraction, startAng, finishAng, opts)¶
Interpolates an Angle component-wise from startAng to finishAng.
Delegates to ApproachNumber independently for pitch (p), yaw (y), and roll (r) and assembles the results into a new Angle. Note that raw lerping of angles can wrap unexpectedly near 180°/−180° boundaries; for large yaw sweeps, normalise the angles before calling this function.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
fraction |
number |
Progress fraction in [0, 1]. |
startAng |
Angle |
The starting angle (fraction = 0). |
finishAng |
Angle |
The target angle (fraction = 1). |
opts |
table\|nil |
Options forwarded to ApproachNumber (smooth, linear, transition). |
Returns
Angle: The interpolated angle.
Usage
Source: gamemode/framework/util/util_core.lua:396
ax.util:ApproachFraction(fraction, smooth, linear)¶
Scales a 0–1 progress fraction by a smoothness percentage.
This is a low-level helper used by ApproachNumber, ApproachVector, and ApproachAngle. smooth is expressed as a percentage (0–100): a value of 100 leaves the fraction unchanged; lower values compress it toward 0, making transitions feel slower or more eased. The result is always clamped to [0, 1] regardless of input.
linear is accepted for signature compatibility but does not currently alter the calculation — the distinction between linear and non-linear movement is handled at the ApproachNumber level.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
fraction |
number |
The raw progress fraction, expected in [0, 1]. |
smooth |
number |
Smoothness multiplier as a percentage (0–100). Defaults to 100 (no scaling) when nil or non-numeric. |
linear |
boolean\|nil |
Reserved for future use; has no effect currently. |
Returns
number: The scaled and clamped fraction in [0, 1].
Usage
Source: gamemode/framework/util/util_core.lua:327
ax.util:ApproachNumber(fraction, start, finish, opts)¶
Interpolates a number from start to finish using a progress fraction.
The fraction is first passed through ApproachFraction using opts.smooth (default 100, i.e. no compression). The transition mode then determines how the adjusted fraction maps to the final value:
"lerp"(default): standard linear interpolation viaLerp."smoothstep": applies a cubic ease-in/ease-out curve (t² × (3 − 2t)) before lerping, producing a gentle S-curve acceleration/deceleration."linear"oropts.linear = true: usesmath.Approach, which moves at a constant step-size per call rather than lerping, useful for physics-style clamped movement.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
fraction |
number |
Progress fraction in [0, 1]. |
start |
number |
The value at fraction = 0. |
finish |
number |
The value at fraction = 1. |
opts |
table\|nil |
Optional settings table: smooth number (0–100) smoothness percent passed to ApproachFraction; linear boolean when true forces the "linear" transition mode; transition string "lerp" | "smoothstep" | "linear". |
Returns
number: The interpolated value betweenstartandfinish.
Usage
local v = ax.util:ApproachNumber(0.5, 0, 100) -- 50
local v = ax.util:ApproachNumber(0.5, 0, 100, { transition = "smoothstep" })
Source: gamemode/framework/util/util_core.lua:352
ax.util:ApproachVector(fraction, startVec, finishVec, opts)¶
Interpolates a Vector component-wise from startVec to finishVec.
Delegates to ApproachNumber independently for X, Y, and Z and assembles the results into a new Vector. All transition modes and smoothness options supported by ApproachNumber work here too. Useful for smoothly animating world positions or velocities over time in a Think hook.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
fraction |
number |
Progress fraction in [0, 1]. |
startVec |
Vector |
The starting vector (fraction = 0). |
finishVec |
Vector |
The target vector (fraction = 1). |
opts |
table\|nil |
Options forwarded to ApproachNumber (smooth, linear, transition). |
Returns
Vector: The interpolated vector.
Usage
Source: gamemode/framework/util/util_core.lua:379
ax.util:Assert(condition, errorMessage, ...)¶
Asserts a condition, printing an error message when it is false.
Unlike Lua's built-in assert, this does NOT throw — execution continues after the call. The error is printed via PrintError (which uses ErrorNoHaltWithStack, so a stack trace is included in the output).
When condition is falsy, returns false followed by any extra arguments.
When condition is truthy, returns it unchanged followed by extra arguments.
Use this for precondition checks where you want to log the failure clearly but still allow the caller to handle it gracefully.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
condition |
any |
The value to test. Falsy (false/nil) triggers the error. |
errorMessage |
string\|nil |
The message to print on failure. Defaults to "Assertion failed". |
... |
any |
Extra values appended to the error output and forwarded as additional return values. |
Returns
boolean|any:condition(or false on failure), followed by....
Usage
local ok = ax.util:Assert(istable(data), "Expected table, got", type(data))
if ( !ok ) then return end
Source: gamemode/framework/util/util_core.lua:687
ax.util:AssertDebug(condition, errorMessage, ...)¶
Asserts a condition, printing a debug message when it is false.
Behaves identically to Assert except the failure message is routed through PrintDebug instead of PrintError. This means the output is only visible when the developer convar is ≥ 1 AND ax_debug_realm is set to match the current realm — making it suitable for internal consistency checks that should be silent in production but informative during development.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
condition |
any |
The value to test. Falsy (false/nil) triggers the debug message. |
errorMessage |
string\|nil |
The message to print on failure. Defaults to "Assertion failed". |
... |
any |
Extra values appended to the debug output and forwarded as additional return values. |
Returns
boolean|any:condition(or false on failure), followed by....
Usage
Source: gamemode/framework/util/util_core.lua:782
ax.util:ClampRound(n, min, max, decimals)¶
Clamps a number to a range, then rounds it to a given precision.
Clamping is applied first, so the rounded result is always within [min, max]. When decimals is 0 or omitted, math.Round is used (nearest integer). For positive decimals, the number is scaled by 10^decimals, rounded, then scaled back, preserving that many decimal places. min and max are both optional; pass nil to skip either bound.
Non-numeric input for n is treated as 0.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
n |
number |
The number to clamp and round. |
min |
number\|nil |
Lower bound (inclusive). Skipped when nil. |
max |
number\|nil |
Upper bound (inclusive). Skipped when nil. |
decimals |
number\|nil |
Number of decimal places to preserve (default 0). |
Returns
number: The clamped and rounded result.
Usage
ax.util:ClampRound(3.14159, 0, 10, 2) -- 3.14
ax.util:ClampRound(150, 0, 100) -- 100
ax.util:ClampRound(4.6) -- 5
Source: gamemode/framework/util/util_core.lua:302
ax.util:DrawBlur(r, x, y, width, height, color)¶
Draws a blurred, optionally rounded rectangle on the screen.
Thin wrapper around ax.render.Draw using ax.render.BLUR mode.
The blur is rendered over whatever is already on screen at that region, making it useful for frosted-glass UI elements. Alpha on color controls the overall opacity of the blur overlay.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
r |
number |
Corner roundness in pixels (0 for a sharp rectangle). |
x |
number |
Left edge of the rectangle in screen pixels. |
y |
number |
Top edge of the rectangle in screen pixels. |
width |
number |
Width of the rectangle in pixels. |
height |
number |
Height of the rectangle in pixels. |
color |
Color |
Color applied over the blur; alpha controls opacity. |
Usage
Source: gamemode/framework/util/util_core.lua:228
ax.util:DrawCircle(x, y, radius, segments, startAngle, endAngle)¶
Draws a smooth arc or full circle outline using polygons.
Generates vertices along the arc from startAngle to endAngle (both in degrees) and draws them as a polygon using surface.DrawPoly. The arc is not filled — it is an open polyline. For a filled circle, use DrawSlice instead. segments controls smoothness; 64 is a good default for most sizes. Call surface.SetDrawColor before this function to set the line colour.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
x |
number |
Center X of the arc in screen pixels. |
y |
number |
Center Y of the arc in screen pixels. |
radius |
number |
Radius of the arc in pixels. |
segments |
number\|nil |
Number of polygon segments (default: 64). Higher values produce a smoother curve. |
startAngle |
number\|nil |
Starting angle in degrees (default: 0). 0 is the 3-o'clock position; angles increase clockwise. |
endAngle |
number\|nil |
Ending angle in degrees (default: 360, full circle). Set to less than 360 for a partial arc. |
Usage
surface.SetDrawColor(255, 255, 255, 200)
ax.util:DrawCircle(ScrW() / 2, ScrH() / 2, 64) -- full circle
ax.util:DrawCircle(100, 100, 32, 32, 0, 180) -- half-circle arc
Source: gamemode/framework/util/util_core.lua:808
ax.util:DrawGradient(r, name, x, y, w, h, color)¶
Draws a gradient material tinted with a color on the screen.
Resolves the gradient via GetGradient(name), then draws it using ax.render.DrawMaterial with optional corner rounding and tint color. When color is omitted, an opaque white tint is used (no tinting).
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
r |
number |
Corner roundness in pixels (0 for a sharp rectangle). |
name |
string |
A direction alias ("left", "right", etc.) or a full material path. See GetGradientPath for all accepted aliases. |
x |
number |
Left edge of the draw area in screen pixels. |
y |
number |
Top edge of the draw area in screen pixels. |
w |
number |
Width of the draw area in pixels. |
h |
number |
Height of the draw area in pixels. |
color |
Color\|nil |
Optional tint applied to the gradient texture. Alpha controls overall opacity. Defaults to Color(255, 255, 255, 255). |
Usage
ax.util:DrawGradient(0, "left", 0, 0, 200, 400, Color(0, 0, 0, 200))
ax.util:DrawGradient(4, "right", ScrW() - 64, 0, 64, ScrH())
Source: gamemode/framework/util/util_core.lua:280
ax.util:DrawSlice(x, y, radius, startAngle, endAngle, color)¶
Draws a filled pie slice, useful for circular progress indicators.
Constructs a polygon with the centre point as vertex 0 and arc vertices fanning out from startAngle to endAngle. An internal –90° offset is applied so that 0° corresponds to the top of the circle (12-o'clock position), making it intuitive for progress bars that start at the top.
Uses a fixed 64-segment resolution. The slice is filled solid with color.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
x |
number |
Center X of the slice in screen pixels. |
y |
number |
Center Y of the slice in screen pixels. |
radius |
number |
Radius of the slice in pixels. |
startAngle |
number |
Starting angle in degrees. 0 = top (12 o'clock). |
endAngle |
number |
Ending angle in degrees. 360 = full circle. |
color |
table |
Color table with r, g, b, a fields. |
Usage
Source: gamemode/framework/util/util_core.lua:847
ax.util:FindInCrosshair(client, target, range)¶
Returns true when target falls within client's crosshair cone.
Uses the dot product of client's aim vector and the normalised direction to target's eye position (or world centre for non-player entities). The dot product is compared against range as a threshold: a value of 1.0 means the target must be directly on-axis; 0.9 (default) allows roughly ±26°; 0.0 accepts any direction in front of the player. A lower range value produces a wider acceptance cone.
Returns nil (falsy) when either client or target is not a valid player.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
client |
Player |
The player whose aim vector is used. |
target |
Entity |
The entity to test against the crosshair cone. |
range |
number\|nil |
Dot-product threshold in [0, 1]. Higher values require tighter aim. Defaults to 0.9. |
Returns
boolean|nil: True iftargetis within the crosshair cone, nil if either argument is not a valid player.
Usage
-- Is Entity(2) roughly in Entity(1)'s sights?
ax.util:FindInCrosshair(Entity(1), Entity(2)) -- default 0.9
-- Wider cone (accepts targets up to ~60° off-axis):
ax.util:FindInCrosshair(Entity(1), Entity(2), 0.5)
-- Very tight aim required (almost pixel-perfect):
ax.util:FindInCrosshair(Entity(1), Entity(2), 0.99)
Source: gamemode/framework/util/util_core.lua:656
ax.util:GetGradient(name)¶
Returns a cached gradient IMaterial by direction name or path.
Resolves name to a path via GetGradientPath, then fetches or creates the material via GetMaterial. Subsequent calls with the same name are served from the material cache at no extra cost.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
name |
string |
A direction alias ("left", "right", etc.) or a full material path. See GetGradientPath for all accepted values. |
Returns
IMaterial: The corresponding gradient material.
Usage
Source: gamemode/framework/util/util_core.lua:263
ax.util:GetGradientPath(name)¶
Resolves a short gradient direction name to a GMod vgui material path.
Accepted short names and their aliases (case-insensitive):
"left"/"l"/1→"vgui/gradient-l""right"/"r"/2→"vgui/gradient-r""top"/"up"/"u"/3→"vgui/gradient-u""bottom"/"down"/"d"/4→"vgui/gradient-d"
Any unrecognised string is returned as-is, allowing full material paths to be passed through without translation. An empty or non-string name defaults to "vgui/gradient-l".
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
name |
string |
A direction alias or a full material path. |
Returns
string: The resolved material path.
Usage
ax.util:GetGradientPath("right") -- "vgui/gradient-r"
ax.util:GetGradientPath("vgui/my_gradient") -- "vgui/my_gradient"
Source: gamemode/framework/util/util_core.lua:244
ax.util:GetHeadTransform(entity)¶
Returns the world position and angle of an entity's head.
Checks for the "eyes" attachment first; if found and valid, its position and angle are returned. Falls back to the ValveBiped.Bip01_Head1 bone when the attachment is absent or returns no data. Returns nil for both values when neither source is available (e.g. a prop with no skeleton).
A debug axis overlay is drawn at the resolved position for 0.1 seconds — this is intentional for development use.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
entity |
Entity |
The entity to inspect (player, NPC, or ragdoll). |
Returns
Vector|nil: World position of the head, or nil when not found.Angle|nil: World angle at the head, or nil when not found.
Usage
local headPos, headAng = ax.util:GetHeadTransform(entity)
if ( headPos ) then -- render something at head level end
Source: gamemode/framework/util/util_core.lua:425
ax.util:GetMaterial(path, parameters)¶
Returns a cached IMaterial, creating it on first use.
Materials are cached by a compound key of path and parameters so that the same path with different parameter strings produces distinct cache entries. parameters defaults to "" — callers that omit it get a different cache slot from those that pass an empty string explicitly only if they use a different string value.
Prints an error and returns false when path is nil/false.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
path |
string |
The material path (e.g. "sprites/glow"). |
parameters |
string\|nil |
Optional parameter string forwarded to Material() (e.g. "nocull noclamp smooth"). |
Returns
IMaterial|false: The cached or newly created material, or false on invalid path.
Usage
local mat = ax.util:GetMaterial("sprites/glow", "nocull")
local icon = ax.util:GetMaterial("vgui/icon_item")
Source: gamemode/framework/util/util_core.lua:197
ax.util:GetPlayerFromAttachedRagdoll(entity)¶
Returns the player whose death ragdoll is the given entity.
Iterates all connected players and checks whether any has a ragdoll.index relay value matching the entity's index. This relay is set by the framework when a player's death ragdoll is created. Returns nil when the entity is not a prop_ragdoll, is invalid, or no player has that ragdoll index.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
entity |
Entity |
The entity to test, expected to be a prop_ragdoll. |
Returns
Player|nil: The player who owns this ragdoll, or nil if not found.
Usage
local owner = ax.util:GetPlayerFromAttachedRagdoll(ent)
if ( owner ) then print(owner:Nick() .. "'s ragdoll") end
Source: gamemode/framework/util/util_core.lua:754
ax.util:GetProjectName()¶
Returns the active gamemode's folder name, used as a data namespace.
Calls engine.ActiveGamemode() to read the folder name of the gamemode currently running (e.g. "parallax" or "parallax-militaryrp"). Falls back to the literal string "parallax" if the engine API is unavailable.
This value is used by functions like BuildDataPath to scope persisted data files per-gamemode so derived gamemodes don't collide with each other.
Realm: shared
Returns
string: The active gamemode folder name, or"parallax"as a safe fallback.
Usage
Source: gamemode/framework/util/util_core.lua:518
ax.util:GetServerAddress()¶
Returns the server's network address, IP, and port as separate values.
Calls game.GetIPAddress() first. On the server side, falls back to the sv_ip convar if the primary call returns an empty string. Parses the resulting "ip:port" string into its components; the port defaults to 0 when not present in the string. Returns three nils when no address can be determined, and logs a debug message.
Realm: shared
Returns
string|nil: The full"ip:port"address string, or nil on failure.string|nil: The IP portion only (may be"0.0.0.0"on listen servers before a map is fully loaded).number|nil: The port number, or 0 when absent from the address.
Usage
local full, ip, port = ax.util:GetServerAddress()
if ( full ) then print("Server running at " .. full) end
Source: gamemode/framework/util/util_core.lua:535
ax.util:GetSortedEntries(entries, comparator)¶
Converts a key/value map into a sorted array of entry objects.
Each entry in the returned array is a table { key = k, value = v }.
The default sort order is case-insensitive lexicographic by key; when two keys are equal after lowercasing, the original (case-sensitive) key string is used as a tiebreaker so the order is stable and predictable.
Provide a custom comparator(a, b) (where a and b are entry tables) to override the sort. Returns an empty table if entries is not a table.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
entries |
table |
The key/value map to convert and sort. |
comparator |
function\|nil |
Optional sort function receiving two entry tables. Should return true when a should come before b. |
Returns
table: Sorted array of{ key, value }entry tables.
Usage
local sorted = ax.util:GetSortedEntries(ax.faction:GetAll())
for _, entry in ipairs(sorted) do print(entry.key, entry.value.name) end
Source: gamemode/framework/util/util_core.lua:158
ax.util:GetSurfaceDataViaName(surfaceName)¶
Returns the surface data table for a named physics surface material.
Looks up the internal surface index with util.GetSurfaceIndex, then retrieves the data table via util.GetSurfaceData. Returns nil when the name is not registered (index 0) or when surfaceName is nil/false.
Surface names are defined in scripts/surfaceproperties.txt and its includes (e.g. "concrete", "metal", "wood").
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
surfaceName |
string |
The physics surface material name to look up. |
Returns
table|nil: The surface data table, or nil if the name is unknown.
Usage
Source: gamemode/framework/util/util_core.lua:571
ax.util:GetSurfaceDataViaTrace(tr)¶
Returns the surface data table for the surface hit by a trace result.
Reads tr.SurfaceProps (the internal physics surface index stored in every trace result) and forwards it to util.GetSurfaceData. Returns nil when the trace missed (tr.Hit is false), when tr is nil, or when SurfaceProps is 0 (no valid surface). Pair with util.TraceLine or util.TraceEntity to get the trace result.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
tr |
table |
A trace result table as returned by util.TraceLine or similar. Must have Hit and SurfaceProps fields. |
Returns
table|nil: The surface data table, or nil if the trace missed or has no valid surface properties.
Usage
local tr = util.TraceLine({ start = eyePos, endpos = eyePos + eyeDir * 256, filter = client })
local data = ax.util:GetSurfaceDataViaTrace(tr)
if ( data ) then print(data.material) end
Source: gamemode/framework/util/util_core.lua:588
ax.util:IsValidPlayer(client)¶
Returns true if client is a player entity.
Checks the Lua type string via type() rather than IsValid(), so it is safe to call on any value including nil, non-entity tables, or invalid entities (which would make IsValid() error). Use this instead of IsValid(client) and client:IsPlayer() when you don't yet know whether the value is even an entity.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
client |
any |
The value to test. |
Returns
boolean: True ifclienthas Lua type"Player".
Usage
Source: gamemode/framework/util/util_core.lua:412
ax.util:NameToUniqueID(name)¶
Converts a human-readable name into a lowercase, underscore-separated ID.
Applies three transformations in order:
- Spaces (including runs of whitespace) are replaced with underscores.
- CamelCase boundaries (lowercase letter followed by uppercase) get an underscore inserted between them, e.g. "MyModule" → "My_Module".
- Any character that is not a letter (A–Z, a–z) or underscore is stripped, so digits and punctuation are removed entirely.
- The result is lowercased.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
name |
string |
The human-readable name to convert. |
Returns
string: A sanitised lowercase unique ID safe for use as a table key or module identifier.
Usage
ax.util:NameToUniqueID("My Module") -- "my_module"
ax.util:NameToUniqueID("MyModule") -- "my_module"
ax.util:NameToUniqueID("Faction 01") -- "faction_" (digits stripped)
Source: gamemode/framework/util/util_core.lua:85
ax.util:NormalizeColor(value)¶
Normalizes a color value to a valid Color object.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
value |
any |
The value to normalize. |
Returns
Color: The normalized color.
Source: gamemode/framework/util/util_core.lua:701
ax.util:PadNumber(num, digits)¶
Pads a number with leading zeroes to a minimum digit count.
Uses string.format with %0Xd under the hood. The result is always a string. If the number already has more digits than digits, it is returned without truncation — digits is a minimum, not a fixed width.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
num |
number |
The integer to pad. |
digits |
number |
The minimum number of digits in the output string. |
Returns
string: The zero-padded number as a string.
Usage
ax.util:PadNumber(7, 3) -- "007"
ax.util:PadNumber(1234, 3) -- "1234" (already wider, not truncated)
ax.util:PadNumber(0, 2) -- "00"
Source: gamemode/framework/util/util_core.lua:638
ax.util:ResolveBodygroupIndex(entity, groupID)¶
Resolves a bodygroup ID to a valid index.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
entity |
Entity |
The entity to resolve the bodygroup for. |
groupID |
any |
The bodygroup ID to resolve. |
Returns
number|nil: The resolved bodygroup index, or nil if invalid.
Source: gamemode/framework/util/util_core.lua:723
ax.util:SafeCall(fn, ...)¶
Calls a function safely, capturing any Lua error without throwing.
NOTE: This definition is overwritten later in this file by a second, simpler SafeCall. See the authoritative definition below for the live behaviour.
This version prints the error via PrintError and unpacks all return values; the later version returns only the first return value.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
fn |
function |
The function to call. Returns false immediately if not a function. |
... |
any |
Arguments forwarded to fn. |
Returns
boolean: True if the call succeeded without error.any: All values returned byfnwhen successful.
Usage
Source: gamemode/framework/util/util_core.lua:55
ax.util:SafeParseTable(tInput, bToJson)¶
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
Converts between a JSON string and a Lua table safely.
Two modes depending on the inputs:
- When
bToJsonis true andtInputis a table, serialises the table to a JSON string viautil.TableToJSONand returns it. - Otherwise, if
tInputis a string, parses it as JSON viautil.JSONToTable(wrapped in pcall) and returns the resulting table, or nil on parse failure. IftInputis already a table it is returned unchanged — useful for APIs that accept either form.
Errors are reported through PrintError and never thrown.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
tInput |
string\|table |
The JSON string to parse, or a table to pass through (or serialise when bToJson is true). |
bToJson |
boolean\|nil |
When true and tInput is a table, converts it to a JSON string instead of parsing. |
Returns
table|string|nil: The parsed table, the serialised JSON string, or nil on failure.
Usage
local tbl = ax.util:SafeParseTable('{"key":"value"}')
local json = ax.util:SafeParseTable({ key = "value" }, true)
Source: gamemode/framework/util/util_core.lua:26
ax.util:SanitizeKey(key)¶
Sanitises an arbitrary string so it is safe to use in file names and paths.
Any character that is not alphanumeric (A–Z, a–z, 0–9), a hyphen (-), underscore (_), or period (.) is replaced with an underscore.
The value is coerced to string via tostring before processing. Returns "" when key is nil or false.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
key |
any |
The value to sanitise (coerced to string). |
Returns
string: A filesystem-safe string.
Usage
ax.util:SanitizeKey("Player:Test") -- "Player_Test"
ax.util:SanitizeKey("config/sub dir/file") -- "config_sub_dir_file"
ax.util:SanitizeKey("my.setting_key-v2") -- "my.setting_key-v2"
Source: gamemode/framework/util/util_core.lua:505
ax.util:Scale(value)¶
Scales a pixel value by the player's UI scale preference.
Reads the interface.scale option (default 1.0) and multiplies value by it. Use this for any hardcoded pixel dimension that should respect the user's interface scale setting (panel sizes, font sizes, offsets, etc.).
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
value |
number |
The base pixel value to scale. |
Returns
number: The value multiplied by the current UI scale factor.
Usage
Source: gamemode/framework/util/util_core.lua:602
ax.util:ScreenScale(value)¶
Applies GMod's ScreenScale then multiplies by the player's UI scale.
ScreenScale converts a value designed for a 640-wide reference display to the current screen width. This function additionally applies the interface.scale option on top, so sizes remain consistent across both different resolutions and different user scale preferences.
Prefer this over raw ScreenScale for all UI element sizing.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
value |
number |
The reference value (as if the screen were 640 px wide). |
Returns
number: The resolution- and scale-adjusted pixel value.
Usage
Source: gamemode/framework/util/util_core.lua:614
ax.util:ScreenScaleH(value)¶
Applies GMod's ScreenScaleH then multiplies by the player's UI scale.
The height-based equivalent of ScreenScale — scales a reference value relative to screen height (480 px reference) rather than width. Multiply by the interface.scale option afterward for consistent vertical sizing.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
value |
number |
The reference value (as if the screen were 480 px tall). |
Returns
number: The resolution- and scale-adjusted pixel value.
Usage
Source: gamemode/framework/util/util_core.lua:624
ax.util:TokenizeString(str)¶
Splits a string into tokens, preserving quoted multi-word segments.
Iterates the string character-by-character. Space characters split tokens unless the parser is inside a quoted region ("). Backslash (\) escapes the next character, so \" includes a literal quote in the current token without ending or starting a quoted region. Empty tokens (consecutive spaces) are skipped. Useful for parsing console-style commands where arguments can contain spaces when wrapped in double quotes.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
str |
string |
The input string to tokenise. |
Returns
table: An ordered array of token strings.
Usage
ax.util:TokenizeString('kick "John Doe" "bad behaviour"')
-- { "kick", "John Doe", "bad behaviour" }
ax.util:TokenizeString('set volume 0.5')
-- { "set", "volume", "0.5" }
Source: gamemode/framework/util/util_core.lua:458
ax.util:UniqueIDToCamel(id)¶
Converts an underscore-separated unique ID to PascalCase.
Each underscore followed by a lowercase letter triggers capitalisation of that letter and removal of the underscore. The very first character is also capitalised. Any character that is not alphanumeric is then stripped from the final result. Returns an empty string when id is not a string.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
id |
string |
The unique ID to convert (e.g. produced by NameToUniqueID). |
Returns
string: The PascalCase equivalent with non-alphanumeric characters removed.
Usage
ax.util:UniqueIDToCamel("my_module") -- "MyModule"
ax.util:UniqueIDToCamel("item_type_id") -- "ItemTypeId"
Source: gamemode/framework/util/util_core.lua:106
ax.util:UniqueIDToName(id)¶
Converts an underscore-separated unique ID back into a human-readable name.
Applies three transformations in order:
- Underscores are replaced with spaces.
- Spaces are inserted at CamelCase boundaries (e.g. from an ID that was produced by merging camel-cased words).
- The first letter of each word is capitalised and the rest are lowercased.
Useful for displaying stored IDs in UI labels without extra formatting logic.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
id |
string |
The unique ID to convert. |
Returns
string: A title-cased, space-separated name.
Usage
ax.util:UniqueIDToName("my_module") -- "My Module"
ax.util:UniqueIDToName("player_health_max") -- "Player Health Max"
Source: gamemode/framework/util/util_core.lua:133
ax.util:BuildDataPath(key, options)¶
Builds a DATA-relative JSON file path for a given key and scope.
key is sanitised via SanitizeKey to remove filesystem-unsafe characters.
Three scope modes are supported via options.scope:
"global"—global/<key>.json: shared across all gamemodes on the server."map"—<project>/maps/<mapname>/<key>.json: per-map within the active gamemode. Usesgame.GetMap()for the map name."project"(default) —<project>/<key>.json: per-gamemode storage.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
key |
string |
The data identifier. Will be sanitised. |
options |
table\|nil |
Optional settings: - scope string: "global", "project", or "map" (default "project"). |
Returns
string: The constructed path relative to theDATAdirectory.
Usage
ax.util:BuildDataPath("config") -- "parallax/config.json"
ax.util:BuildDataPath("config", { scope = "global" }) -- "global/config.json"
ax.util:BuildDataPath("zones", { scope = "map" }) -- "parallax/maps/gm_construct/zones.json"
Source: gamemode/framework/util/util_file.lua:284
ax.util:DetectFileRealm(file)¶
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
File and JSON helpers.
Determines the intended realm of a Lua file from its filename prefix.
Inspects only the filename component (not the directory path). The check is case-insensitive. Recognised prefixes:
cl_→"client"sv_→"server"sh_or anything else →"shared"(default)
This is used internally by Include and IncludeDirectory to route files to the correct side automatically when no explicit realm is provided.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
file |
string |
A filename or path. Only the final filename segment is examined (e.g. "framework/cl_init.lua" → inspects "cl_init.lua"). |
Returns
string:"client","server", or"shared".
Usage
ax.util:DetectFileRealm("cl_hud.lua") -- "client"
ax.util:DetectFileRealm("sv_database.lua") -- "server"
ax.util:DetectFileRealm("sh_config.lua") -- "shared"
ax.util:DetectFileRealm("framework/init.lua") -- "shared"
ax.util:DetectFileRealm("modules/rq_minstd.lua") -- "require"
Source: gamemode/framework/util/util_file.lua:32
ax.util:EnsureDataDir(path)¶
Creates all directories in a DATA-relative path that do not yet exist.
Splits path into segments by / and walks them cumulatively, calling file.CreateDir for each segment that is not already a directory. Idempotent — safe to call repeatedly even if the directories already exist.
Typically called before writing a file to guarantee its parent directories are present.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
path |
string |
A DATA-relative path containing the directories to create (e.g. "parallax/maps/gm_construct/"). The trailing slash is important — any final segment without a slash is treated as a filename and will not be created as a directory. |
Usage
Source: gamemode/framework/util/util_file.lua:308
ax.util:Include(path, realm)¶
Includes a Lua file with automatic realm-based routing.
Normalises path separators and strips leading slashes, then detects the realm via DetectFileRealm if no hint is provided. Routing rules:
"client": on the server, callsAddCSLuaFileonly (sends to clients). On the client, callsinclude."server": callsincludeon the server only. No-op on the client."shared": on the server, calls bothAddCSLuaFileandinclude. On the client, callsinclude.
Both AddCSLuaFile and include are wrapped with pcall internally to prevent one bad file from halting the entire boot sequence. A warning is printed on failure. Returns false for invalid or non-.lua paths.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
path |
string |
Path to the Lua file, relative to the LUA mount point. |
realm |
string\|nil |
Realm override: "client", "server", or "shared". Detected automatically from the filename prefix when omitted. |
Returns
boolean: True if an include or AddCSLuaFile was attempted, false on invalid input.
Usage
Source: gamemode/framework/util/util_file.lua:90
ax.util:IncludeDirectory(directory, fromLua, toSkip, timeFilter)¶
Recursively includes all .lua files found under a directory.
On the first call (not from recursion), the calling file's directory is detected via debug.getinfo and prepended to directory to resolve relative paths correctly. Subsequent recursive calls pass fromLua = true to skip that detection step.
Each .lua file is passed to Include, which handles realm detection and AddCSLuaFile/include routing. Subdirectories are processed depth-first.
Files and directories listed in toSkip (as keys, e.g. { ["boot.lua"] = true }) are silently skipped. The optional timeFilter (in seconds) skips files that have not been modified within that time window — useful for selective hot-reload workflows.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
directory |
string |
Path to the directory to scan, relative to the LUA mount or the calling file's directory. |
fromLua |
boolean\|nil |
Internal recursion flag. Pass nil or false on the first call; true is set automatically during recursion. |
toSkip |
table\|nil |
Table of filenames/directory names to skip, keyed by name (e.g. { ["ignore_me.lua"] = true }). |
timeFilter |
number\|nil |
When provided, files modified more than this many seconds ago are skipped. |
Returns
boolean: True after the directory has been processed, false on invalid input.
Usage
ax.util:IncludeDirectory("framework/libraries/")
ax.util:IncludeDirectory("modules/", nil, { ["old_module.lua"] = true })
Source: gamemode/framework/util/util_file.lua:141
ax.util:LoadEntities(path, timeFilter)¶
Adapted and borrowed from Nutscript, tool inclusion has been borrowed from Helix.
https://github.com/NutScript/NutScript/blob/1.2-stable/gamemode/core/libs/sh_plugin.lua#L112
https://github.com/NebulousCloud/helix/blob/master/gamemode/core/libs/sh_plugin.lua#L192
Loads scripted entities, weapons, tools, and effects from a directory.
Scans four subdirectories under path: entities/, weapons/, tools/, and effects/. For each, both folder-based and single-file layouts are supported:
- Folder layout: a subdirectory per entity containing
init.lua(server),cl_init.lua(client), and/orshared.lua(both). - Single-file layout: a single
.luafile per entity, included as shared.
Entities and weapons are registered with scripted_ents.Register and weapons.Register respectively. Tools are injected into gmod_tool's Tool table. Effects are registered client-side only via effects.Register.
When any tools are loaded, spawnmenu_reload is issued on the client to refresh the spawnmenu. The optional timeFilter skips entities whose directory or file has not been modified within that many seconds — useful for selective hot-reload passes.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
path |
string |
The base directory path (LUA-relative) to scan. |
timeFilter |
number\|nil |
When set, entities not modified within this many seconds are skipped. |
Usage
ax.util:LoadEntities("myaddon")
ax.util:LoadEntities("modules/weapons", 30) -- only reload recently changed
Source: gamemode/framework/util/util_file.lua:339
ax.util:ReadJSON(path)¶
Reads and parses a JSON file from the DATA directory.
Reads the file with file.Read(path, "DATA"), then deserialises it with util.JSONToTable (wrapped in pcall). Returns nil without throwing on any failure: missing file, empty file, or malformed JSON. Safe to call speculatively — a missing config file is not an error condition.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
path |
string |
Path relative to the DATA directory (e.g. "parallax/config.json"). |
Returns
table|nil: The parsed Lua table, or nil on any failure.
Usage
Source: gamemode/framework/util/util_file.lua:220
ax.util:WriteJSON(path, tbl)¶
Serialises a table to JSON and writes it to a file in the DATA directory.
Creates any missing parent directories automatically before writing.
All failure cases (serialisation error, directory creation error, write error) print a warning and return false without throwing. Serialisation uses util.TableToJSON wrapped in pcall.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
path |
string |
Path relative to the DATA directory where the file will be written (e.g. "parallax/config.json"). |
tbl |
table |
The table to serialise and write. |
Returns
boolean: True on success, false on any failure.
Usage
Source: gamemode/framework/util/util_file.lua:242
ax.util:FindCharacter(identifier, allowUnloaded)¶
Finds a character by numeric ID or by name (partial, case-insensitive).
Searches in two passes:
- Active characters — iterates connected players and tests each one's current character (
client:GetCharacter()). Numeric identifiers are matched by exact character ID; string identifiers are matched by name usingFindString(partial, case-insensitive, exact matches take priority via thematchesByNamehelper). - All instances — if no active character matched, falls back to
ax.character.instances(all loaded characters regardless of whether a player is using them). Numeric lookup uses direct table indexing; string lookup uses the same name-matching helper.
Returns nil when nothing is found.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
identifier |
number\|string |
A numeric character ID or a name string (full or partial). |
Returns
ax.character.meta|nil: The matched character object, or nil.
Usage
ax.util:FindCharacter(42) -- by ID
ax.util:FindCharacter("John") -- partial name match
ax.util:FindCharacter("john doe") -- case-insensitive
Source: gamemode/framework/util/util_find.lua:217
ax.util:FindPlayer(identifier)¶
Finds a connected player by a variety of identifier types.
Lookup is attempted in this priority order:
- If
identifieris already a valid Player entity, it is returned as-is. - If
identifieris a number,Entity(identifier)is returned. - If
identifieris a string, the following are tried in order:
a. SteamID format (e.g. "STEAM_0:1:12345") → player.GetBySteamID
b. SteamID64 format (e.g. "76561198...") → player.GetBySteamID64
c. Partial name/SteamID/SteamID64 substring match against all players (case-insensitive, first match wins).
- If
identifieris a table (array), each element is tried recursively and the first successful match is returned.
Returns NULL (not nil) on no match — callers should test with IsValid.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
identifier |
number\|string\|Player\|table |
An entity index, SteamID, SteamID64, name substring, a Player entity, or a table of any of these. |
Returns
Player|NULL: The matched player entity, orNULLif not found.
Usage
ax.util:FindPlayer("76561198000000000")
ax.util:FindPlayer("John") -- partial name match
ax.util:FindPlayer(1) -- entity index
Source: gamemode/framework/util/util_find.lua:141
ax.util:FindString(str, find, caseSensitive, startPos, usePatterns)¶
Tests whether find appears as a substring inside str.
By default the search is case-insensitive (both strings are lowercased via utf8.lower or string.lower before comparison) and pattern characters in find are treated as plain text. All optional parameters allow overriding these defaults when needed.
Prints an error and returns false when either str or find is nil.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
str |
string |
The string to search in. |
find |
string |
The substring (or pattern) to search for. |
caseSensitive |
boolean\|nil |
When true, the strings are compared without lowercasing. Default: false (case-insensitive). |
startPos |
number\|nil |
The character position to start searching from. Default: 0 (from the beginning). |
usePatterns |
boolean\|nil |
When true, find is treated as a Lua pattern. Default: false (plain-text search via string.find plain flag). |
Returns
boolean: True iffindappears instr, false otherwise.
Usage
ax.util:FindString("Hello World", "world") -- true
ax.util:FindString("Hello World", "World", true) -- true (exact case)
ax.util:FindString("Hello World", "World", false) -- true (case-insensitive)
ax.util:FindString("Hello World", "xyz") -- false
Source: gamemode/framework/util/util_find.lua:77
ax.util:FindText(txt, find)¶
Tests whether any word in a text block contains a substring.
Splits txt by both spaces and newlines and passes each word individually to FindString. Returns true as soon as any word matches. Returns false immediately when either argument is nil. This is more permissive than a whole-string search — it matches even when the query appears in only one word of a multi-word text.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
txt |
string |
The text block to split and search. |
find |
string |
The substring to look for in each word. |
Returns
boolean: True if any word intxtcontainsfind(case-insensitive).
Usage
ax.util:FindText("the quick brown fox", "quick") -- true
ax.util:FindText("hello\nworld", "world") -- true
ax.util:FindText("hello world", "xyz") -- false
Source: gamemode/framework/util/util_find.lua:105
ax.util:NormalizeSearchString(value)¶
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
User and character finder utilities.
Normalises a value into a lowercase, trimmed string for search comparisons.
Converts value to a string via tostring, trims leading/trailing whitespace, and lowercases the result using utf8.lower when available (falling back to string.lower). Returns "" when the result is empty or when value is nil. Used as a pre-processing step by SearchMatches to ensure consistent case-insensitive matching.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
value |
any |
The value to normalise (coerced to string). |
Returns
string: The trimmed, lowercased string, or""if empty/nil.
Usage
Source: gamemode/framework/util/util_find.lua:25
ax.util:SearchMatches(query, ...)¶
Tests whether a search query is contained in any of the provided candidates.
Both the query and each candidate are normalised with NormalizeSearchString before comparison. An empty query always returns true — this matches the convention of "show everything when the search box is blank". The check is substring-based (not exact match), so "cit" will match "citizen".
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
query |
string |
The search text to look for. |
... |
any |
Candidate values to test against (each coerced to string). |
Returns
boolean: True if the query is empty, or if any candidate contains the query as a substring (case-insensitive).
Usage
ax.util:SearchMatches("pol", "Citizen", "Police Officer") -- true
ax.util:SearchMatches("", "anything") -- true
ax.util:SearchMatches("xyz", "Citizen", "Police") -- false
Source: gamemode/framework/util/util_find.lua:47
ax.util:PreparePackage(...)¶
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
Printing and logging helpers.
Converts a list of values into a flat array suitable for MsgC output.
Iterates the arguments and converts each one as follows:
- Valid entities are converted to their
tostringrepresentation. - Valid player entities additionally get
[SteamID64]appended as a separate element so the output clearly identifies who was involved. - All other values are included as-is.
A newline string is always appended as the last element so that each call to a Print* function ends on its own line. The returned table can be unpacked directly into MsgC or used with table.concat.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
... |
any |
Any number of values to prepare. |
Returns
table: Flat array of values ready to unpack intoMsgCor similar.
Usage
local pkg = ax.util:PreparePackage("Player joined:", somePlayer)
MsgC(Color(255, 255, 255), unpack(pkg))
Source: gamemode/framework/util/util_print.lua:29
ax.util:Print(...)¶
Prints an informational message prefixed with [PARALLAX].
Uses MsgC with color_print (blue-ish Color(100, 150, 255)). Visible on both server and client consoles. All arguments are processed through PreparePackage — entities are converted to strings and players get their SteamID64 appended. A trailing newline is included automatically.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
... |
any |
Values to print. |
Returns
table: The prepared argument array that was printed.
Usage
Source: gamemode/framework/util/util_print.lua:64
ax.util:PrintDebug(...)¶
Prints a debug message, gated behind developer mode and realm convars.
Output is only produced when ALL of the following conditions are true:
- The
developerconvar is ≥ 1 (set withdeveloper 1in console). ax_debug_realmmatches the current realm:1→ client only2→ server only3→ both sides- If
ax_debug_filteris non-empty, the message must contain at least one of its comma-separated keywords (case-insensitive substring match). - If
ax_debug_rate_limitis positive, the same message (by content key) can only be printed once within that many seconds — prevents log spam from code running every frame.
Uses MsgC with color_debug (grey Color(150, 150, 150)). Returns nil silently when any gate condition prevents output.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
... |
any |
Values to include in the debug message. |
Returns
table|nil: The prepared argument array when printed, nil when gated.
Usage
ax.util:PrintDebug("Character loaded:", char:GetName())
ax.util:PrintDebug("Store set:", key, "=", value)
Source: gamemode/framework/util/util_print.lua:141
ax.util:PrintError(...)¶
Prints an error message prefixed with [PARALLAX] [ERROR], with a stack trace.
Uses ErrorNoHaltWithStack, so the full call stack is included in the console output. Execution continues after the call — this does NOT throw.
Use this for non-fatal errors where you want clear diagnostics without stopping the current execution path. Arguments are joined with spaces via table.concat after PreparePackage processing.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
... |
any |
Values to include in the error message. |
Returns
table: The prepared argument array that was printed.
Usage
Source: gamemode/framework/util/util_print.lua:80
ax.util:PrintSuccess(...)¶
Prints a success message prefixed with [PARALLAX] [SUCCESS].
Uses MsgC with color_success (green Color(100, 255, 100)). Use to confirm that an operation completed as expected — module loads, database connections established, configuration saved successfully, etc.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
... |
any |
Values to include in the success message. |
Returns
table: The prepared argument array that was printed.
Usage
ax.util:PrintSuccess("Database connected:", dbName)
ax.util:PrintSuccess("Configuration saved to", path)
Source: gamemode/framework/util/util_print.lua:110
ax.util:PrintWarning(...)¶
Prints a warning message prefixed with [PARALLAX] [WARNING].
Uses MsgC with color_warning (orange Color(255, 200, 100)). No stack trace is included — use PrintError when a stack trace is needed. Suitable for recoverable conditions that should be visible in the console without alarming users or halting execution.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
... |
any |
Values to include in the warning. |
Returns
table: The prepared argument array that was printed.
Usage
Source: gamemode/framework/util/util_print.lua:94
ax.util:AddSound(name, path, volume, pitch, channel, level)¶
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
Registers a named sound script and precaches it for use in gameplay.
Wraps sound.Add with validated inputs and sane defaults. After registration the sound is immediately precached via util.PrecacheSound, so callers do not need to call that separately. Sound scripts registered here can be emitted with Entity:EmitSound(name).
Defaults when parameters are omitted:
volume: 1.0 (full volume)pitch: 100 (normal pitch)channel:CHAN_AUTO(GMod selects the channel automatically)level: 75 dB (typical indoor sound radius)
path may be a string for a single file, or a table of file paths for random variation (GMod picks one at random per emission). pitch may be a fixed number (e.g. 100) or a { min, max } table for random pitch per emission (e.g. { 95, 105 }).
Returns false with a printed error when name or path is invalid.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
name |
string |
The sound script identifier (e.g. "ax.ui.click"). Use namespaced names to avoid collisions with other addons. |
path |
string\|table |
The sound file path(s) relative to sound/ (e.g. "buttons/button14.wav"). |
volume |
number\|nil |
Volume scalar 0–1. Default: 1.0. |
pitch |
number\|table\|nil |
Fixed pitch percent, or { min, max } table for random pitch. Default: 100. |
channel |
number\|nil |
Sound channel constant (CHAN_*). Default: CHAN_AUTO. |
level |
number\|nil |
Sound propagation level in dB. Default: 75. |
Returns
boolean: True on successful registration, false on invalid input.
Usage
ax.util:AddSound("ax.ui.click", "buttons/button14.wav")
ax.util:AddSound("ax.ui.notify", { "ambient/alarms/alarm1.wav", "ambient/alarms/alarm2.wav" }, 0.8, { 95, 105 })
Source: gamemode/framework/util/util_sound.lua:34
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" }
})
Source: gamemode/framework/util/util_store.lua:42
ax.util:CapText(text, maxLength)¶
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
Text utilities.
Truncates text to a maximum character count, appending "..." when cut.
If the text is already within maxLength characters it is returned unchanged. When truncation is needed, the text is cut to maxLength - 3 characters and "..." is appended, so the returned string is always at most maxLength characters long in total. Returns "" and prints an error when either argument is invalid.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
text |
string |
The text to truncate. |
maxLength |
number |
The maximum number of characters allowed (inclusive of the "..." suffix). |
Returns
string: The original text, or a truncated version ending with"...".
Usage
Source: gamemode/framework/util/util_text.lua:26
ax.util:CapTextWord(text, maxLength)¶
Truncates text at a word boundary to avoid splitting words mid-character.
Splits the text by spaces and accumulates words until the next word would exceed maxLength. The result always has "..." appended, even when the boundary falls exactly at maxLength. As a result the returned string may be shorter than maxLength if the last fitting word ends well before it.
Returns "" and prints an error when either argument is invalid.
Realm: shared
Parameters
| Name | Type | Description |
|---|---|---|
text |
string |
The text to truncate. |
maxLength |
number |
The maximum number of characters to aim for. |
Returns
string: Words that fit withinmaxLength, followed by"...".
Usage
ax.util:CapTextWord("the quick brown fox", 12) -- "the quick..."
ax.util:CapTextWord("hi", 50) -- "hi" (unchanged)
Source: gamemode/framework/util/util_text.lua:48
ax.util:GetTextHeight(font)¶
Returns the line height of a font in pixels.
Measures the height of the capital letter "W" as a representative character that occupies the full ascender height of the font. The result is the number of vertical pixels a single line of text in this font occupies. Calls surface.SetFont(font) as a side effect.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
font |
string |
The font name to measure. |
Returns
number: The line height in pixels.
Usage
Source: gamemode/framework/util/util_text.lua:160
ax.util:GetTextSize(font, text)¶
Returns the rendered pixel dimensions of a string in a given font.
Convenience wrapper that calls surface.SetFont(font) then returns both values from surface.GetTextSize(text) in one call. Use this when you need both width and height to avoid two separate font sets.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
font |
string |
The font name to measure with. |
text |
string |
The string to measure. |
Returns
number: Width oftextin pixels.number: Height oftextin pixels.
Usage
Source: gamemode/framework/util/util_text.lua:173
ax.util:GetTextWidth(font, text)¶
Returns the rendered pixel width of a string in a given font.
Calls surface.SetFont(font) as a side effect, changing the active surface font state. Use GetTextSize if you need both dimensions at once.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
font |
string |
The font name to measure with. |
text |
string |
The string to measure. |
Returns
number: The width oftextin pixels when rendered infont.
Usage
Source: gamemode/framework/util/util_text.lua:149
ax.util:GetWrappedText(text, font, maxWidth)¶
Splits text into lines that each fit within a pixel width limit.
Measures text using surface.GetTextSize with font to determine where line breaks should occur. Words are added to the current line until adding the next word would exceed maxWidth, at which point a new line is started. When a single word is wider than maxWidth, it is split character-by-character so it always fits. If the entire text fits on one line, a single-element table is returned immediately.
Returns false (with a printed error) when any argument is invalid.
Realm: client
Parameters
| Name | Type | Description |
|---|---|---|
text |
string |
The text to wrap. |
font |
string |
The font name used for pixel-width measurement. Must be a font registered with surface.CreateFont or a GMod built-in. |
maxWidth |
number |
The maximum line width in pixels. |
Returns
table|false: An ordered array of line strings, or false on invalid input.
Usage
local lines = ax.util:GetWrappedText("Hello world, how are you?", "DermaDefault", 100)
for _, line in ipairs(lines) do draw.SimpleText(line, ...) end
Source: gamemode/framework/util/util_text.lua:89
ax.util:GetBranch()¶
Returns the Git branch name this Parallax build was made from.
Performs the same two-tier lookup as GetVersion: live ax.version data first, then ReadVersionFile() as a fallback. Falls back to "unknown" when unavailable, so this function always returns a string. Useful for distinguishing between "main", "staging", or feature branches when diagnosing issues across different server deployments.
Realm: shared
Returns
string: The branch name (e.g."main","staging"), or"unknown"if version data is not available.
Usage
Source: gamemode/framework/util/util_version.lua:81
ax.util:GetCommitCount()¶
Returns the total commit count for this Parallax build.
Performs the same two-tier lookup as GetVersion: live ax.version data first, then ReadVersionFile() as a fallback. The value is coerced to a number via tonumber. Falls back to 0 when unavailable, so this function always returns a number. The commit count is useful for comparing build recency without parsing the version string.
Realm: shared
Returns
number: The commit count, or0as a safe fallback.
Usage
Source: gamemode/framework/util/util_version.lua:44
ax.util:GetCommitHash()¶
Returns the short Git commit hash for this Parallax build.
Performs the same two-tier lookup as GetVersion: live ax.version data first, then ReadVersionFile() as a fallback. Falls back to an empty string "" when unavailable, so this function always returns a string.
The hash is useful for identifying the exact source revision when reporting bugs or comparing server builds.
Realm: shared
Returns
string: The short commit hash (e.g."a3f2c1d"), or""if version data is not available.
Usage
Source: gamemode/framework/util/util_version.lua:63
ax.util:GetVersion()¶
Utility helpers used across the Parallax framework (printing, file handling, text utilities, etc.).
Versioning utilities.
Returns the Parallax framework version string (e.g. "0.3.42").
Performs a two-tier lookup:
- If
ax.versionis a table andax.version.data.versionis set (the live in-memory version populated at framework startup), that value is returned immediately. - Otherwise,
ax.version:ReadVersionFile()is called to readversion.jsonfrom disk and extract theversionfield.
Falls back to "0.0.0" when neither source yields a value, so this function always returns a string — never nil.
Realm: shared
Returns
string: The version string, or"0.0.0"as a safe fallback.
Usage
Source: gamemode/framework/util/util_version.lua:26