Skip to content

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)

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

ax.util:CreateBotCharacter(bot)

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

local name = ax.util:GenerateBotName() -- e.g. "Jordan Walker"

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

local faction = ax.util:GetRandomBotFaction()
if ( faction ) then print(faction.name) end

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

local ang = ax.util:ApproachAngle(fraction, eyeAng, targetAng)

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

local t = ax.util:ApproachFraction(0.5, 80) -- 0.4

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 via Lerp.
  • "smoothstep": applies a cubic ease-in/ease-out curve (t² × (3 − 2t)) before lerping, producing a gentle S-curve acceleration/deceleration.
  • "linear" or opts.linear = true: uses math.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 between start and finish.

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

local pos = ax.util:ApproachVector(fraction, startPos, endPos, { smooth = 80 })

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

ax.util:AssertDebug(self.registry[key], "Key not in registry:", key)

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

ax.util:DrawBlur(8, 10, 10, 200, 100, Color(255, 255, 255, 180))

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

-- Draw a 75% progress indicator
ax.util:DrawSlice(200, 200, 48, 0, 270, Color(100, 200, 255, 200))

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 if target is 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

local mat = ax.util:GetGradient("bottom")

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

local project = ax.util:GetProjectName() -- e.g. "parallax-militaryrp"

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

local data = ax.util:GetSurfaceDataViaName("metal")
if ( data ) then print(data.jumpfactor) end

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 if client has Lua type "Player".

Usage

if ( ax.util:IsValidPlayer(client) ) then
    client:ChatPrint("hello")
end

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:

  1. Spaces (including runs of whitespace) are replaced with underscores.
  2. CamelCase boundaries (lowercase letter followed by uppercase) get an underscore inserted between them, e.g. "MyModule" → "My_Module".
  3. Any character that is not a letter (A–Z, a–z) or underscore is stripped, so digits and punctuation are removed entirely.
  4. 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 by fn when successful.

Usage

local ok, a, b = ax.util:SafeCall(function() return 1, 2 end)

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 bToJson is true and tInput is a table, serialises the table to a JSON string via util.TableToJSON and returns it.
  • Otherwise, if tInput is a string, parses it as JSON via util.JSONToTable (wrapped in pcall) and returns the resulting table, or nil on parse failure. If tInput is 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

local w = ax.util:Scale(200)  -- 200 at 1.0x, 240 at 1.2x

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

local padding = ax.util:ScreenScale(8)

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

local rowHeight = ax.util:ScreenScaleH(16)

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:

  1. Underscores are replaced with spaces.
  2. Spaces are inserted at CamelCase boundaries (e.g. from an ID that was produced by merging camel-cased words).
  3. 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. Uses game.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 the DATA directory.

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

ax.util:EnsureDataDir("parallax/settings/")
ax.util:EnsureDataDir("global/maps/rp_city/")

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, calls AddCSLuaFile only (sends to clients). On the client, calls include.
  • "server": calls include on the server only. No-op on the client.
  • "shared": on the server, calls both AddCSLuaFile and include. On the client, calls include.

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

ax.util:Include("framework/sh_util.lua")
ax.util:Include("framework/sv_database.lua", "server")

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/or shared.lua (both).
  • Single-file layout: a single .lua file 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

local cfg = ax.util:ReadJSON("parallax/config.json")
if ( cfg ) then print(cfg.version) end

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

ax.util:WriteJSON("parallax/config.json", { version = "1.0" })

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:

  1. 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 using FindString (partial, case-insensitive, exact matches take priority via the matchesByName helper).
  2. 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:

  1. If identifier is already a valid Player entity, it is returned as-is.
  2. If identifier is a number, Entity(identifier) is returned.
  3. If identifier is 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).

  1. If identifier is 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, or NULL if 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 if find appears in str, 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 in txt contains find (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

ax.util:NormalizeSearchString("  Hello  ")  -- "hello"
ax.util:NormalizeSearchString(nil)                 -- ""

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 tostring representation.
  • 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 into MsgC or 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

ax.util:Print("Module loaded:", moduleName)
ax.util:Print("Player connected:", client)

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:

  1. The developer convar is ≥ 1 (set with developer 1 in console).
  2. ax_debug_realm matches the current realm:
  3. 1 → client only
  4. 2 → server only
  5. 3 → both sides
  6. If ax_debug_filter is non-empty, the message must contain at least one of its comma-separated keywords (case-insensitive substring match).
  7. If ax_debug_rate_limit is 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

ax.util:PrintError("Failed to load config:", err)

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

ax.util:PrintWarning("Deprecated function called, use NewFunc instead")

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:

  • name string: identifier used in debug messages (e.g. "config").
  • authority string: "server" or "client" — only that side persists and loads values from disk.
  • path string|function: DATA-relative path to the JSON file, or a function (spec, store) → string for dynamic paths.
  • net table: net channel names used for networking: init (bulk sync), set (single key update), sync (option bulk upload), request (server asks client to sync).
  • data table (optional): { key, options } for ax.data-backed persistence instead of raw JSON.
  • legacyPaths table (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

ax.util:CapText("Hello, World!", 8)  -- "Hello..."
ax.util:CapText("Hi", 10)                   -- "Hi" (unchanged)

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 within maxLength, 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

local lineH = ax.util:GetTextHeight("DermaDefault")

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 of text in pixels.
  • number: Height of text in pixels.

Usage

local w, h = ax.util:GetTextSize("DermaDefault", "Hello World")

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 of text in pixels when rendered in font.

Usage

local w = ax.util:GetTextWidth("DermaDefault", "Hello World")

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

local branch = ax.util:GetBranch()  -- e.g. "main"

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, or 0 as a safe fallback.

Usage

local count = ax.util:GetCommitCount()  -- e.g. 142

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

local hash = ax.util:GetCommitHash()  -- e.g. "a3f2c1d"

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:

  1. If ax.version is a table and ax.version.data.version is set (the live in-memory version populated at framework startup), that value is returned immediately.
  2. Otherwise, ax.version:ReadVersionFile() is called to read version.json from disk and extract the version field.

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

local v = ax.util:GetVersion()  -- e.g. "0.3.42"

Source: gamemode/framework/util/util_version.lua:26