FTE's console variables: one table every process of a game reads and writes, the server, its client program and its menu alike, as FTE's single process has one set.
cvars = QuakeServer.Cvars.new()
QuakeServer.Cvars.register(cvars, "sv_gravity", "800")
{:ok, _prints} = QuakeServer.Cvars.set(cvars, "sv_gravity", "600")
QuakeServer.Cvars.value(cvars, "sv_gravity")
#=> 600.0The table is an ETS table belonging to the process that called new/0; it lives as
long as that process and delete/1 frees it sooner. Reads never wait on another
process. Names are matched without regard to ASCII case, and a variable registered
with an :alias answers to both names.
A variable holds its value as text (string), with value the text read as FTE's
Q_atof reads it (a 32-bit float) and ival as Q_atoi reads it. Each has a default
(the value cvarreset gives back) and, for one the engine registers, the engine's own
default.
Flags are FTE's (flags/0): :archive (written by cfg_save, set by seta),
:userinfo and :serverinfo (the value is the player's or the server's info key of
the same name), :noset (read only), :maplatch (a change while a server runs waits
for the next map), :rendererlatch and :videolatch (a change while the renderer is
up waits for vid_reload or vid_restart), :notfromserver (no program or server
may set it), :nounsafeexpand (no program may read it), :usercreated (made by a
config or a program rather than the engine) and the rest of FTE's.
Every change is stamped and counts up the table's generation (generation/1), so a
program's autocvar_ globals and a server's info keys follow it
(QuakeServer.Autocvars).
The table also holds what FTE keeps beside its cvars: whether a server or a renderer
is running (put_running/3), whether an archived variable changed since the last save
(unsaved?/1), the directory configs are written to (home/1), the console aliases
(command_alias/2) and the key bindings with their bind maps (binding/3,
bindmaps/1).
Summary
Functions
Give name the flags flags besides its own; nothing when there is no such variable.
Give every variable with any of the flags flags (one flag or a list) its latched
value, as FTE's Cvar_ApplyLatches, and with clear: true take those flags off them
all. Returns how many had a latched value.
The variables as FTE's cfg_save writes them (Cvar_WriteVariables): the archived
ones, or with all? every one but cl_warncmd; never read only or :nosave ones.
Each group is headed by a // group line; an engine variable is written as name "value", one a config or program made as seta or set, with its description after
// at the next multiple of eight columns (at least 24), each of its lines so.
Text read as a number, as FTE's Q_atof: a 32-bit float.
Text read as a whole number, as FTE's Q_atoi.
The key binding of key number keynum in modifier state modifier (0 to 15, as
QuakeServer.Keys numbers them) as {command, level}, or nil when it is unbound.
Every key binding as {keynum, modifier, command, level}, by key number then modifier.
The two modifier states key presses read their bindings from (FTE's key_bindmaps), {0, 0} at first.
The bitmask of flag names names.
Text read as a number, as C's atof: leading spaces, a sign, digits, a point and an exponent; a 32-bit float.
The console alias name's commands, or nil when there is none.
Every console alias as {name, commands}, sorted by name.
Free the table; it may not be used after.
Whether there is a variable name.
The variable name, or nil when there is none.
Whether cvar has flag name.
FTE's flag bits by name.
A number as FTE's Cvar_SetValue writes it: six decimals, trailing zeros and point dropped.
How many changes the table has seen; it counts up with every change.
The variable name, made when there is none, as FTE's Cvar_Get2: one that is there
takes on :userinfo and :serverinfo from flags; one made is created by a config or
a program (:usercreated) with default as its value and default and the other
flags. A name with a quote, ^, $, ; or whitespace in it, or an empty one, makes
nothing: nil. Options: :description, :group (default "Custom variables").
The directory cfg_save writes configs to and exec reads them from first, or nil.
The variables flagged :serverinfo or :userinfo, as {name, stamp}.
Every variable, sorted by name.
Every variable's default becomes its value, unless read only or a cheat (FTE's cvar_lockdefaults).
The server takes the variable over, as FTE's Cvar_LockFromServer: it is set to
value past its latches and flagged :serveroverride, its own value kept as the
latched one to come back to (apply_latches/3 with :serveroverride).
A new, empty table belonging to the calling process.
Every engine variable's default goes back to the engine's (FTE's cvar_purgedefaults); values stay.
Bind key number keynum in modifier state modifier to command at restriction
level, or unbind it with nil; either way the configuration counts as changed
(unsaved?/1).
Set the two modifier states key presses read their bindings from.
Make console alias name run commands, as FTE's alias command.
Make value variable name's engine default, as FTE's Cvar_SetEngineDefault: its
default follows when it was the engine's; its value is left as it is. Nothing when
there is no such variable.
Use directory as the place configs are written to and read from first.
Mark whether a server (:server) or the renderer (:renderer) is running, for the latching flags.
Register an engine variable, as FTE's Cvar_Register: one not there is made with
default as its value, its default and its engine default; one a config or a program
made first becomes the engine's, keeping its value (its latched one, if any) and its
:archive flag; one the engine registered already is left as it is.
Take the flags flags off name; nothing when there is no such variable.
Set back to their defaults the variables whose names match pattern (* and ?
wildcards; * or nil is every one), as FTE's cvarreset. Options: :group (only
variables of a group matching it), alt: true (second names match too), :exclude
(flag names; variables with any are left). :noreset variables are left, as are read
only ones when every variable is reset. Returns the lines printed.
The defaults of engine variables go back to the engine's, as FTE's
cvar_resettodefaults_*: :all, :saved (archived only) or :unsaved; read only and
:noreset variables are left.
Whether a server (:server) or the renderer (:renderer) is running.
Mark the archived variables saved.
The server's info keys from its :serverinfo variables: every one with a value.
Set name to value (nil for its default), as FTE's Cvar_Set: a read-only
variable is refused; a variable latched by its flags keeps value for later (a
:maplatch one while a server runs, a :rendererlatch or :videolatch one while the
renderer is up); otherwise the value changes, any latched value is dropped, and an
engine variable's own check runs (r_meshpitch and r_meshroll become 1 or -1, fov
at least 10, viewsize 30 to 120).
The change stamp of name, or nil when there is no such variable.
The value of name as text, "" when there is no such variable.
Whether an archived variable changed since the last save (FTE's cvars_haveunsaved).
The player's info keys from the :userinfo variables: every one with a value.
The value of name as a number, 0.0 when there is no such variable.
Types
@type flag() ::
:archive
| :userinfo
| :serverinfo
| :noset
| :maplatch
| :notfromserver
| :usercreated
| :cheat
| :semicheat
| :rendererlatch
| :serveroverride
| :renderercallback
| :nounsafeexpand
| :rulesetlatch
| :shadersystem
| :tellgamecode
| :configdefault
| :nosave
| :noreset
| :teamplaytaint
| :watched
| :videolatch
| :warnonchange
| :rendereroverride
@type t() :: %QuakeServer.Cvars{ generation: :atomics.atomics_ref(), release: boolean(), table: :ets.tid() }
Functions
Give name the flags flags besides its own; nothing when there is no such variable.
@spec apply_latches(t(), flag() | [flag()], keyword()) :: non_neg_integer()
Give every variable with any of the flags flags (one flag or a list) its latched
value, as FTE's Cvar_ApplyLatches, and with clear: true take those flags off them
all. Returns how many had a latched value.
The variables as FTE's cfg_save writes them (Cvar_WriteVariables): the archived
ones, or with all? every one but cl_warncmd; never read only or :nosave ones.
Each group is headed by a // group line; an engine variable is written as name "value", one a config or program made as seta or set, with its description after
// at the next multiple of eight columns (at least 24), each of its lines so.
Text read as a number, as FTE's Q_atof: a 32-bit float.
Text read as a whole number, as FTE's Q_atoi.
@spec binding(t(), integer(), non_neg_integer()) :: {String.t(), integer()} | nil
The key binding of key number keynum in modifier state modifier (0 to 15, as
QuakeServer.Keys numbers them) as {command, level}, or nil when it is unbound.
@spec bindings(t()) :: [{integer(), non_neg_integer(), String.t(), integer()}]
Every key binding as {keynum, modifier, command, level}, by key number then modifier.
@spec bindmaps(t()) :: {non_neg_integer(), non_neg_integer()}
The two modifier states key presses read their bindings from (FTE's key_bindmaps), {0, 0} at first.
@spec bits([flag()]) :: non_neg_integer()
The bitmask of flag names names.
Text read as a number, as C's atof: leading spaces, a sign, digits, a point and an exponent; a 32-bit float.
The console alias name's commands, or nil when there is none.
Every console alias as {name, commands}, sorted by name.
@spec delete(t()) :: :ok
Free the table; it may not be used after.
Whether there is a variable name.
@spec fetch(t(), String.t()) :: QuakeServer.Cvars.Cvar.t() | nil
The variable name, or nil when there is none.
@spec flag?(QuakeServer.Cvars.Cvar.t(), flag()) :: boolean()
Whether cvar has flag name.
@spec flags() :: %{required(flag()) => pos_integer()}
FTE's flag bits by name.
A number as FTE's Cvar_SetValue writes it: six decimals, trailing zeros and point dropped.
@spec generation(t()) :: non_neg_integer()
How many changes the table has seen; it counts up with every change.
The variable name, made when there is none, as FTE's Cvar_Get2: one that is there
takes on :userinfo and :serverinfo from flags; one made is created by a config or
a program (:usercreated) with default as its value and default and the other
flags. A name with a quote, ^, $, ; or whitespace in it, or an empty one, makes
nothing: nil. Options: :description, :group (default "Custom variables").
The directory cfg_save writes configs to and exec reads them from first, or nil.
The variables flagged :serverinfo or :userinfo, as {name, stamp}.
@spec list(t()) :: [QuakeServer.Cvars.Cvar.t()]
Every variable, sorted by name.
@spec lock_defaults(t()) :: :ok
Every variable's default becomes its value, unless read only or a cheat (FTE's cvar_lockdefaults).
The server takes the variable over, as FTE's Cvar_LockFromServer: it is set to
value past its latches and flagged :serveroverride, its own value kept as the
latched one to come back to (apply_latches/3 with :serveroverride).
@spec new() :: t()
A new, empty table belonging to the calling process.
@spec purge_defaults(t()) :: :ok
Every engine variable's default goes back to the engine's (FTE's cvar_purgedefaults); values stay.
@spec put_binding(t(), integer(), non_neg_integer(), String.t() | nil, integer()) :: :ok
Bind key number keynum in modifier state modifier to command at restriction
level, or unbind it with nil; either way the configuration counts as changed
(unsaved?/1).
@spec put_bindmaps(t(), {non_neg_integer(), non_neg_integer()}) :: :ok
Set the two modifier states key presses read their bindings from.
Make console alias name run commands, as FTE's alias command.
Make value variable name's engine default, as FTE's Cvar_SetEngineDefault: its
default follows when it was the engine's; its value is left as it is. Nothing when
there is no such variable.
Use directory as the place configs are written to and read from first.
Mark whether a server (:server) or the renderer (:renderer) is running, for the latching flags.
@spec register(t(), String.t(), String.t(), keyword()) :: QuakeServer.Cvars.Cvar.t()
Register an engine variable, as FTE's Cvar_Register: one not there is made with
default as its value, its default and its engine default; one a config or a program
made first becomes the engine's, keeping its value (its latched one, if any) and its
:archive flag; one the engine registered already is left as it is.
Options: :flags (a list of flag/0), :alias, :description, :group.
Take the flags flags off name; nothing when there is no such variable.
Set back to their defaults the variables whose names match pattern (* and ?
wildcards; * or nil is every one), as FTE's cvarreset. Options: :group (only
variables of a group matching it), alt: true (second names match too), :exclude
(flag names; variables with any are left). :noreset variables are left, as are read
only ones when every variable is reset. Returns the lines printed.
@spec reset_defaults(t(), :all | :saved | :unsaved) :: :ok
The defaults of engine variables go back to the engine's, as FTE's
cvar_resettodefaults_*: :all, :saved (archived only) or :unsaved; read only and
:noreset variables are left.
Whether a server (:server) or the renderer (:renderer) is running.
@spec saved(t()) :: :ok
Mark the archived variables saved.
The server's info keys from its :serverinfo variables: every one with a value.
Set name to value (nil for its default), as FTE's Cvar_Set: a read-only
variable is refused; a variable latched by its flags keeps value for later (a
:maplatch one while a server runs, a :rendererlatch or :videolatch one while the
renderer is up); otherwise the value changes, any latched value is dropped, and an
engine variable's own check runs (r_meshpitch and r_meshroll become 1 or -1, fov
at least 10, viewsize 30 to 120).
{:ok, lines} gives the lines FTE prints about it (latching while cl_warncmd is set,
read only); {:error, :missing} when there is no such variable. Option force: true
sets past the latches and :noset.
The change stamp of name, or nil when there is no such variable.
The value of name as text, "" when there is no such variable.
Whether an archived variable changed since the last save (FTE's cvars_haveunsaved).
The player's info keys from the :userinfo variables: every one with a value.
The value of name as a number, 0.0 when there is no such variable.