### Configure Installation Directory Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Sets the target directory for server file installation. Must be executed before logging in. ```text force_install_dir /home/steam/gmod_ds/ ``` -------------------------------- ### Handle Installation Order Error Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Error message displayed if the installation directory is not set before logging in. ```text Please use force_install_dir before logon! ``` -------------------------------- ### Install CSS Server Files Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Commands to set the CSS directory and update the application. ```text force_install_dir /home/steam/css_ds/ app_update 232330 -validate ``` -------------------------------- ### Install Required Software Packages Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Commands to install necessary dependencies for running the server on various Linux distributions. ```bash apt install lib32gcc1 lib32stdc++6 lib32tinfo5 wget ``` ```bash yum install glibc.i686 libstdc++.i686 ncurses-compat-libs.686 wget ``` ```bash dnf install glibc.i686 libstdc++.i686 ncurses-compat-libs.i686 wget ``` -------------------------------- ### Reference Hardware Specifications Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Example hardware configurations used for testing the server environment. ```text CPU: 2 logical Cores @2.1Ghz x86_64 RAM: 4Gb DDR3 (ECC non-buffered 1333Mhz) Storage: 32Gb HDD Network: 100/30 MBit down/up OS: Ubuntu-18.04 64-Bit ``` ```text CPU: 1 logical Core @3.5Ghz x86_64 RAM: 4Gb DDR3 (ECC non-buffered 1333Mhz) Storage: 32Gb HDD Network: 100/30 MBit down/up OS: Ubuntu-20.04 64-Bit ``` ```text CPU: 4 logical Cores @1,5Ghz x86_64 RAM: 8Gb DDR3 (non-ECC 1333Mhz) Storage: 60Gb SSD Network: 100/30 MBit down/up OS: Fedora32 64-Bit ``` -------------------------------- ### mount.cfg file structure Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Examples of the mount.cfg file content before and after modification. ```text // // Use this file to mount additional paths to the filesystem // DO NOT add a slash to the end of the filename // "mountcfg" { //"cstrike" "C:\mycssserver\cstrike" //"tf" "C:\mytf2server\tf" } ``` ```text // // Use this file to mount additional paths to the filesystem // DO NOT add a slash to the end of the filename // "mountcfg" { "cstrike" "/home/steam/css_ds/cstrike" //"tf" "C:\mytf2server\tf" } ``` -------------------------------- ### Start server with Workshop collection Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Command to launch the server while including a specific Steam Workshop collection ID. ```bash ~/gmod_ds/srcds_run -game garrysmod +gamemode terrortown +maxplayers 16 +map gm_flatgrass +host_workshop_collection 2052244154 ``` -------------------------------- ### Install SteamCMD on Linux Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Commands to create a directory, download the SteamCMD archive, and extract the files. ```bash mkdir ~/steam # create the 'steam' directory in the home directory cd ~/steam # go to the steam directory wget http://media.steampowered.com/client/steamcmd_linux.tar.gz # download the compressed steamcmd files tar -xvzf steamcmd_linux.tar.gz # uncompress the files ``` -------------------------------- ### Install or Update App Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Downloads or updates the specified application ID with validation. ```text app_update 4020 -validate ``` -------------------------------- ### Start Garrysmod server Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Command to launch the server with specific game mode, player count, and map settings. ```bash ~/gmod_ds/srcds_run -game garrysmod +gamemode terrortown +maxplayers 16 +map gm_flatgrass ``` -------------------------------- ### Example addon.json file Source: https://docs.ttt2.neoxult.de/developers/basics/creating-an-addon The addon.json file defines metadata, categories, and file exclusion rules for the Steam Workshop. ```json { "title": "My Addon", "type": "weapon", "tags": [ "fun", "roleplay" ], "ignore": [ "*.txt", "*.md" ] } ``` -------------------------------- ### SteamCMD Shell Prompt Source: https://docs.ttt2.neoxult.de/server-owners/manual-install The expected shell prompt after successfully starting SteamCMD. ```text Steam> ``` -------------------------------- ### Language File Directory Structure Source: https://docs.ttt2.neoxult.de/developers/content-creation/language-support Example of the required file system hierarchy for organizing language files within an addon. ```text / └── lua/ └── terrortown/ └── lang/ ├── de/ | └── pharoah.lua ├── en/ | └── pharoah.lua └── it/ └── pharoah.lua ``` -------------------------------- ### Define HUD base class Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-hud-theme Initial setup for the cl_init.lua file to define the base class for the HUD. ```lua local base = "scalable_hud" DEFINE_BASECLASS(base) HUD.Base = base ``` -------------------------------- ### Defining Parametric Language Strings Source: https://docs.ttt2.neoxult.de/developers/content-creation/language-support Example of a translation string containing placeholders for dynamic values. ```lua L["ankh_health_points"] = "Health: {health} / {maxhealth}" ``` -------------------------------- ### Force HUD elements Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-hud-theme Example of forcing specific HUD elements and using pure_skin fallbacks within the Initialize function. ```lua function HUD:Initialize() self:ForceElement("octagonal_playerinfo") self:ForceElement("octagonal_wswitch") self:ForceElement("octagonal_drowning") self:ForceElement("octagonal_mstack") self:ForceElement("octagonal_sidebar") self:ForceElement("octagonal_punchometer") self:ForceElement("octagonal_target") -- use pure skin fallback for roundinfo elements self:ForceElement("pure_skin_roundinfo") self:ForceElement("pure_skin_teamindicator") self:ForceElement("pure_skin_miniscoreboard") BaseClass.Initialize(self) end ``` -------------------------------- ### Implement remote controlled TargetID Source: https://docs.ttt2.neoxult.de/developers/content-creation/using-targetid Example implementation of TTTModifyTargetedEntity to redirect TargetID logic to a remote entity's perspective. ```lua -- Assuming this entity is assigned local remoteEntity local isRemoteControlled = false -- Set this to true, when being in remote-View -- Enable TargetID when controlling the sheep hook.Add("TTTModifyTargetedEntity", "remoteTargetId", function() if isRemoteControlled then return remoteTargetId(remoteEntity) end end) local function remoteTargetId(ent) local pos = ent:GetPos() local dir = ent:GetAngles():Forward() local filter = {ent} -- filters itself out, so you don't show your own targetID targetEnt, distance = targetid.FindEntityAlongView(pos, dir, filter) return targetEnt end ``` -------------------------------- ### Execute Startup Script Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Run the server using the created startup script. ```bash ./ttt2_server.sh ``` -------------------------------- ### Initialize Startup Script Directory Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Create and enter a dedicated directory for server management scripts. ```bash mkdir ~/startscripts/ # create the directory cd ~/startscripts/ # move inside the created directory ``` -------------------------------- ### Create Startup Script File Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Initialize a new shell script file for the server startup command. ```bash nano ttt2_server.sh ``` -------------------------------- ### Clientside Initialization Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-weapon Configure viewmodel settings, icons, and buy menu data for the client. Use language identifiers for name and description fields to support localization. ```lua if CLIENT then -- How much of the first person viewmodel is seen SWEP.ViewModelFOV = 70 -- If true, the viewmodel is on the left SWEP.ViewModelFlip = true -- Does the client draw its own crosshair over the default ones SWEP.DrawCrossHair = false -- The filename of the icon shown in the buymenu SWEP.Icon = "vgui/ttt/blue_template_icon.vtf" -- The information shown in the buy menu SWEP.EquipMenuData = { type = "item_weapon", name = "weapon_template_name", desc = "weapon_tempalte_desc" } end ``` -------------------------------- ### Define Server Startup Scripts Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Minimal and advanced startup scripts for launching the server, with the advanced version using tmux for background execution. ```bash ~/gmod_ds/srcds_run -game garrysmod +gamemode terrortown +maxplayers 16 +map gm_flatgrass +host_workshop_collection 2052244154 +sv_setsteamaccount WHATEVERYOURTOKENIS ``` ```bash #!/bin/bash echo "Starting Histalek's TTT2 Server. Connect to the serverconsole with 'tmux a -t ttt2'!" tmux new -d -s ttt2 '~/gmod_ds/srcds_run -game garrysmod +gamemode terrortown +maxplayers 16 +map gm_flatgrass +host_workshop_collection 2052244154 +sv_setsteamaccount WHATEVERYOURTOKENIS' ``` -------------------------------- ### Initialize a SQL Table Source: https://docs.ttt2.neoxult.de/developers/content-creation/sql-orm Defines the table structure and creates it in the database. ```lua local sqlTableName = "an_unique_table_name" local savingKeys = { state = {typ = "bool", default = false}, amount = {typ = "number", bits = 8, default = 0} } sql.CreateSqlTable(sqlTableName, savingKeys) ``` ```lua if not sql.CreateSqlTable(sqlTableName, savingKeys) then return end ``` -------------------------------- ### Define Finish Prepare Callback Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Callback function triggered on the second key press before activation. ```lua classData.OnFinishPrepareAbilityActivation = function(ply) -- [default: nil] ``` -------------------------------- ### Set Script Permissions Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Make the startup script executable by the current user. ```bash chmod u+x ttt2_server.sh ``` -------------------------------- ### Initialize Player List Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Retrieves all players on the server into a local variable. ```lua local plys = player.GetAll() ``` -------------------------------- ### KARMA.DoKarmaChange Source: https://docs.ttt2.neoxult.de/developers/content-creation/using-karma A global function used to add or subtract karma from a player. The change is applied to the base karma at the start of the next round. ```APIDOC ## KARMA.DoKarmaChange(ply, amount, reason) ### Description Modifies a player's karma value. The change is applied to the base karma before damage reduction calculations occur in the next round. ### Parameters - **ply** (Player) - Required - The player object whose karma is being modified. - **amount** (Number) - Required - The amount of karma to change. Can be a positive or negative value. - **reason** (String) - Required - A string or localization key displayed as a tooltip in the round-end screen. ``` -------------------------------- ### Configure Steam Game Server Account Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Add the Steam account token to the server startup command to improve server browser ranking. ```bash ~/gmod_ds/srcds_run -game garrysmod +gamemode terrortown +maxplayers 16 +map gm_flatgrass +host_workshop_collection 2052244154 +sv_setsteamaccount WHATEVERYOURTOKENIS ``` -------------------------------- ### Define Prepare Callback Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Callback function triggered prior to activation, enabling two-step activation. ```lua classData.OnStartPrepareAbilityActivation = function(ply) -- [default: nil] ``` -------------------------------- ### Initialize Server-Side File Synchronization Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Ensures the script file is sent to the client upon joining the server. ```lua if SERVER then AddCSLuaFile() end ``` -------------------------------- ### Serverside Initialization Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-weapon Use this block to share files and resources with the client. Ensure unique file paths for icons to prevent display conflicts. ```lua if SERVER then -- Shares the specified file with the client (if blank shares current file) AddCSLuaFile() -- Shares the buy menu icon with the client resource.AddFile("materials/vgui/ttt/blue_template_icon.vmt") end ``` -------------------------------- ### Minimal server.cfg configuration Source: https://docs.ttt2.neoxult.de/server-owners/manual-install A basic server.cfg file template for setting server identity, logging, and network rates. ```text hostname "My Garrysmod Server" sv_password "" sv_allowdownload 0 sv_allowupload 0 sv_timeout 60 log on sv_logbans 1 sv_logecho 0 sv_logfile 1 sv_log_onefile 0 sv_minrate 0 sv_maxrate 20000 sv_maxupdaterate 66 sv_minupdaterate 10 //execute ban files exec banned_ip.cfg exec banned_user.cfg ``` -------------------------------- ### Define Role Configuration and Initialization Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Sets the core properties, scoring multipliers, and team assignment for a new role. ```lua function ROLE:PreInitialize() self.color = Color(209, 98, 90, 255) self.abbr = "test" self.surviveBonus = 0 self.score.killsMultiplier = 2 self.score.teamKillsMultiplier = -8 self.preventFindCredits = false self.preventKillCredits = false self.preventTraitorAloneCredits = false self.preventWin = false self.unknownTeam = false self.defaultTeam = TEAM_TRAITOR self.conVarData = { pct = 0.15, -- necessary: percentage of getting this role selected (per player) maximum = 1, -- maximum amount of roles in a round minPlayers = 7, -- minimum amount of players until this role is able to get selected credits = 2, -- the starting credits of a specific role shopFallback = SHOP_FALLBACK_DETECTIVE, -- granting the role access to the shop togglable = true, -- option to toggle a role for a client if possible (F1 menu) random = 33 } end function ROLE:Initialize() roles.SetBaseRole(self, ROLE_TRAITOR) end ``` -------------------------------- ### Create Unprivileged Server User Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Command to create a new user account for running the server securely. ```bash sudo useradd -m steam ``` -------------------------------- ### Edit mount.cfg Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Command to open the mount configuration file for editing with nano. ```bash nano ~/gmod_ds/garrysmod/cfg/mount.cfg ``` -------------------------------- ### Configure Charging Time Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Sets the duration the activation key must be held; use nil for instant activation. ```lua classData.charging = -- [default: nil] ``` -------------------------------- ### Register a Basic Class Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Registers a new class with a unique name, color, and localized language strings. This must be executed on both client and server. ```lua -- Example 1 - A basic class CLASS.AddClass("YOURCLASS", { color = Color(149, 188, 195, 255), lang = { name = { English = "Your Class", Deutsch = "Deine Klasse" }, desc = { English = "A class description", Deutsch = "Eine Klassenbeschreibung" } } }) ``` -------------------------------- ### Execute SteamCMD Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Command to initialize the SteamCMD script and trigger self-updates. ```bash ./steamcmd.sh # execute the steamcmd script ``` -------------------------------- ### Create an ORM Model Source: https://docs.ttt2.neoxult.de/developers/content-creation/sql-orm Instantiates an ORM model for an existing SQL table. ```lua local ormModel = orm.Make(sqlTableName) ``` -------------------------------- ### Manage Server Branch Updates Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Commands to switch between standard, experimental 64-bit, and stable server branches via SteamCMD. ```bash app_update 4020 validate ``` ```bash app_update 4020 -beta x86-64 validate ``` ```bash app_update 4020 -beta NONE validate ``` -------------------------------- ### Initialize HUD function Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-hud-theme The basic structure for the HUD initialization function. ```lua function HUD:Initialize() -- something end ``` -------------------------------- ### Switch to Server User Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Commands to switch to the steam user and ensure the bash shell is active. ```bash sudo su steam ``` ```bash /bin/bash ``` ```bash sudo usermod --shell /bin/bash steam ``` ```bash sudo passwd steam ``` ```bash su steam ``` ```bash chsh -s /bin/bash ``` -------------------------------- ### Define Class Language Table Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Initializes the language table for class name and description localization. ```lua classData.lang = {} ``` -------------------------------- ### gmpublish help output Source: https://docs.ttt2.neoxult.de/developers/basics/creating-an-addon Usage information for the gmpublish command-line tool. ```text gmpublish.exe ``` -------------------------------- ### Register a new VSkin Source: https://docs.ttt2.neoxult.de/developers/content-creation/vskin Defines a new skin by registering a table of colors and parameters. All specified values must be present to prevent rendering failures. ```lua vskin.RegisterVSkin("dark_ttt2", { colors = { background = Color(40, 45, 52, 255), accent = Color(34, 93, 200, 255), accent_dark = Color(23, 67, 139, 255), scroll = Color(20, 30, 40, 255), shadow = Color(0, 0, 0, 100), screen = Color(10, 15, 20, 200), title_text = Color(255, 255, 255, 255) }, params = { shadow_size = 4, header_height = 45, collapsable_height = 30, border_size = 3, corner_radius = 6 } }) ``` -------------------------------- ### Define localization string Source: https://docs.ttt2.neoxult.de/developers/content-creation/using-karma Define a localization key to display a human-readable reason in the round end screen tooltip. ```lua karma_teamkill_tooltip = "Teamkills" ``` -------------------------------- ### Role Purchase Configuration Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-weapon Specify which roles are permitted to purchase the weapon in the shop menu. ```lua -- Which roles can purchase this swep (table) SWEP.CanBuy = {ROLE_TRAITOR} ``` -------------------------------- ### Define a VMT template for simple icons Source: https://docs.ttt2.neoxult.de/developers/content-creation/icon-and-design-guideline Use this template for simple, plain white icons. It includes settings for transparency and vertex coloring. ```text "UnlitGeneric" { "$basetexture" "" "$nocull" 1 "$nodecal" 1 "$nolod" 1 "$translucent" 1 "$vertexalpha" 1 "$vertexcolor" 1 } ``` -------------------------------- ### Full Role Hook Implementation Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Complete server-side hook implementation for the Tester role health mechanic. ```lua if SERVER then hook.Add("PlayerDeath", "ttt2_heal_up_tester", function( victim, inflictor, attacker) if victim:GetSubRole() == ROLE_TESTER then return end if SpecDM and (victim.IsGhost() and victim:IsGhost()) then return end if victim:GetTeam() ~= TEAM_TRAITOR then return end local plys = player.GetAll() for i = 1, #plys do local ply = plys[i] if ply:GetSubRole() == ROLE_TESTER and ply:Alive() and ply:IsActive() then -- is the player's health beneath 100, he gains an amount of hp if ply:Health() < ply:GetMaxHealth() then ply:SetHealth(125) else -- is the player's health above 100, he gains another amount of hp ply:SetHealth(200) end end end end) end ``` -------------------------------- ### Fix steamclient.so Dependency Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Create a symlink to the steamclient library in the expected directory to resolve initialization errors. ```bash mkdir -p ~/.steam/sdk32 ln -s ~/steam/linux32/steamclient.so ~/.steam/sdk32/steamclient.so ``` -------------------------------- ### Define Activation Check Callback Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Callback function to validate if the ability can be activated. ```lua classData.CheckActivation = function(ply) -- [default: nil] ``` -------------------------------- ### Defining Language Strings Source: https://docs.ttt2.neoxult.de/developers/content-creation/language-support Retrieves the language table reference and populates it with role names and popup information. ```lua local L = LANG.GetLanguageTableReference("en") -- GENERAL ROLE LANGUAGE STRINGS L[PHARAOH.name] = "Pharaoh" L["info_popup_" .. PHARAOH.name] = [[You are the Pharaoh! Use your Ankh to your benefit. Place it in a strategic position and make sure it is protected!]] -- ... ``` -------------------------------- ### Miscellaneous SWEP Attributes Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-weapon Configure general weapon behavior, models, and ironsight settings. Unspecified values will inherit from weapon_tttbase. ```lua SWEP.HoldType = "ar2" -- What the swep looks like to the user (Custom models can be used too) SWEP.ViewModel = "models/weapons/c_irifle.mdl" -- What the swep looks like to everyone else SWEP.WorldModel = "models/weapons/w_irifle.mdl" -- Whether the swep will force the user to see the viewmodel's hands SWEP.UseHands = true -- Whether the swep will spawn upon map gen (override as false if EQUIP1/2) SWEP.AutoSpawnable = false -- Which entity you pick up to fill your clips SWEP.AmmoEnt = "item_ammo_smg1_ttt" -- Which roles gain this weapon upon round start (table data structure) SWEP.InLoadoutFor = nil -- If true only one can be bought per round SWEP.LimitedStock = true -- Is the player able to drop the swep SWEP.AllowDrop = true -- If true, the killed player will not scream upon death SWEP.IsSilent = false -- If true, the swep has no ironsights capability (no Secondary fire if ironsights?) SWEP.NoSights = false -- Multiply the headshot damage by this much SWEP.HeadshotMultiplier = 50 -- The lower the slower SWEP.DeploySpeed = 0.2 -- Moves the Viewmodel by this vector when using ironsights SWEP.IronSightsPos = Vector(-2, -5, 0) -- Rotates the Viewmodel by this angle when using ironsights SWEP.IronSightsAng = Vector(-2, 0, 0) ``` -------------------------------- ### Register a Status Source: https://docs.ttt2.neoxult.de/developers/content-creation/sidebar-population Register a new status on the client using STATUS:RegisterStatus with an icon, type, and optional DrawInfo callback. ```lua hook.Add("Initialize", "my_addon_ininit", function() STATUS:RegisterStatus("unique_identifier", { -- sets the icon that will be rendered hud = Material("vgui/ttt/PATH.png"), -- the type that defines the color, it can be 'good', 'bad' or 'default' type = "bad", -- can be used to draw custom text on top of the status icon DrawInfo = function() return "Info" end, -- should not be used, is set automatically by type (intenal) hud_color = Color() }) end) ``` -------------------------------- ### Define a VMT template for classic icons Source: https://docs.ttt2.neoxult.de/developers/content-creation/icon-and-design-guideline Use this template for classic weapon and perk icons. It ensures proper rendering with transparency and vertex color support. ```text "UnlitGeneric" { "$basetexture" "" "$translucent" 1 "$vertexalpha" 1 "$vertexcolor" 1 } ``` -------------------------------- ### Define Activation Callback Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Callback function triggered when the ability is activated. ```lua classData.OnAbilityActivate = function(ply) -- [default: nil] ``` -------------------------------- ### Receiving Network Packets and Displaying EPOP Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Listens for a network packet on the client and triggers an EPOP message using localized text. ```lua if CLIENT then net.Receive("ttt2_test_role_popup", function() EPOP:AddMessage({text = LANG.GetTranslation("ttt2_role_tester_epop"), color = TESTER.ltcolor}, "", 10) end) end ``` -------------------------------- ### Retrieve Data from ORM Source: https://docs.ttt2.neoxult.de/developers/content-creation/sql-orm Methods for fetching all entries or specific rows from the database. ```lua local data = ormModel:All() ``` ```lua local data = ormModel:Find(primaryValue) ``` ```lua local data = ormModel:Where({ {column = "state", value = true, concat = "AND"}, {column = "amount", op = ">", value = 8}}) ) ``` -------------------------------- ### Defining Event Localization Strings Source: https://docs.ttt2.neoxult.de/developers/content-creation/using-event-system Required localization keys for event titles and descriptions. ```text title_event_ = "My cool event" ``` ```text desc_event_ = "{player} has done something." ``` ```text tooltip__score = "My event: {score}" _score = "My event:" ``` -------------------------------- ### Status Management Methods Source: https://docs.ttt2.neoxult.de/developers/content-creation/sidebar-population Methods for adding and removing status icons for players. ```APIDOC ## STATUS:AddStatus([ply,] id) ## STATUS:AddTimedStatus([ply,] identifier, duration, showDuration) ## STATUS:RemoveStatus([ply,] id) ### Description Functions to manage status icons on players. When called on the server, the first argument must be the player or a table of players. ### Parameters - **ply** (Player/table) - Optional - The player or table of players to affect. - **id/identifier** (string) - Required - The unique identifier of the status. - **duration** (number) - Required (for AddTimedStatus) - Time in seconds before removal. - **showDuration** (boolean) - Required (for AddTimedStatus) - Whether to display the remaining time on the icon. ``` -------------------------------- ### Define Role Language Strings Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Configures the English translation table for a role, including name, pop-up information, and body search text. ```lua L = LANG.GetLanguageTableReference("en") -- GENERAL ROLE LANGUAGE STRINGS L[TESTER.name] = "Tester" L["info_popup_" .. TESTER.name] = [[You are the Tester! If If one of your Traitor colleagues dies, your HP increases by a certain value.]] L["body_found_" .. TESTER.abbr] = "They were a Tester." L["search_role_" .. TESTER.abbr] = "This person was a Tester!" L["target_" .. TESTER.name] = "Tester" L["ttt2_desc_" .. TESTER.name] = [[The Tester needs to win with the traitors!]] ``` -------------------------------- ### Configure Ability Timing Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Sets the duration for which the ability remains active. ```lua classData.time = -- [default: 60] ``` -------------------------------- ### Iterate Through Players Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Standard for-loop structure to iterate through the player list. ```lua for i=1, #plys do ``` -------------------------------- ### TTT2 Role Directory Structure Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role The standard file hierarchy for a TTT2 role project, including Lua scripts, language files, and material assets. ```text / ├── lua/ │ └── terrortown/ │ ├── autorun/ │ │ └── shared/ │ │ └── sh__convars.lua │ ├── entities/ │ │ └── roles/ │ │ └── / │ │ └── shared.lua │ └── lang/ | ├── en/ | | └── .lua | ├── de/ | | └── .lua | └── ../ | └── .lua └── materials/ └── vgui/ └── ttt/ └── dynamic/ └── roles/ ├── icon_.vmt └── icon_.vtf ``` -------------------------------- ### Defining Language Strings Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Configures language translations for role information and EPOP messages. ```lua L = LANG.GetLanguageTableReference("en") -- GENERAL ROLE LANGUAGE STRINGS L[TESTER.name] = "Tester" L["info_popup_" .. TESTER.name] = [[You are the Tester! If If one of your Traitor colleagues dies, your HP increases by a certain value.]] L["body_found_" .. TESTER.abbr] = "They were a Tester." L["search_role_" .. TESTER.abbr] = "This person was a Tester!" L["target_" .. TESTER.name] = "Tester" L["ttt2_desc_" .. TESTER.name] = [[The Tester needs to win with the traitors!]] -- OTHER ROLE LANGUAGE STRINGS L["ttt2_role_tester_epop"] = "While some lose strength, others gain new strength!" ``` -------------------------------- ### Registering a PlayerDeath Hook Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Initializes a hook to listen for player death events, requiring an identifier and a callback function with victim, inflictor, and attacker parameters. ```lua hook.Add("PlayerDeath", "ttt2_heal_up_tester", function(victim, inflictor, attacker) -- Code to be processed must be filled in here end) ``` -------------------------------- ### gmad help output Source: https://docs.ttt2.neoxult.de/developers/basics/creating-an-addon Usage information for the gmad command-line tool. ```text gmad.exe ``` -------------------------------- ### Draw Perk Info Text Source: https://docs.ttt2.neoxult.de/developers/content-creation/sidebar-population Implement the DrawInfo function to render short text on the perk icon. ```lua function ITEM:DrawInfo() return math.random(0, 100) end ``` -------------------------------- ### Manage Statuses Source: https://docs.ttt2.neoxult.de/developers/content-creation/sidebar-population Functions for adding, removing, and timing statuses for players. ```lua STATUS:AddStatus([ply,] id) STATUS:AddTimedStatus([ply,] identifier, duration, showDuration) STATUS:RemoveStatus([ply,] id) ``` -------------------------------- ### Define HUD folder structure Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-hud-theme The required directory layout for a TTT2 HUD addon project. ```text / ├── lua/ │ └── terrortown/ │ ├── autorun/ │ │ ├── your other lua files ... │ │ └── ttt2__force_download.lua │ └── gamemode/ │ └── shared/ │ ├── hud_elements/ │ │ ├── base_elements/ │ │ │ └── _element.lua │ │ ├── tttinfopanel/ │ │ │ └── _playerinfo.lua │ │ └── bunch of others... │ └── huds/ │ └── / │ └── cl_init.lua ├── materials/ │ └── vgui/ │ └── ttt/ │ └── huds/ │ └── / │ └── preview.png └── resource/ └── fonts/ ``` -------------------------------- ### Login Anonymously Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Authenticates the SteamCMD session using an anonymous account for public server files. ```text login anonymous ``` -------------------------------- ### Grant superadmin via ULX Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Command to assign superadmin privileges to a user via the server console. ```text ulx adduser "your username" superadmin ``` -------------------------------- ### Registering a Basic TTT2 Event Source: https://docs.ttt2.neoxult.de/developers/content-creation/using-event-system Defines the structure for a custom event, including client-side UI elements and server-side trigger and scoring logic. ```lua if CLIENT then EVENT.icon = Material("path/to/material") EVENT.title = "title_event_" function EVENT:GetText() -- each returned subtable is rendered as one paragraph return { { string = "desc_event_", params = { player = self.event.finder.nick, }, translateParams = false }, { -- ... } } end end if SERVER then -- this function is triggered when the event is triggered function EVENT:Trigger(finder) self:AddAffectedPlayers( {finder:SteamID64()}, {finder:Nick()} ) return self:Add({ -- string indexed data can be added here finder = { nick = finder:Nick(), sid64 = finder:SteamID64() } }) end -- this function is triggered to calculate the score function EVENT:CalculateScore() self:SetPlayerScore(self.event.finder.sid64, { score = 3 }) end end -- simple text to store in the log file function EVENT:Serialize() return self.event.finder.nick .. " has done something." end ``` -------------------------------- ### Configure Cooldown Time Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Sets the cooldown duration after the active ability is used. ```lua classData.cooldown = -- [default: 60] ``` -------------------------------- ### Registering a Network String Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Registers a unique identifier for network data packets on the server. ```lua if SERVER then AddCSLuaFile() util.AddNetworkString("ttt2_test_role_popup") end ``` -------------------------------- ### Health Adjustment Logic Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Conditional logic to set player health based on current health status. ```lua -- is the player's health beneath 100, he gains an amount of hp if ply:Health() < ply:GetMaxHealth() then ply:SetHealth(125) else -- is the player's health above 100, he gains another amount of hp ply:SetHealth(200) end ``` -------------------------------- ### Configure Max Activation Amount Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Sets the maximum number of times an ability can be activated per round. ```lua classData.amount = -- [default: nil] ``` -------------------------------- ### Define OnSet Callback Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Callback function triggered when the class is assigned to a player. ```lua classData.OnSet = function(ply) -- [default: nil] ``` -------------------------------- ### Check Player Role and Status Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Conditional check to verify if the player is a living Tester. ```lua if ply:GetSubRole() == ROLE_TESTER and ply:Alive() then ``` -------------------------------- ### Define Charge Callback Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Callback function executed every frame during the charging process. ```lua classData.OnCharge = function(ply) -- [default: nil] ``` -------------------------------- ### If-Else Nest Template Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Generic structure for conditional logic with an alternative fallback. ```lua if [FIRST CONDITION HERE] then --[CODE TO PROCESS HERE] else --[CODE TO PROCESS HERE] end ``` -------------------------------- ### Exit SteamCMD Source: https://docs.ttt2.neoxult.de/server-owners/manual-install Command to terminate the SteamCMD session. ```text quit ``` -------------------------------- ### Implementing Role-Specific Conditions Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Uses an if-statement to terminate the function early if the victim is not a tester or is not part of the traitor team. ```lua if victim:GetSubRole() == ROLE_TESTER and victim:GetTeam() ~= TEAM_TRAITOR then return end ``` -------------------------------- ### Conditional Net Library Execution Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Uses an if-statement to check a boolean ConVar before broadcasting a network packet. ```lua -- if convar is set, players receive the pop-up if cv_send_popup then net.Start("ttt2_test_role_popup") net.Broadcast() end ``` -------------------------------- ### Synchronizing Karma changes Source: https://docs.ttt2.neoxult.de/developers/content-creation/using-event-system Overrides the default behavior to ensure karma changes are synchronized across the network. ```lua function EVENT:ShouldKarmaChangeSynchronize() return true end ``` -------------------------------- ### Access Current Player in Loop Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Assigns the current iteration player to a local variable. ```lua local ply = plys[i] ``` -------------------------------- ### Create and Modify Database Rows Source: https://docs.ttt2.neoxult.de/developers/content-creation/sql-orm Operations for inserting new data or updating existing records using ORM objects. ```lua local data = ormModel:New({name = "primary_key", state = true, amount = 7}) data:Save() ``` ```lua local data = ormModel:Find(primaryValue) if not data then return end data.state = false data.amount = 12 data:Save() ``` -------------------------------- ### Configure Class Color Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Sets the color used for the class in the HUD and targetID. ```lua classData.color = -- [default: Color(255, 155, 0, 255)] ``` -------------------------------- ### Define a Perk Icon Source: https://docs.ttt2.neoxult.de/developers/content-creation/sidebar-population Assign a material to the ITEM.hud property to display a perk icon on the HUD. ```lua ITEM.hud = Material("vgui/ttt/perks/hud_nopropdmg.png") ``` -------------------------------- ### Configure Weapon Reset Behavior Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Determines if the player retains their weapons while the ability is active. ```lua classData.avoidWeaponReset = -- [default: false] ``` -------------------------------- ### Create ConVars Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-role Define custom ConVars with identifiers, default values, and flags in a shared Lua file. ```lua CreateConVar("ttt_tester_health_above_100", 200, {FCVAR_ARCHIVE, FCVAR_NOTIFY}) CreateConVar("ttt_tester_health_beneath_100", 125, {FCVAR_ARCHIVE, FCVAR_NOTIFY}) CreateConVar("ttt_tester_send_popup", 1, {FCVAR_ARCHIVE, FCVAR_NOTIFY}) ``` -------------------------------- ### Weapon Kind Assignment Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-weapon Define the weapon category using SWEP.Kind. The slot is automatically generated based on this value. ```lua -- Kind specifies what weapon_ttt category it falls into SWEP.Kind = WEAPON_EQUIP1 ``` -------------------------------- ### Configure Respawn Behavior Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Prevents the class from being re-applied on respawn regardless of global ConVar settings. ```lua classData.surpressKeepOnRespawn = -- [default: false] ``` -------------------------------- ### Define Passive Items Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Sets the table of items provided to the player upon class activation. ```lua classData.items = {} ``` -------------------------------- ### Configure Unstoppable Ability Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-class Determines if the player can disable the ability after activation. ```lua classData.unstoppable = -- [default: false] ``` -------------------------------- ### Triggering an event Source: https://docs.ttt2.neoxult.de/developers/content-creation/using-event-system Executes a defined event by calling the trigger function with the event name and target player. ```lua events.Trigger(EVENT_, somePlayer) ``` -------------------------------- ### Inherit from dynamic_hud_element Source: https://docs.ttt2.neoxult.de/developers/content-creation/creating-a-hud-theme Setting the base class for a custom HUD element to enable TTT2 features. ```lua local base = "dynamic_hud_element" ```