### Start Datastream: Clockwork vs Helix Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Illustrates the change in starting a datastream. Helix's `netstream.Start` function takes individual arguments instead of a table for data. ```lua -- before Clockwork.datastream:Start(receiver, "MessageName", {1, 2, 3}); -- after netstream.Start(receiver, "MessageName", 1, 2, 3) ``` -------------------------------- ### Register, Get, and Set Server Configurations Source: https://context7.com/nebulouscloud/helix/llms.txt Use `ix.config.Add` to register configuration options. Read values with `ix.config.Get` and modify them with `ix.config.Set`. `ix.config.SetDefault` can override framework defaults. ```lua -- SHARED: register configs (typically in schema config file) ix.config.Add("startingMoney", 100, "How much money new characters start with.", function(old, new) print("startingMoney changed from", old, "to", new) end, { category = "economy", data = { min = 0, max = 10000 } }) ix.config.Add("pvpEnabled", false, "Whether PvP is allowed.") -- SHARED: read config (with fallback default) local startMoney = ix.config.Get("startingMoney", 100) local pvp = ix.config.Get("pvpEnabled", false) -- SERVER: change a config value (also broadcasts to clients) ix.config.Set("startingMoney", 250) -- Override schema-level default (e.g., change framework default from schema) ix.config.SetDefault("maxCharacters", 3) ``` -------------------------------- ### Configuration System (`ix.config`) Source: https://context7.com/nebulouscloud/helix/llms.txt Manage server configuration options that can be modified in-game and persist across restarts. Supports adding, getting, and setting configuration values. ```APIDOC ## `ix.config.Add` / `ix.config.Get` / `ix.config.Set` Registers server configuration options that can be changed in-game by superadmins and persist between restarts. ### Usage ```lua -- Add a new configuration option ix.config.Add("startingMoney", 100, "How much money new characters start with.", function(old, new) print("startingMoney changed from", old, "to", new) end, { category = "economy", data = { min = 0, max = 10000 } }) ix.config.Add("pvpEnabled", false, "Whether PvP is allowed.") -- Get a configuration option's value local startMoney = ix.config.Get("startingMoney", 100) local pvp = ix.config.Get("pvpEnabled", false) -- Set a configuration option's value (broadcasts to clients) ix.config.Set("startingMoney", 250) -- Set a default value for a schema-level configuration ix.config.SetDefault("maxCharacters", 3) ``` ``` -------------------------------- ### Minimal Schema Skeleton Setup Source: https://context7.com/nebulouscloud/helix/llms.txt A basic schema requires `init.lua` and `cl_init.lua` to derive from Helix, and `sh_schema.lua` to define schema properties, include additional files, set currency, and override framework defaults. ```lua -- gamemode/init.lua AddCSLuaFile("cl_init.lua") DeriveGamemode("helix") -- gamemode/cl_init.lua DeriveGamemode("helix") -- schema/sh_schema.lua Schema.name = "My RP" Schema.author = "me" Schema.description = "A custom roleplay schema built on Helix." Schema.folder = "myrp" -- must match the gamemode folder name -- Include additional files ix.util.Include("cl_schema.lua") ix.util.Include("sv_schema.lua") -- Set up currency ix.currency.Set("$", "dollar", "dollars") -- Override a framework default config ix.config.SetDefault("maxCharacters", 3) ix.config.SetDefault("defaultMoney", 150) ``` -------------------------------- ### Schema Bootstrap Source: https://context7.com/nebulouscloud/helix/llms.txt Provides a minimal skeleton for creating a custom schema, including essential files and setup steps. ```APIDOC ## Schema Bootstrap ### Minimal schema skeleton A schema is a derived gamemode. The minimum required files and setup are: ```lua -- gamemode/init.lua AddCSLuaFile("cl_init.lua") DeriveGamemode("helix") -- gamemode/cl_init.lua DeriveGamemode("helix") -- schema/sh_schema.lua Schema.name = "My RP" Schema.author = "me" Schema.description = "A custom roleplay schema built on Helix." Schema.folder = "myrp" -- must match the gamemode folder name -- Include additional files ix.util.Include("cl_schema.lua") ix.util.Include("sv_schema.lua") -- Set up currency ix.currency.Set("$", "dollar", "dollars") -- Override a framework default config ix.config.SetDefault("maxCharacters", 3) ix.config.SetDefault("defaultMoney", 150) ``` ``` -------------------------------- ### Install LDoc for Documentation Building Source: https://github.com/nebulouscloud/helix/blob/master/README.md Installs LDoc, a documentation generator for Lua, which is used for building the Helix documentation. Ensure LuaRocks is installed before running these commands. ```shell git clone https://github.com/impulsh/ldoc cd ldoc luarocks make ``` ```shell ldoc . ``` -------------------------------- ### Animation Model Class Setup: Clockwork vs. Helix Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Shows how to associate a model with an animation class. Clockwork uses a specific function per model type, whereas Helix uses a general function to set the class for any model. ```lua -- before Clockwork.animation:AddCivilProtectionModel("models/mymodel.mdl") -- after ix.anim.SetModelClass("models/mymodel.mdl", "metrocop") ``` -------------------------------- ### Client Initialization (cl_init.lua) Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/getting-started.md This file handles client-side initialization for your gamemode, deriving it from 'helix'. ```lua DeriveGamemode("helix") ``` -------------------------------- ### Iterate Players with Active Characters Source: https://context7.com/nebulouscloud/helix/llms.txt Use `ix.util.GetCharacters` to get an iterator yielding `(player, character)` pairs, skipping players without loaded characters. ```lua for client, character in ix.util.GetCharacters() do print(client:SteamName(), character:GetName(), character:GetMoney()) end -- > Bot01 John Doe 50 -- > Bot02 Jane Smith 120 ``` -------------------------------- ### Plugin System (`ix.plugin`) Source: https://context7.com/nebulouscloud/helix/llms.txt Enables the creation and management of plugins. Plugins are loaded from `plugins//sh_plugin.lua` and can register hooks and manage persistent data. ```APIDOC ## Plugin System (`ix.plugin`) ### Creating a plugin — `sh_plugin.lua` structure Plugins live in `plugins//` and must have a `sh_plugin.lua` entrypoint. Functions defined on `PLUGIN` are automatically registered as hooks. ### Usage ```lua -- plugins/myplugin/sh_plugin.lua PLUGIN.name = "My Plugin" PLUGIN.author = "me" PLUGIN.description = "Demonstrates the plugin system." -- Example hook: PlayerSpawn function PLUGIN:PlayerSpawn(client) if client:GetCharacter() then client:NotifyLocalized("greetPlayer", client:GetName()) end end -- Example hook: AdjustCreationPayload function PLUGIN:AdjustCreationPayload(client, payload, newPayload) newPayload.money = 200 end -- Persistent plugin data function PLUGIN:SaveData() self:SetData({ someKey = "someValue" }) end function PLUGIN:LoadData() local data = self:GetData() print(data.someKey) end function PLUGIN:OnLoaded() print(self.name .. " loaded!") end ``` ``` -------------------------------- ### Modify Schema Hook Function and Arguments Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md When converting from Clockwork to Helix, you will need to modify the function name and arguments for your schema or plugin hooks. The example shows a before and after state of a hook. ```lua -- before function Schema:PlayerPlayPainSound(player, gender, damageInfo, hitGroup) -- ... end -- after function Schema:GetPlayerPainSound(client) -- ... end ``` -------------------------------- ### Configure and Use Currency with ix.currency Source: https://context7.com/nebulouscloud/helix/llms.txt Sets up the server's currency system, formats currency amounts, spawns money entities, and allows manipulation of character money. ```lua -- SHARED: configure currency (call in schema sh_schema.lua) ix.currency.Set("$", "dollar", "dollars", "models/props_lab/box01a.mdl") ``` ```lua -- SHARED: format an amount as a string print(ix.currency.Get(1)) -- > $1 dollar print(ix.currency.Get(50)) -- > $50 dollars ``` ```lua -- SERVER: spawn a money pile at a location local moneyEnt = ix.currency.Spawn(Vector(100, 200, 300), 250) ``` ```lua -- Character money manipulation (SERVER): local char = client:GetCharacter() char:GiveMoney(100) -- add 100 char:TakeMoney(25) -- subtract 25 print(char:GetMoney()) -- > 125 print(char:HasMoney(200)) -- > false ``` -------------------------------- ### Retrieve Faction with ix.faction.Get Source: https://context7.com/nebulouscloud/helix/llms.txt Get a faction object using its numeric index (team number) or its unique string ID. The retrieved faction object contains properties like `name` and `color`. ```lua -- by numeric index (team number) local faction = ix.faction.Get(client:Team()) print(faction.name) -- "Citizen" print(faction.color) -- Color table -- by uniqueID string local faction2 = ix.faction.Get("citizen") print(faction2.index) -- 1 ``` -------------------------------- ### Initialize Gamemode (init.lua) Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/getting-started.md This file is essential for initializing your gamemode. It derives the gamemode from 'helix' and ensures client-side files are added. ```lua AddCSLuaFile("cl_init.lua") DeriveGamemode("helix") ``` -------------------------------- ### Plugin Name, Author, and Description Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Define essential plugin metadata in sh_plugin.lua. Ensure PLUGIN table is localized if used after loading. ```lua PLUGIN.name = "Plugin Name" PLUGIN.author = "Plugin Author" PLUGIN.description = "Plugin Description" ``` -------------------------------- ### Add Item to Inventory with Inventory:Add (SERVER) Source: https://context7.com/nebulouscloud/helix/llms.txt On the server, use `inv:Add` to place an item into a character's inventory. It finds an empty slot and creates an instance of the item. Handles quantity and returns success status with an error message if it fails. ```lua -- SERVER: give item to a player's main inventory local char = client:GetCharacter() local inv = char:GetInventory() local success, err = inv:Add("bandage", 2) -- 2x bandage if not success then client:NotifyLocalized(err or "unknownError") end ``` -------------------------------- ### Add Configuration: Clockwork vs Helix Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Demonstrates the syntax change for adding configurations. Helix consolidates arguments into a single `Add` function. ```lua -- before Clockwork.config:Add("run_speed", 225) -- after ix.config.Add("runSpeed", 235, ...) ``` -------------------------------- ### ix.util.Include / ix.util.IncludeDir Source: https://context7.com/nebulouscloud/helix/llms.txt Includes Lua files, automatically handling realm-specific inclusion (`sh_`, `sv_`, `cl_`) and directory traversal. Should be called from a shared context. ```APIDOC ## ix.util.Include — Realm-aware file inclusion Includes a Lua file with automatic `AddCSLuaFile` and `include` calls based on filename prefix (`sv_`, `sh_`, `cl_`) or explicit realm argument. Should always be called from shared context. ```lua -- include a shared file (auto-sent to client) ix.util.Include("schema/sh_myrules.lua") -- include a server-only file ix.util.Include("schema/sv_economy.lua") -- include a client-only file ix.util.Include("schema/cl_hud.lua", "client") -- include all .lua files in a directory (uses file prefix for realm) ix.util.IncludeDir("schema/libs") ``` ``` -------------------------------- ### Find All Commands with ix.command.FindAll Source: https://context7.com/nebulouscloud/helix/llms.txt Searches for registered commands matching a query. Supports sorting and exact matching. ```lua -- find all commands matching "char", sorted, with exact match first local results = ix.command.FindAll("char", true, true, true) for _, cmd in ipairs(results) do print(cmd.name, cmd:GetDescription()) end ``` -------------------------------- ### Include Lua Files with Realm Awareness Source: https://context7.com/nebulouscloud/helix/llms.txt Use `ix.util.Include` to automatically handle `AddCSLuaFile` and `include` calls based on filename prefixes or explicit realm arguments. Always call from shared context. ```lua -- include a shared file (auto-sent to client) ix.util.Include("schema/sh_myrules.lua") ``` ```lua -- include a server-only file ix.util.Include("schema/sv_economy.lua") ``` ```lua -- include a client-only file ix.util.Include("schema/cl_hud.lua", "client") ``` ```lua -- include all .lua files in a directory (uses file prefix for realm) ix.util.IncludeDir("schema/libs") ``` -------------------------------- ### Hook System (`hook.SafeRun`) Source: https://context7.com/nebulouscloud/helix/llms.txt Provides a safe way to execute hooks using `pcall`, returning any errors encountered along with the hook's results. ```APIDOC ### `hook.SafeRun` — Protected hook execution Runs a hook inside a `pcall` and returns any errors alongside the hook's return values. ### Usage ```lua -- Run a hook safely local errors, result = hook.SafeRun("MyCustomHook", arg1, arg2) if errors and #errors > 0 then for _, err in ipairs(errors) do print("[Error]", err.plugin or err.schema, err.errorMessage) end else print("Hook returned:", result) end ``` ``` -------------------------------- ### Create and Persist a New Character with ix.char.Create (SERVER) Source: https://context7.com/nebulouscloud/helix/llms.txt This server-side function creates a new character record in the database, sets up its default inventory, and calls a callback with the new character's ID. Ensure all required fields like name, model, and faction are provided. ```lua -- SERVER ix.char.Create({ name = "John Doe", description = "A weathered survivor.", model = "models/humans/group01/male_01.mdl", faction = "citizen", -- uniqueID of faction steamID = client:SteamID64(), money = 50, data = { skin = 0, groups = {} } }, function(charID) print("Created character with ID:", charID) -- ix.char.loaded[charID] is now available end) ``` -------------------------------- ### Include File Utility Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Replace Clockwork's IncludePrefixed utility with Helix's ix.util.Include for including files. ```lua Clockwork.kernel:IncludePrefixed("sh_myfile.lua") ``` ```lua ix.util.Include("sh_myfile.lua") ``` -------------------------------- ### Spawning and Giving Items: Clockwork vs. Helix Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Demonstrates the simplified methods for spawning items in the map and giving items to players in Helix compared to Clockwork. Helix handles item instancing automatically in these cases. ```lua -- spawning an item in the map Clockwork.entity:CreateItem(player, Clockwork.item:CreateInstance("item"), Vector(1, 2, 3)); -- giving a player an item player:GiveItem(Clockwork.item:CreateInstance("item")); ``` ```lua -- spawning an item in the map ix.item.Spawn("item", Vector(1, 2, 3)) -- giving a player an item client:GetCharacter():GetInventory():Add("test") ``` -------------------------------- ### Spawn Item Entity in World with ix.item.Spawn (SERVER) Source: https://context7.com/nebulouscloud/helix/llms.txt This server-side function instances an item in the database and creates its corresponding world entity. It provides a callback with the item's ID and the entity object. ```lua -- SERVER ix.item.Spawn("pistol", Vector(100, 200, 300), function(item, entity) print("Spawned item ID:", item:GetID()) print("Entity:", entity) end, Angle(0, 90, 0), { ammo = 12 }) ``` -------------------------------- ### Create New Item Instance with ix.item.Instance (SERVER) Source: https://context7.com/nebulouscloud/helix/llms.txt A low-level server-side function to create an item instance in a specific inventory slot. Prefer `inventory:Add()` for general use. This function allows specifying the inventory ID, item name, data, and precise slot coordinates. ```lua -- SERVER: add item to inventory 5 at slot (2, 3) ix.item.Instance(5, "medkit", { uses = 3 }, 2, 3, function(item) print("Item instance created:", item:GetID()) item:SetData("uses", 3) end) ``` -------------------------------- ### Currency System Source: https://context7.com/nebulouscloud/helix/llms.txt Manages the in-game currency, allowing configuration, formatting, spawning money entities, and character money manipulation. ```APIDOC ## Currency System (`ix.currency`) ### `ix.currency.Set` / `ix.currency.Get` / `ix.currency.Spawn` Configures the server currency and provides helpers for formatting and spawning money entities. ```lua -- SHARED: configure currency (call in schema sh_schema.lua) ix.currency.Set("$", "dollar", "dollars", "models/props_lab/box01a.mdl") -- SHARED: format an amount as a string print(ix.currency.Get(1)) -- > $1 dollar print(ix.currency.Get(50)) -- > $50 dollars -- SERVER: spawn a money pile at a location local moneyEnt = ix.currency.Spawn(Vector(100, 200, 300), 250) -- Character money manipulation (SERVER): local char = client:GetCharacter() char:GiveMoney(100) -- add 100 char:TakeMoney(25) -- subtract 25 print(char:GetMoney()) -- > 125 print(char:HasMoney(200)) -- > false ``` ``` -------------------------------- ### Restore Inventories from Database with ix.inventory.Restore (SERVER) Source: https://context7.com/nebulouscloud/helix/llms.txt Server-side function to load inventories and their contents from the database. Allows specifying inventory IDs and their grid sizes, with an optional callback for post-restoration actions. ```lua -- SERVER: restore two inventories with different sizes ix.inventory.Restore({ [10] = {5, 5}, -- inventoryID 10, 5x5 grid [11] = {7, 4}, -- inventoryID 11, 7x4 grid }, nil, nil, function(inventory) print("Restored inventory:", inventory:GetID(), inventory.w, inventory.h) end) ``` -------------------------------- ### Retrieve Item Definition with ix.item.Get Source: https://context7.com/nebulouscloud/helix/llms.txt Use `ix.item.Get` to fetch the base definition of an item. This returns the item's properties but not an instance. Check if the definition exists before accessing its properties. ```lua local itemDef = ix.item.Get("pistol") if itemDef then print(itemDef.name) -- "Pistol" print(itemDef.model) -- "models/weapons/w_pistol.mdl" print(itemDef.width) -- 1 print(itemDef.height) -- 2 end ``` -------------------------------- ### Schema Configuration (sh_schema.lua) Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/getting-started.md Defines the core properties of your schema, such as name, author, and description. It also includes other schema files. ```lua Schema.name = "My Schema" Schema.author = "me!" Schema.description = "My awesome schema." -- include your other schema files ix.util.Include("cl_schema.lua") ix.util.Include("sv_schema.lua") -- etc. ``` -------------------------------- ### External MySQL Configuration with helix.yml Source: https://context7.com/nebulouscloud/helix/llms.txt To use MySQL instead of SQLite, create a `helix.yml` file in `garrysmod/gamemodes/helix/` with the specified database connection details. ```yaml database: adapter: "mysqloo" hostname: "127.0.0.1" username: "helix_user" password: "secret" database: "helix_db" port: 3306 ``` -------------------------------- ### Language System (`ix.lang`) Source: https://context7.com/nebulouscloud/helix/llms.txt Provides multi-language support by allowing phrases to be added to specific languages and retrieved using the `L` global function, respecting player language preferences. ```APIDOC ## Language System (`ix.lang`) ### `ix.lang.AddTable` / `L()` — Multi-language support Add phrases to a language and retrieve them with the `L` global function (respects player language preference). ### Usage ```lua -- Add phrases to the English language table ix.lang.AddTable("english", { greetPlayer = "Welcome, %s!", farewellPlayer = "Goodbye, %s. Come back soon.", moneyReceived = "You received %s." }) -- Retrieve a localized phrase (client-side or server-side for a specific client) print(L("greetPlayer", "Alice")) -- Example output: Welcome, Alice! print(L("farewellPlayer", "Bob")) -- Example output: Goodbye, Bob. Come back soon. -- On the server, always pass the client as the second argument for context -- client:ChatPrint(L("greetPlayer", client, client:GetName())) -- Retrieve a phrase, returning nil if not found local phrase = L2("greetPlayer", "Alice") ``` ``` -------------------------------- ### Database Configuration (`helix.yml`) Source: https://context7.com/nebulouscloud/helix/llms.txt Allows external configuration of the database connection, specifically for using MySQL via the `mysqloo` adapter. ```APIDOC ## Database (`ix.db` / MySQL configuration) ### `helix.yml` — External MySQL configuration To use MySQL instead of the default SQLite, create `garrysmod/gamemodes/helix/helix.yml` with the following structure: ```yaml database: adapter: "mysqloo" hostname: "127.0.0.1" username: "helix_user" password: "secret" database: "helix_db" port: 3306 ``` ``` -------------------------------- ### Register Chat/Console Command with ix.command.Add Source: https://context7.com/nebulouscloud/helix/llms.txt Use `ix.command.Add` to register commands accessible via chat (`/CommandName`) or console (`ix CommandName`). Supports access control (e.g., `adminOnly`) and argument type checking using `ix.type`. ```lua -- SHARED: register a simple admin command with typed arguments ix.command.Add("CharGiveMoney", { description = "Give money to a character.", adminOnly = true, arguments = { ix.type.character, ix.type.number }, OnRun = function(self, client, target, amount) if amount <= 0 then return "@invalidAmount" end target:GiveMoney(amount) client:NotifyLocalized("moneyGiven", amount) end }) -- CLIENT: send the command programmatically ix.command.Send("CharGiveMoney", "John", 100) -- SERVER: force run a command programmatically ix.command.Run(client, "CharGiveMoney", {"John", "100"}) -- Parse raw chat text (SERVER): ix.command.Parse(client, "/CharGiveMoney John 100") ``` -------------------------------- ### Item Definition Source: https://context7.com/nebulouscloud/helix/llms.txt Defines a custom item by creating a Lua file in the appropriate directory. This includes properties like name, description, model, size, price, and functions for usage. ```APIDOC ## Item definition — Defining a custom item Items are defined in `items//sh_.lua` (or `items/base/sh_.lua` for bases). ### Example `items/consumables/sh_medkit.lua` ```lua ITEM.name = "Medical Kit" ITEM.description = "Restores 50 HP when used." ITEM.model = "models/items/healthkit.mdl" ITEM.width = 2 ITEM.height = 2 ITEM.price = 100 ITEM.functions.Use = { tip = "useTip", icon = "icon16/heart.png", OnRun = function(item) local client = item.player client:SetHealth(math.min(client:Health() + 50, 100)) client:EmitSound("items/smallmedkit1.wav") -- return true to remove item, false to keep it return true end, OnCanRun = function(item) return item.player:Health() < 100 end } ``` ``` -------------------------------- ### ix.item.Instance Source: https://context7.com/nebulouscloud/helix/llms.txt Creates a new item instance in a specific inventory slot. ```APIDOC ## ix.item.Instance ### Description Low-level item creation into a specific inventory slot. Prefer `inventory:Add()` for normal use. This function is intended for server-side use. ### Parameters - **inventoryID** (number) - The ID of the inventory to add the item to. - **itemType** (string) - The unique identifier of the item type. - **itemData** (table, optional) - Data associated with the item instance. - **slotX** (number) - The X-coordinate of the inventory slot. - **slotY** (number) - The Y-coordinate of the inventory slot. - **callback** (function, optional) - A function called with the created `item` object. ### Example ```lua -- SERVER: add item to inventory 5 at slot (2, 3) ix.item.Instance(5, "medkit", { uses = 3 }, 2, 3, function(item) print("Item instance created:", item:GetID()) item:SetData("uses", 3) end) ``` ``` -------------------------------- ### Define a Custom Item Source: https://context7.com/nebulouscloud/helix/llms.txt Create custom items by defining their properties (name, description, model, size, price) and functions (like `Use` or `OnCanRun`) in shared Lua files. The `Use` function should return `true` to consume the item. ```lua -- items/consumables/sh_medkit.lua ITEM.name = "Medical Kit" ITEM.description = "Restores 50 HP when used." ITEM.model = "models/items/healthkit.mdl" ITEM.width = 2 ITEM.height = 2 ITEM.price = 100 ITEM.functions.Use = { tip = "useTip", icon = "icon16/heart.png", OnRun = function(item) local client = item.player client:SetHealth(math.min(client:Health() + 50, 100)) client:EmitSound("items/smallmedkit1.wav") -- return true to remove item, false to keep it return true end, OnCanRun = function(item) return item.player:Health() < 100 end } ``` -------------------------------- ### Item Instancing: Clockwork vs. Helix Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Compares the item instancing methods between Clockwork and Helix. Helix uses a callback system for asynchronous database insertion, while Clockwork returns the instance directly. ```lua -- Clockwork instancing item = Clockwork.item:CreateInstance("item") ``` ```lua -- Helix instancing ix.item.Instance(0, "item", data, x, y, function(item) end) ``` -------------------------------- ### Define a Class and Join with Character:JoinClass Source: https://context7.com/nebulouscloud/helix/llms.txt Classes are sub-roles defined in `classes/sh_.lua` using the `CLASS` table. They have properties like name, description, faction, and limits. `Character:JoinClass` attempts to assign a player to a class, returning success or failure. ```lua -- schema/classes/sh_recruit.lua CLASS.name = "Recruit" CLASS.description = "New to the force." CLASS.faction = FACTION_POLICE -- faction index global CLASS.limit = 0 -- 0 = unlimited CLASS.isDefault = true function CLASS:CanSwitchTo(client) return true end -- SERVER: assign a class local success = client:GetCharacter():JoinClass(1) if not success then client:Notify("Cannot join that class.") end -- Get all players in class 1 local players = ix.class.GetPlayers(1) for _, ply in ipairs(players) do print(ply:GetName()) end ``` -------------------------------- ### ix.command.FindAll Source: https://context7.com/nebulouscloud/helix/llms.txt Searches for registered commands that match a given query string. It supports sorting and exact matching options. ```APIDOC ## ix.command.FindAll — Search registered commands Searches for registered commands matching a query string, with options for sorting and exact matching. ### Usage ```lua -- find all commands matching "char", sorted, with exact match first local results = ix.command.FindAll("char", true, true, true) for _, cmd in ipairs(results) do print(cmd.name, cmd:GetDescription()) end ``` ``` -------------------------------- ### Play Sounds Sequentially with ix.util.EmitQueuedSounds Source: https://context7.com/nebulouscloud/helix/llms.txt Use this function to play a list of sounds one after another from a specific entity. You can configure delays between sounds. ```lua local sounds = { "ambient/alarms/klaxon1.wav", {"ambient/alarms/klaxon1.wav", 0.2, 0.5}, -- {path, postDelay, preDelay} "ambient/alarms/klaxon1.wav", } local totalDuration = ix.util.EmitQueuedSounds(someEntity, sounds, 0, 0.1, 75, 100) print("Sequence ends in " .. totalDuration .. " seconds") ``` -------------------------------- ### Check Command Access with ix.command.HasAccess Source: https://context7.com/nebulouscloud/helix/llms.txt Verify if a client has permission to execute a specific command using `ix.command.HasAccess`. This is useful for conditional logic or UI elements. ```lua if ix.command.HasAccess(client, "CharGiveMoney") then print("Client can use CharGiveMoney") end ``` -------------------------------- ### ix.command.Add Source: https://context7.com/nebulouscloud/helix/llms.txt Registers a chat or console command. Commands can be invoked via `/CommandName` in chat or `ix CommandName` in the console. Supports access control and argument type checking. ```APIDOC ## `ix.command.Add` — Register a chat/console command Registers a command invokable via `/CommandName` in chat or `ix CommandName` in console. Supports CAMI-based access control and strict argument type checking. ### Usage ```lua -- SHARED: register a simple admin command with typed arguments ix.command.Add("CharGiveMoney", { description = "Give money to a character.", adminOnly = true, arguments = { ix.type.character, ix.type.number }, OnRun = function(self, client, target, amount) if amount <= 0 then return "@invalidAmount" end target:GiveMoney(amount) client:NotifyLocalized("moneyGiven", amount) end }) -- CLIENT: send the command programmatically ix.command.Send("CharGiveMoney", "John", 100) -- SERVER: force run a command programmatically ix.command.Run(client, "CharGiveMoney", {"John", "100"}) -- Parse raw chat text (SERVER): ix.command.Parse(client, "/CharGiveMoney John 100") ``` ``` -------------------------------- ### Add and Retrieve Multi-language Phrases Source: https://context7.com/nebulouscloud/helix/llms.txt Use `ix.lang.AddTable` to define phrases for different languages. Retrieve them using the global `L()` function, which respects player language preferences. `L2()` returns nil if a phrase is not found. ```lua -- SHARED: add phrases to English (single-file plugin style) ix.lang.AddTable("english", { greetPlayer = "Welcome, %s!", farewellPlayer = "Goodbye, %s. Come back soon.", moneyReceived = "You received %s." }) -- CLIENT / SERVER (client-side): print(L("greetPlayer", "Alice")) -- > Welcome, Alice! print(L("farewellPlayer", "Bob")) -- > Goodbye, Bob. Come back soon. -- SERVER (always pass the client as second argument): client:ChatPrint(L("greetPlayer", client, client:GetName())) -- L2 returns nil if phrase not found (instead of the key itself): local phrase = L2("greetPlayer", "Alice") ``` -------------------------------- ### Force Character Off with Character:Kick / Character:Ban (SERVER) Source: https://context7.com/nebulouscloud/helix/llms.txt Use `Kick` to return a player to the character selection menu. Use `Ban` to additionally prevent the character from being used for a specified duration, or permanently. ```lua local char = client:GetCharacter() -- kick back to character menu char:Kick() -- ban for 1 hour (3600 seconds) char:Ban(3600) -- permanent ban char:Ban() ``` -------------------------------- ### ix.faction.LoadFromDir Source: https://context7.com/nebulouscloud/helix/llms.txt Loads faction definitions from Lua files within a specified directory. This function is typically called automatically by the framework during initialization. ```APIDOC ## `ix.faction.LoadFromDir` — Load factions from directory Called automatically; parses all `sh_*.lua` files in a directory and registers them as GMod teams. ### Example `schema/factions/sh_citizen.lua` ```lua -- schema/factions/sh_citizen.lua (auto-loaded by framework) FACTION.name = "Citizen" FACTION.description = "An ordinary citizen." FACTION.color = Color(100, 220, 100) FACTION.isDefault = true -- selectable without whitelist FACTION.models = { "models/humans/group01/male_01.mdl", "models/humans/group01/female_01.mdl", } FACTION_CITIZEN = FACTION.index -- store global index ``` ``` -------------------------------- ### ix.item.Spawn Source: https://context7.com/nebulouscloud/helix/llms.txt Spawns an item entity in the world and in the database. ```APIDOC ## ix.item.Spawn ### Description Instances an item in the database and creates its world entity. This function is intended for server-side use. ### Parameters - **itemType** (string) - The unique identifier of the item type to spawn. - **position** (Vector) - The world position where the item should be spawned. - **callback** (function) - A function called with the created `item` object and its `entity`. - **angles** (Angle, optional) - The initial angles for the spawned item entity. - **data** (table, optional) - Additional data to associate with the item instance (e.g., ammo count). ### Example ```lua -- SERVER ix.item.Spawn("pistol", Vector(100, 200, 300), function(item, entity) print("Spawned item ID:", item:GetID()) print("Entity:", entity) end, Angle(0, 90, 0), { ammo = 12 }) ``` ``` -------------------------------- ### Safe Hook Execution with hook.SafeRun Source: https://context7.com/nebulouscloud/helix/llms.txt Use `hook.SafeRun` to execute hooks within a `pcall`. This prevents errors in hooks from crashing the calling function and returns any errors encountered. ```lua -- Run a hook safely - errors won't crash the calling function local errors, result = hook.SafeRun("MyCustomHook", arg1, arg2) if errors and #errors > 0 then for _, err in ipairs(errors) do print("[Error]", err.plugin or err.schema, err.errorMessage) end else print("Hook returned:", result) end ``` -------------------------------- ### ix.util.EmitQueuedSounds Source: https://context7.com/nebulouscloud/helix/llms.txt Plays a list of sounds sequentially with configurable delays and spacing. ```APIDOC ## ix.util.EmitQueuedSounds ### Description Plays a list of sounds one after another from an entity with configurable delays and spacing. ### Parameters - **entity** (Entity) - The entity to play sounds from. - **sounds** (table) - A list of sounds to play. Each element can be a string (sound path) or a table {path, postDelay, preDelay}. - **delay** (number) - Initial delay before the first sound plays. - **spacing** (number) - Spacing between sounds. - **volume** (number) - Volume for the sounds. - **pitch** (number) - Pitch for the sounds. ### Returns - **totalDuration** (number) - The total duration of the sound sequence in seconds. ### Example ```lua local sounds = { "ambient/alarms/klaxon1.wav", {"ambient/alarms/klaxon1.wav", 0.2, 0.5}, -- {path, postDelay, preDelay} "ambient/alarms/klaxon1.wav", } local totalDuration = ix.util.EmitQueuedSounds(someEntity, sounds, 0, 0.1, 75, 100) print("Sequence ends in " .. totalDuration .. " seconds") ``` ``` -------------------------------- ### Class Definition and Character:JoinClass Source: https://context7.com/nebulouscloud/helix/llms.txt Defines classes as sub-roles within factions and provides a method for characters to join a specific class. It also includes a function to retrieve all players currently in a given class. ```APIDOC ## Class definition and `Character:JoinClass` Classes are sub-roles within a faction defined in `classes/sh_.lua`. ### Example `schema/classes/sh_recruit.lua` ```lua -- schema/classes/sh_recruit.lua CLASS.name = "Recruit" CLASS.description = "New to the force." CLASS.faction = FACTION_POLICE -- faction index global CLASS.limit = 0 -- 0 = unlimited CLASS.isDefault = true function CLASS:CanSwitchTo(client) return true end -- SERVER: assign a class local success = client:GetCharacter():JoinClass(1) if not success then client:Notify("Cannot join that class.") end -- Get all players in class 1 local players = ix.class.GetPlayers(1) for _, ply in ipairs(players) do print(ply:GetName()) end ``` ``` -------------------------------- ### Inventory:Add Source: https://context7.com/nebulouscloud/helix/llms.txt Adds an item to an inventory. This function attempts to find an empty slot and create an instance of the item within the inventory. It returns false and an error string on failure. ```APIDOC ## Inventory:Add — Add an item to an inventory (SERVER) Finds an empty slot and instances the item into the inventory. Returns `false, errorString` on failure. ### Usage ```lua -- SERVER: give item to a player's main inventory local char = client:GetCharacter() local inv = char:GetInventory() local success, err = inv:Add("bandage", 2) -- 2x bandage if not success then client:NotifyLocalized(err or "unknownError") end ``` ``` -------------------------------- ### ix.char.Create Source: https://context7.com/nebulouscloud/helix/llms.txt Creates and persists a new character in the database. ```APIDOC ## ix.char.Create ### Description Creates a character record in the database, generates its default inventory, and calls the callback with the new character ID. This function is intended for server-side use. ### Parameters - **options** (table) - A table containing character creation options: - **name** (string) - The name of the character. - **description** (string) - A description for the character. - **model** (string) - The model path for the character. - **faction** (string) - The unique ID of the character's faction. - **steamID** (string) - The 64-bit Steam ID of the player. - **money** (number) - The starting amount of money for the character. - **data** (table, optional) - Additional data for the character (e.g., skin, groups). - **callback** (function) - A function to be called with the new character ID upon successful creation. ### Example ```lua -- SERVER ix.char.Create({ name = "John Doe", description = "A weathered survivor.", model = "models/humans/group01/male_01.mdl", faction = "citizen", -- uniqueID of faction steamID = client:SteamID64(), money = 50, data = { skin = 0, groups = {} } }, function(charID) print("Created character with ID:", charID) -- ix.char.loaded[charID] is now available end) ``` ``` -------------------------------- ### Register Custom Chat Classes with ix.chat.Register Source: https://context7.com/nebulouscloud/helix/llms.txt Defines new chat message types with custom formatting, colors, and access rules. Requires the 'InitializedChatClasses' hook. ```lua -- SHARED (inside InitializedChatClasses hook): hook.Add("InitializedChatClasses", "MyRadioChat", function() ix.chat.Register("radio", { prefix = {"/R", "/Radio"}, format = "[RADIO] %s: \"%s\"", color = Color(100, 200, 100), description = "Transmit over the radio.", CanHear = function(self, speaker, listener) -- only players in the same faction hear this return speaker:Team() == listener:Team() end, CanSay = function(self, speaker, text) if not speaker:Alive() then speaker:NotifyLocalized("noPerm") return false end return speaker:GetCharacter():HasFlags("r") end }) end) ``` ```lua -- SERVER: send a message programmatically ix.chat.Send(client, "radio", "Sector 4 is clear.", false) ``` ```lua -- SERVER: broadcast an event message to everyone ix.chat.Send(nil, "event", "A mysterious figure has arrived.") ``` -------------------------------- ### Define a Faction with FACTION table Source: https://context7.com/nebulouscloud/helix/llms.txt Factions are defined using the `FACTION` table in `sh_*.lua` files within the `factions` directory. Properties include name, description, color, default status, and available models. The framework automatically loads these. ```lua -- schema/factions/sh_citizen.lua (auto-loaded by framework) FACTION.name = "Citizen" FACTION.description = "An ordinary citizen." FACTION.color = Color(100, 220, 100) FACTION.isDefault = true -- selectable without whitelist FACTION.models = { "models/humans/group01/male_01.mdl", "models/humans/group01/female_01.mdl", } FACTION_CITIZEN = FACTION.index -- store global index ``` -------------------------------- ### Set Currency Name: Clockwork vs Helix Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Shows the updated method for setting currency names. Helix uses a more structured `Set` function with symbol, singular, and plural arguments. ```lua -- before Clockwork.config:SetKey("name_cash", "Tokens") Clockwork.config:SetKey("name_cash", "Dollars") -- another example -- after ix.currency.Set("", "token", "tokens") ix.currency.Set("$", "dollar", "dollars") ``` -------------------------------- ### Parse Human-Readable Time Strings Source: https://context7.com/nebulouscloud/helix/llms.txt Convert human-readable time strings (e.g., '5y2d7w') into seconds using `ix.util.GetStringTime`. Bare numbers are treated as minutes. ```lua print(ix.util.GetStringTime("10")) -- 600 (10 minutes) print(ix.util.GetStringTime("1h30m")) -- 5400 (1.5 hours) print(ix.util.GetStringTime("5y2d7w")) -- 162086400 print(ix.util.GetStringTime("2h")) -- 7200 ``` -------------------------------- ### Helix Plugin Structure and Hooks Source: https://context7.com/nebulouscloud/helix/llms.txt Plugins are placed in `plugins//` with an `sh_plugin.lua` entrypoint. Functions defined on `PLUGIN` are automatically registered as hooks. Persistent data can be managed using `self:SetData` and `self:GetData`. ```lua -- plugins/myplugin/sh_plugin.lua PLUGIN.name = "My Plugin" PLUGIN.author = "me" PLUGIN.description = "Demonstrates the plugin system." -- Hook: runs when any player spawns (auto-registered via HOOKS_CACHE) function PLUGIN:PlayerSpawn(client) if client:GetCharacter() then client:NotifyLocalized("greetPlayer", client:GetName()) end end -- Hook: modify character creation function PLUGIN:AdjustCreationPayload(client, payload, newPayload) -- force all new characters to start with 200 money newPayload.money = 200 end -- Persistent plugin data (SERVER/CLIENT): function PLUGIN:SaveData() self:SetData({ someKey = "someValue" }) end function PLUGIN:LoadData() local data = self:GetData() print(data.someKey) -- > "someValue" end function PLUGIN:OnLoaded() print(self.name .. " loaded!") end ``` -------------------------------- ### Manage Player Flags: Clockwork vs Helix Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Demonstrates the updated methods for managing player flags. Helix uses character-specific methods accessed via `client:GetCharacter()`. ```lua -- before Clockwork.player:GiveFlags(player, flags) Clockwork.player:TakeFlags(player, flags) Clockwork.player:HasFlags(player, flags) -- after client:GetCharacter():GiveFlags(flags) client:GetCharacter():TakeFlags(flags) client:GetCharacter():HasFlags(flags) ``` -------------------------------- ### Add Flag: Clockwork vs Helix Source: https://github.com/nebulouscloud/helix/blob/master/docs/manual/converting-from-clockwork.md Shows the simplified syntax for adding a new flag in Helix. The description is now the second argument, and the name is omitted. ```lua -- before Clockwork.flag:Add("x", "Name", "Description") -- after ix.flag.Add("x", "Description") ``` -------------------------------- ### Find Players by Name or SteamID Source: https://context7.com/nebulouscloud/helix/llms.txt Use `ix.util.FindPlayer` to search connected players by partial name or exact Steam ID. The second argument can disable Lua pattern matching for safer user input. ```lua -- server-side: find player by partial name local target = ix.util.FindPlayer("John") if target then target:Notify("Found you!") end ``` ```lua -- find by full SteamID local target2 = ix.util.FindPlayer("STEAM_0:1:12345678") ``` ```lua -- disallow Lua patterns (safer for user input) local target3 = ix.util.FindPlayer(someUserInput, false) ``` -------------------------------- ### ix.inventory.Restore Source: https://context7.com/nebulouscloud/helix/llms.txt Loads inventories and their associated items from the database into memory. This is a server-side function. ```APIDOC ## ix.inventory.Restore — Load inventories from database (SERVER) Loads one or more inventories and their items from the database into memory. ### Usage ```lua -- SERVER: restore two inventories with different sizes ix.inventory.Restore({ [10] = {5, 5}, -- inventoryID 10, 5x5 grid [11] = {7, 4}, -- inventoryID 11, 7x4 grid }, nil, nil, function(inventory) print("Restored inventory:", inventory:GetID(), inventory.w, inventory.h) end) ``` ``` -------------------------------- ### ix.item.Get Source: https://context7.com/nebulouscloud/helix/llms.txt Retrieves the base item definition for a given item ID. This returns the template, not an instance of the item. ```APIDOC ## ix.item.Get — Retrieve an item template Returns the base item definition table (not an instance). ### Usage ```lua local itemDef = ix.item.Get("pistol") if itemDef then print(itemDef.name) -- "Pistol" print(itemDef.model) -- "models/weapons/w_pistol.mdl" print(itemDef.width) -- 1 print(itemDef.height) -- 2 end ``` ```