### Creating and Running a Custom Hook Source: https://github.com/thegrb93/starfallex/wiki/[Tutorial]-Hooks This example defines a custom hook named 'myveryownhook' and then runs it, passing a string argument. ```lua hook.add("myveryownhook", "some_unique_name", function(text) print(text) end) hook.run("myveryownhook", "hello") ``` -------------------------------- ### Lua Table Library Function Example Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Shows how to create a 'library' by storing functions within a table. This example defines a 'table.count' function to return the number of elements in a table using 'pairs'. ```lua function table.count(tbl) local count = 0 for k, v in pairs(tbl) do count = count + 1 end return count end print(table.count(Table)) ``` -------------------------------- ### Client-Server Communication with Net Library Source: https://context7.com/thegrb93/starfallex/llms.txt The `net` library enables typed message passing between client and server. This example synchronizes a random value and a hologram entity. ```lua --@name Net Sync Example --@shared if SERVER then local value = math.random(0, 100) -- Respond to client requests net.receive("requestValue", function(len, ply) net.start("sendValue") net.writeUInt(value, 7) -- 7 bits → 0–127 net.send(ply) end) -- Broadcast a hologram entity to a newly initialized client hook.add("ClientInitialized", "sendHolo", function(ply) local holo = holograms.create(chip():getPos() + Vector(0,0,40), Angle(), "models/hunter/blocks/cube025x025x025.mdl") net.start("holoSync") net.writeEntity(holo) net.send(ply) end) else -- Ask the server for the value on startup net.start("requestValue") net.send() -- Receive and display it local received net.receive("sendValue", function() received = net.readUInt(7) print("Server value:", received) end) -- Receive a server-side hologram and manipulate it client-side net.receive("holoSync", function() net.readEntity(function(ent) if ent == nil then error("Entity not found") end local holo = ent:toHologram() hook.add("tick", "pulse", function() local s = 0.75 + math.sin(timer.curtime() * 5) * 0.25 local m = Matrix() m:setScale(Vector(s)) holo:setRenderMatrix(m) end) end) end) end ``` -------------------------------- ### Create and Draw to Off-Screen Canvas Source: https://context7.com/thegrb93/starfallex/llms.txt Use `render.createRenderTarget` to create an off-screen texture and `render.selectRenderTarget` to draw to it. This example demonstrates drawing a rainbow gradient over multiple frames. ```lua --@name RenderTarget Example --@client render.createRenderTarget("canvas") -- Draw a rainbow gradient to the render target using a coroutine spread over multiple frames local paint = coroutine.wrap(function() for y = 0, 1023 do for x = 0, 1023 do render.setColor(Color(x * y * 360 / 512 % 360, 1, 1):hsvToRGB()) render.drawRectFast(x, y, 1, 1) end coroutine.yield() end return true end) hook.add("renderoffscreen", "paintCanvas", function() render.selectRenderTarget("canvas") while quotaAverage() < quotaMax() * 0.5 do if paint() then hook.remove("renderoffscreen", "paintCanvas") return end end end) -- Display the render target on the screen hook.add("render", "showCanvas", function() render.setRenderTargetTexture("canvas") render.drawTexturedRect(0, 0, 512, 512) end) ``` -------------------------------- ### CPU Quota Management Example Source: https://context7.com/thegrb93/starfallex/llms.txt Checks CPU usage against defined limits to prevent script termination. The `quotaCheck` function helps determine if further processing is safe within the quota. ```lua --@name CPU Quota Example --@server local function quotaCheck(threshold) -- Returns true when below `threshold` fraction of the quota return math.max(quotaAverage(), quotaUsed()) < quotaMax() * threshold end -- Process as many iterations as possible each tick without exceeding 95% quota hook.add("think", "heavyWork", function() local i = 0 while quotaCheck(0.95) do i = i + 1 end print("Iterations this tick:", i) end) ``` -------------------------------- ### Lua Math Library Function Example Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Demonstrates creating a custom function within the 'math' library to calculate the average of elements in an array-like table. It uses the '#' operator to get the table length. ```lua function math.average(tbl) local avg = 0 for _, v in ipairs(tbl) do avg = avg + 1 end return avg / #tbl end print(math.average({1, 5, 8, 3, 2})) ``` -------------------------------- ### Lua Scopes: do, if, function, loops Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Provides examples of different scope types in Lua: basic 'do' blocks, conditional 'if' blocks, anonymous functions, 'while' loops, 'for' loops, 'for in' loops, and 'repeat until' loops. ```lua do x = 1 end -- This is a basic scope. It does nothing but act as a scope if true then x = 2 end -- This is an 'if' scope. program execution will only enter it if the condition is satisfied (function() x = 3 end)() -- Functions are similar to the first scope, but can be stored as variables and executed at will. while x == 3 do x = 4 end -- This is a 'while loop'. It will execute code inside it repeatedly until the condition is dissatisfied for i=1, 1 do x = 5 end -- This is a 'for loop'. It will execute code inside until the specified number of iterations is done. local myFunction = function() if x == 6 then return nil else return true end end for k in myFunction do x = 6 end -- This is a 'for in loop'. It will keep calling 'func' and executing code inside until func returns 'nil' repeat x = 7 until x==7 -- This is a 'repeat until loop. It will execute code until the condition is satisfied ``` -------------------------------- ### Adding a Hook with a Non-Anonymous Function Source: https://github.com/thegrb93/starfallex/wiki/[Tutorial]-Hooks This example shows how to add a hook using a pre-defined, non-anonymous function. This can improve code organization. ```lua --@name DTut: Hooks --@server function announceNoclip(user, state) if state then print("Oh wee! " .. user:getName() .. " is using noclip!") else print(user:getName() .. " isn't using noclip anymore") end end hook.add("PlayerNoClip", "some_unique_name", announceNoclip) ``` -------------------------------- ### Lua Table Initialization and Access Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Introduces Lua tables, which can store various data types including functions. Elements are stored sequentially and accessed via integer indices starting from 1. ```lua Table = {"hello", function() print("hi") end, 193782, 1212} print(Table[1]) Table[2]() Table[3] = Table[3] + 1 ``` -------------------------------- ### Lua Function Definition with Conditional Logic Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Illustrates a common syntax for defining functions in Lua, equivalent to variable assignment. This example includes a conditional statement within the function. ```lua function Function() if x == 2 then print("x is 2") else print("x is not 2") end end ``` -------------------------------- ### Object-Oriented Programming with Middleclass Source: https://context7.com/thegrb93/starfallex/llms.txt Demonstrates subclassing and object instantiation using the provided Middleclass-compatible `class()` global. The `initialize` method serves as the constructor. ```lua --@name OOP Example --@shared local Animal = class("Animal") function Animal:initialize(name, sound) self.name = name self.sound = sound end function Animal:speak() print(self.name .. " says " .. self.sound) end -- Subclass inherits Animal local Dog = class("Dog", Animal) function Dog:initialize(name) Animal.initialize(self, name, "Woof") self.tricks = {} end function Dog:learnTrick(trick) self.tricks[#self.tricks + 1] = trick print(self.name .. " learned: " .. trick) end local rex = Dog:new("Rex") rex:speak() -- Rex says Woof rex:learnTrick("sit") -- Rex learned: sit print(#rex.tricks) -- 1 ``` -------------------------------- ### Creating Hologram Entities with holograms.create Source: https://context7.com/thegrb93/starfallex/llms.txt Spawn client- or server-side holograms at a specified world position using `holograms.create`. Holograms support entity methods for manipulation like setting position, rotation, color, and animations. ```lua --@name Hologram Example --@server local c = chip() -- Create a G-Man hologram above the chip local holo = holograms.create(c:getPos() + Vector(0,0,60), Angle(), "models/gman_high.mdl") holo:setColor(Color(128, 0, 255)) -- purple tint holo:setAngVel(Angle(0, 90, 0)) -- continuous yaw rotation -- Move it forward each tick hook.add("Tick", "moveHolo", function() holo:setPos(holo:getPos() + Vector(1, 0, 0)) end) -- Stop and animate after 3 seconds timer.simple(3, function() hook.remove("Tick", "moveHolo") holo:setAngVel(Angle()) holo:setAnimation("idle01") end) ``` -------------------------------- ### Delayed and Recurring Timers with timer.simple and timer.create Source: https://context7.com/thegrb93/starfallex/llms.txt Execute functions after a delay using `timer.simple` or create named repeating timers with `timer.create`. Set `reps = 0` for indefinite repetition. Useful for scheduling actions like animations or sound effects. ```lua --@name Timer Example --@server local holo = holograms.create(chip():getPos() + Vector(0,0,50), Angle(), "models/gman_high.mdl") holo:setColor(Color(128, 0, 255)) holo:setAngVel(Angle(0, 100, 0)) -- Stop rotating after 2 seconds timer.simple(2, function() holo:setAngVel(Angle()) -- Then play a swinging animation 6 times, every 1.2 seconds timer.create("swingTimer", 1.2, 6, function() holo:setAnimation("swing") holo:emitSound("npc/zombie/claw_miss1.wav") end) end) ``` -------------------------------- ### Load and Play Audio from URL with BASS Source: https://context7.com/thegrb93/starfallex/llms.txt Streams audio from a URL using the BASS library, supporting 3D positional audio, looping, and metadata. Requires permission to be granted for URL access. ```lua --@name Music Player --@author Sparky --@model models/props_lab/citizenradio.mdl --@shared if SERVER then hook.add("PlayerSay", "songCommand", function(ply, txt) if ply == owner() and txt:sub(1, 6) == "!song " then net.start("playSong") net.writeString(txt:sub(7)) net.send() return "" -- suppress chat message end end) else local song local function loadSong(url) if song then song:stop() end bass.loadURL(url, "3d noblock", function(snd, err, errtxt) if isValid(snd) then song = snd snd:setFade(500, 2000) -- fade: min 500u, max 2000u snd:setVolume(2) pcall(snd.setLooping, snd, true) -- Tags are not available immediately after stream init timer.simple(0.3, function() local tags = snd:getTagsID3() or snd:getTagsOGG() or snd:getTagsMP4() if tags and next(tags) then for k, v in pairs(tags) do print(k, v) end else print("Stream:", snd:getTagsMeta()) end end) hook.add("think", "updateSndPos", function() if isValid(snd) and isValid(chip()) then snd:setPos(chip():getPos()) end end) else print("Error:", errtxt) end end) end net.receive("playSong", function() local url = net.readString() if not hasPermission("bass.loadURL", url) then print("Press E on the chip to grant audio permission") return end loadSong(url) end) setupPermissionRequest({"bass.loadURL"}, "URL sounds", true) end ``` -------------------------------- ### Establish Persistent WebSocket Connections Source: https://context7.com/thegrb93/starfallex/llms.txt Opens a persistent WebSocket connection to a specified host and port. Handles connection, disconnection, and message events via callbacks. Requires client-side execution. ```lua --@name WebSocket Echo Example --@client local ws = WebSocket("ws.ifelse.io", 443, true) function ws:onConnected() print("Connected, state:", self:getState()) self:write("Hello from StarfallEx!") end function ws:onMessage(msg) print("Received:", msg) if msg == "Hello from StarfallEx!" then self:write("Goodbye") elseif msg == "Goodbye" then self:close() end end function ws:onDisconnected(errored) print("Disconnected, errored:", errored) end ws:connect() ``` -------------------------------- ### Manage Persistent Files with file Library Source: https://context7.com/thegrb93/starfallex/llms.txt Enables reading and writing files within the `sf_filedata/` directory. All file operations are sandboxed to this path. Supports writing, reading, checking existence, deleting, and listing files. Requires client-side execution. ```lua --@name File I/O Example --@client -- Write a config file file.write("myconfig.txt", "speed=42\ncolor=blue") -- Read it back local contents = file.read("myconfig.txt") print(contents) -- speed=42\ncolor=blue -- Check existence and delete if file.exists("myconfig.txt") then print("File size:", #file.read("myconfig.txt")) file.delete("myconfig.txt") end -- List files in the sf_filedata directory local files, dirs = file.find("*", "*") for _, f in ipairs(files) do print("file:", f) end ``` -------------------------------- ### Basic Script Execution Source: https://github.com/thegrb93/starfallex/wiki/[Tutorial]-Hooks Code outside of hooks executes only once when the script is loaded. ```lua --@name Hello World --@server print("Hello world!") ``` -------------------------------- ### Extract StarfallEx Source Code Source: https://github.com/thegrb93/starfallex/blob/master/Readme.md Instructions for extracting the downloaded source code zip file into the Garry's Mod addons directory. ```text C:\path\to\Steam\steamapps\common\GarrysMod\garrysmod\addons ``` -------------------------------- ### Lua Function as an Argument Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Shows how functions can be passed as arguments to other functions in Lua. The receiving function can then execute the passed function. ```lua function Function(func) if func() then print("func worked!") end end Function(function() return true end) ``` -------------------------------- ### Boolean and Logical Operators in Lua Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Explains logical operators 'and' and 'or', along with the 'not' operator for boolean values. Shows how they combine conditions. ```lua local Boolean = true local String = "hi" print(Boolean and String == "hi") -- Prints whether our boolean is true and string is 'hi' print(Boolean or not Boolean) ``` -------------------------------- ### Lua Table with Functions and Data Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Demonstrates a Lua table that holds both data (pitch, yaw, roll) and functions (Add). It shows two ways to define and call a method, highlighting the colon syntax for object-oriented programming. ```lua MyAngle = {pitch = 50, yaw = 10, roll = 0} function MyAngle.Add(ang1, ang2) return {pitch = ang1.pitch + ang2.pitch, yaw = ang1.yaw + ang2.yaw, roll = ang1.roll + ang2.roll} end Angle2 = MyAngle.Add(MyAngle, MyAngle) ``` ```lua function MyAngle:Add(ang2) return {pitch = self.pitch + ang2.pitch, yaw = self.yaw + ang2.yaw, roll = self.roll + ang2.roll} end Angle2 = MyAngle:Add(Angle2) ``` -------------------------------- ### 2D/3D Drawing with the render Library Source: https://context7.com/thegrb93/starfallex/llms.txt Utilize the `render` library for drawing primitives on StarfallEx screens and HUDs. This library is available in client-realm hooks like `render`, `drawhud`, and `renderoffscreen`. It supports setting colors, fonts, and drawing text or rectangles. ```lua --@name Render Example --@client local font = render.createFont("Default", 30) -- "render" hook fires every frame the screen/HUD needs to be drawn hook.add("render", "drawHelloWorld", function() -- Draw red text render.setColor(Color(255, 0, 0, 255)) render.setFont(font) render.drawText(20, 20, "Hello World!") -- Draw a semi-transparent blue rectangle render.setColor(Color(0, 100, 255, 180)) render.drawRect(10, 60, 200, 40) end) ``` -------------------------------- ### Wiremod Integration with Wire Library Source: https://context7.com/thegrb93/starfallex/llms.txt The `wire` library allows chips to interact with Wiremod's Expression2. Use `wire.adjustPorts` to define inputs/outputs and the `Input` hook to handle incoming wired values. ```lua --@name Wire Integration --@server -- Declare a single entity-type input called "Ent" wire.adjustPorts { ["Ent"] = "entity" } hook.add("Input", "handleInput", function(name, value) if name == "Ent" and value:isValid() then print("Received entity:", value, "class:", value:getClass()) value:setColor(Color(255, 100, 0)) end end) -- Legacy-style multi-input / output declaration wire.adjustInputs({"Button", "Speed"}, {"Number", "Number"}) wire.adjustOutputs({"Active"}, {"Number"}) hook.add("input", "legacyInput", function(key, val) if key == "Button" and val == 1 then wire.ports.Active = 1 print("Button pressed! Speed =", wire.ports.Speed) end end) ``` -------------------------------- ### Lua Function Definition and Execution Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Shows how to define and execute a simple Lua function. Functions can be assigned to variables and called later. Local variables defined outside a function can be accessed within it, up to a limit of 256 locals. ```lua local Function = function() print("hey") end Function() ``` ```lua local x = 5 Function = function() print(x) end Function() x = 2 Function() ``` -------------------------------- ### Perform Raw TCP Communication with socket Library Source: https://context7.com/thegrb93/starfallex/llms.txt Provides low-level TCP communication capabilities via the LuaSocket library. Requires the `gmod_luasocket` binary module and client-side execution. Used for custom protocols or raw HTTP. ```lua --@name TCP HTTP GET Example --@client -- Requires the gmod_luasocket binary module local sock = socket.tcp() sock:settimeout(0) sock:connect("example.com", 80) local chunks = {} hook.add("think", "tcpProcess", function() local r, w, e = socket.select({sock}, {sock}, 0) if w and w[1] then sock:send("GET / HTTP/1.0\r\nHost: example.com\r\n\r\n") end if r and r[1] then local data, err, partial = sock:receive(2048) local chunk = data or partial if chunk then chunks[#chunks + 1] = chunk end if err == "closed" then file.write("response.txt", table.concat(chunks)) hook.remove("think", "tcpProcess") sock:close() end end end) ``` -------------------------------- ### Lua Function Returning a Function (Closures) Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Explains and demonstrates how Lua functions can return other functions. Each returned function maintains its own independent state for local variables, as shown with the 'x' variable. ```lua function Function() local x = 0 return function() x = x + 1 return x end end local func1 = Function() local func2 = Function() print(func1(), func1(), func2(), func1(), func2()) ``` -------------------------------- ### Clone StarfallEx Repository Source: https://github.com/thegrb93/starfallex/blob/master/Readme.md Use this command to clone the StarfallEx repository directly into your Garry's Mod addons folder. ```bash git clone https://github.com/thegrb93/StarfallEx "C:\path\to\Steam\steamapps\common\GarrysMod\garrysmod\addons\starfallex" ``` -------------------------------- ### Global vs. Local Variables in Lua Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Demonstrates the difference between global variables (accessible everywhere, stored in _G) and local variables (scoped, more efficient). Prefer locals for performance and memory management. ```lua x = 5 -- variable 'x' now contains the number 5 and is 'global' so it can be accessed from anywhere else in the Lua program and it will stay forever or until set to 'nil' print(x) -- This will show the value of x in your chat local x = 2 -- This defines a 'local' x that contains 2. After this definition, 'x' will refer to the local print(x) print(_G.x) -- You can still access the global by using _G.x -- _G is a 'table', you'll learn those in Part 6 _G.x = 10 x = 4 print(_G.x) print(x) -- We prefer to use 'local' instead of 'global' because they have faster accessing and their memory is managed more efficiently -- 'global' is really only used to store stuff you want every piece of code to have access to, like libraries. -- Even then, most scripts will access the library from 'global' once by doing "local mylibrary = mylibrary" local math = math print(math.sqrt(5)) -- math library usage is sped up by 'local' -- The disadvantage to 'local' is that you are only allowed 256 of them per function and they are destroyed when their 'scope' ends (see part 2). ``` -------------------------------- ### timer.simple / timer.create — Delayed and Recurring Timers Source: https://context7.com/thegrb93/starfallex/llms.txt Provides functions to execute code after a specified delay (`timer.simple`) or to create recurring timers (`timer.create`). Useful for scheduling tasks and animations. ```APIDOC ## timer.simple / timer.create ### Description Schedules a function to be executed after a delay or at regular intervals. ### Methods - `timer.simple(delay, callback)`: Executes `callback` once after `delay` seconds. - `timer.create(name, delay, reps, callback)`: Creates a named timer. `name` is a unique identifier, `delay` is in seconds, `reps` is the number of repetitions (0 for infinite), and `callback` is the function to execute. ### Example ```lua -- Stop rotating after 2 seconds timer.simple(2, function() holo:setAngVel(Angle()) -- Then play a swinging animation 6 times, every 1.2 seconds timer.create("swingTimer", 1.2, 6, function() holo:setAnimation("swing") holo:emitSound("npc/zombie/claw_miss1.wav") end) end) ``` ``` -------------------------------- ### Lua Function with Multiple Return Values Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Demonstrates how Lua functions can accept various data types as arguments and return multiple values. The arguments act as local variables within the function's scope. ```lua function Function(x, y) return x+1, x+2, #y end local a, b, c = Function(100, "hello") ``` -------------------------------- ### Lua Table: Array vs. Hashmap Indexing Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Explains the two ways Lua tables store data: as an 'array' with integer indices and as a 'hashmap' with arbitrary keys. String keys can often be accessed without quotes if they are valid identifiers. ```lua Table = {5, 6, 7, 8} -- This is an array; the indeces are 1, 2, 3, 4 Table = {a = 5, [1.567] = 6, [true] = 7, ["hello_world"] = 8} -- This is a hashmap; the indeces are "a", 1.567, true, and "hello_world" print(Table.a, Table["a"]) ``` -------------------------------- ### Numeric Operators in Lua Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Demonstrates arithmetic operators for numbers: addition ('+'), subtraction ('-'), multiplication ('*'), division ('/'), exponentiation ('^'), equality ('=='), inequality ('~='), greater than ('>'), and greater than or equal to ('>='). ```lua local Number = 108 print(Number + 3 - 1) -- Prints the result of adding 3 to Number and subtracting 1 print(Number * 2 / 3) -- Prints the result of multiplying Number by 2 and dividing by 3 print(Number ^ 4) -- Prints the result of exponentiating Number by 4 print(Number == 100) -- Prints whether the number is 100 print(Number ~= 100) -- Prints whether the number is not 100 print(Number > 100) -- Prints whether the number is greater than 100 print(Number >= 100) -- Prints whether the number is greater than or equal to 100 ``` -------------------------------- ### Starfall: Input Hook with Wire Port Access Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Sets up an input hook that triggers when a 'Button' input is pressed (value 1). It prints a message and the current value of the 'Ent' wire port. ```lua hook.add("input","",function(key,value) if key == "Button" and value == 1 then print("The button was pressed!") print("Ent is " .. tostring(wire.ports.Ent)) end end) ``` -------------------------------- ### render Library — 2D/3D Drawing Source: https://context7.com/thegrb93/starfallex/llms.txt Provides drawing primitives for rendering 2D text and shapes on StarfallEx screens and HUDs. This library is accessible within client-realm hooks like `render` and `drawhud`. ```APIDOC ## render Library ### Description Offers functions for drawing 2D graphics on screens and HUDs within the client realm. ### Available Functions (Examples) - `render.createFont(name, size)`: Creates a font object. - `render.setColor(color)`: Sets the drawing color (Color object). - `render.setFont(font)`: Sets the current font. - `render.drawText(x, y, text)`: Draws text at the specified coordinates. - `render.drawRect(x, y, width, height)`: Draws a rectangle. ### Example ```lua -- "render" hook fires every frame the screen/HUD needs to be drawn hook.add("render", "drawHelloWorld", function() -- Draw red text render.setColor(Color(255, 0, 0, 255)) render.setFont(font) render.drawText(20, 20, "Hello World!") -- Draw a semi-transparent blue rectangle render.setColor(Color(0, 100, 255, 180)) render.drawRect(10, 60, 200, 40) end) ``` ``` -------------------------------- ### Running a Hook Manually Source: https://github.com/thegrb93/starfallex/wiki/[Tutorial]-Hooks The `hook.run` function allows you to manually trigger a hook and pass arguments to any hooked functions. ```lua hook.run("name", ...) ``` -------------------------------- ### Generate Fibonacci Sequence in Lua Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course This snippet generates the first 10 numbers of the Fibonacci sequence and prints them as a space-separated string. It initializes a table with the first two numbers and iteratively calculates the rest. ```lua local fibbinaci = {1, 1} for i=1, 10 do fibbinaci[i+2] = fibbinaci[i] + fibbinaci[i+1] end print(table.concat(fibbinaci, " ")) ``` -------------------------------- ### file Library Source: https://context7.com/thegrb93/starfallex/llms.txt Enables reading and writing files within the `sf_filedata/` directory. All file operations are sandboxed to this specific path. ```APIDOC ## file Library — Persistent File I/O The `file` library lets scripts read and write files under the `sf_filedata/` directory. All I/O is sandboxed to that path. ### Methods - **file.write(path, data)**: Writes data to the specified file path. - **file.read(path)**: Reads the entire content of the specified file path and returns it as a string. - **file.exists(path)**: Returns true if the file at the specified path exists, false otherwise. - **file.delete(path)**: Deletes the file at the specified path. - **file.find(pattern)**: Finds files and directories matching the given pattern. Returns two tables: one for files and one for directories. ``` -------------------------------- ### Spawn Scripted Entities (SENTs) with prop.createSent Source: https://context7.com/thegrb93/starfallex/llms.txt Spawns a scripted entity like a vehicle seat or lamp. The returned entity can be controlled. Requires server-side execution. ```lua --@name Chair Controller --@server -- Spawn a frozen jeep seat 20 units above the chip local chair = prop.createSent(chip():getPos() + chip():getUp() * 20, Angle(), "Seat_Jeep", true) local holo = holograms.create(chair:getPos() + chair:getForward() * 50, Angle(), "models/props_phx/games/chess/white_rook.mdl", Vector(0.75)) local driver, velocity, acceleration = nil, 0, 0 local inputMap = { [IN_KEY.FORWARD] = 10, [IN_KEY.BACK] = -8 } local function setDriver(ply, vehicle, role) if vehicle == chair then driver = role and ply end end hook.add("PlayerEnteredVehicle", "setDriver", setDriver) hook.add("PlayerLeaveVehicle", "setDriver", setDriver) hook.add("KeyPress", "kp", function(ply, key) if ply == driver and inputMap[key] then acceleration = inputMap[key] end end) hook.add("KeyRelease", "kr", function(ply, key) if ply == driver and inputMap[key] then acceleration = 0 end end) hook.add("Tick", "move", function() velocity = (velocity + acceleration) * 0.9 holo:setVel(Vector(0, velocity, 0)) end) ``` -------------------------------- ### Script Header Annotations Source: https://context7.com/thegrb93/starfallex/llms.txt Use header annotations to control script metadata and execution context. Specify the script name, author, model, and execution realm (server, client, or shared). ```lua --@name My Script --@author YourName --@model models/props_lab/citizenradio.mdl --@server -- run only on server; use @client or @shared as alternatives ``` -------------------------------- ### Registering Event Callbacks with hook.add Source: https://context7.com/thegrb93/starfallex/llms.txt Register functions to named events using `hook.add`. This is the primary method for responding to recurring or asynchronous events. Hooks can be set to run once and then remove themselves. ```lua --@name Hook Example --@server -- Fires every server tick (~33 Hz) hook.add("think", "myThink", function() -- logic here end) -- Fires when a player uses noclip hook.add("PlayerNoClip", "noclipAnnounce", function(ply, state) if state then print(ply:getName() .. " enabled noclip!") else print(ply:getName() .. " disabled noclip!") end end) -- Execute hook only once, then remove it hook.add("renderoffscreen", "runOnce", function() print("This runs exactly once!") hook.remove("renderoffscreen", "runOnce") end) -- Manually fire a custom hook with arguments hook.add("myCustomEvent", "listener", function(msg) print("Event fired with: " .. msg) end) hook.run("myCustomEvent", "hello") ``` -------------------------------- ### socket Library Source: https://context7.com/thegrb93/starfallex/llms.txt Provides raw TCP communication capabilities through the LuaSocket library. This is useful for low-level HTTP requests or custom network protocols. ```APIDOC ## socket Library — Raw TCP via LuaSocket The optional `socket` binary module (requires `gmod_luasocket`) exposes LuaSocket's TCP API for low-level HTTP or custom-protocol communication. ### Methods - **socket.tcp()**: Creates a new TCP client socket. ### Socket Methods - **connect(host, port)**: Connects the socket to the specified host and port. - **send(data)**: Sends data over the socket. - **receive(size)**: Receives data from the socket. `size` is the maximum number of bytes to receive. - **close()**: Closes the socket connection. - **settimeout(timeout)**: Sets the timeout for socket operations. ### Events - **socket.select(read_sockets, write_sockets, timeout)**: Waits for socket events. Returns tables of sockets ready for reading, writing, or an error. ``` -------------------------------- ### WebSocket Source: https://context7.com/thegrb93/starfallex/llms.txt Opens a persistent WebSocket connection to a specified host and port. It supports secure connections and provides callbacks for connection events and message handling. ```APIDOC ## WebSocket — Persistent WebSocket Connections `WebSocket(host, port, secure)` opens a persistent WebSocket connection. Callbacks `onConnected`, `onDisconnected`, and `onMessage` handle lifecycle events. ### Parameters - **host** (string) - The hostname or IP address of the WebSocket server. - **port** (number) - The port number of the WebSocket server. - **secure** (boolean) - Whether to use a secure WebSocket connection (WSS). ### Methods - **connect()**: Establishes the WebSocket connection. - **close()**: Closes the WebSocket connection. - **write(message)**: Sends a message to the server. - **getState()**: Returns the current state of the WebSocket connection. ### Callbacks - **onConnected()**: Called when the connection is successfully established. - **onDisconnected(errored)**: Called when the connection is closed. `errored` is a boolean indicating if the disconnection was due to an error. - **onMessage(msg)**: Called when a message is received from the server. ``` -------------------------------- ### Lua Table with Mixed Array and Hashmap Parts Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Illustrates a Lua table containing both sequential integer keys (array part) and arbitrary keys (hashmap part). 'ipairs' only iterates the array part, while 'pairs' iterates all parts. ```lua Table = {[1] = 1, [2] = 2, [3] = 3, [4] = 4, a = 1, b = 2, c = 3, d = 4} for k, v in ipairs(Table) do print(k, v) end for k, v in pairs(Table) do print(k, v) end ``` -------------------------------- ### Lua Table Iteration with pairs Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Demonstrates iterating over all key-value pairs in a Lua table, including both array and hashmap parts, using the 'pairs' iterator. The order of iteration for 'pairs' is not guaranteed. ```lua for k, v in pairs(Table) do print(k, v) end ``` -------------------------------- ### Basic Chat Command Source: https://github.com/thegrb93/starfallex/wiki/Examples&Snippets A server-side chat command that prints the second argument after '!i' to the console. Only the owner can use this command. ```lua --@name basic commands --@author Wizard Lizard --@server local Arg = {}   hook.add("PlayerSay", "test", function(ply, text)     Arg = string.explode(" ", text)       if tostring(Arg[1]) == "!i" and ply == owner() then            print( tostring(Arg[2]) )                    return ""            end      end) ``` -------------------------------- ### Font Awesome Icon Rendering Source: https://github.com/thegrb93/starfallex/wiki/[Snippet-Example]-Font-Awesome-Lib This function renders a Font Awesome icon at specified coordinates and size. It ensures the correct font is loaded and then draws the icon as text. ```lua local awesomeFonts = {} local function getFont(size) if not awesomeFonts[size] then awesomeFonts[size] = render.createFont("FontAwesome", size, 400, true, false, false, false, false, true) end return awesomeFonts[size] end function render.drawIcon(x, y, icon, size) icon = unichar(icon) render.setFont(getFont(size)) render.drawText(x, y, icon, 0) end ``` -------------------------------- ### Basic Data Types in Lua Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Introduces fundamental Lua data types: String, Number, Function, Nil, Boolean, and Table. Shows how to check the type of a variable using the 'type()' function. ```lua local String = "hello" local Number = 108 local Function = function() print("hey") end local Nil = nil local Boolean = true local Table = {} print(type(String)) print(type(Number)) print(type(Function)) print(type(Nil)) print(type(Boolean)) print(type(Table)) -- Each Lua type has its own abilities -- String: string stores raw data and the 'string' library contains functions to manipulate and find data within them -- Number: numbers can be used for math of course. The 'math' library contains functions for numbers -- Function: functions contain code and allow you to execute it -- Nil: nil allows you to know if the variable has been defined or not; if it hasn't, it is nil. -- Boolean: booleans are like numbers but can only be 'true' or 'false' -- Table: tables can store anything and can be indexed with anything; they are what makes Lua so powerful. The 'table' library has some useful functions for them ``` -------------------------------- ### Lua Class Definition and Object Instantiation Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Defines a 'Ball' class with an initialize method and a think method for updating its position based on velocity and gravity. It then creates an array of 'Ball' objects and calls their 'think' methods. ```lua Ball = class("Ball") function Ball:initialize() self.x = 0 self.y = 0 self.dx = 0 self.dy = 0 end function Ball:think() self.x = self.x + self.dx * timer.frametime() self.y = self.y + self.dy * timer.frametime() sself.dy = self.dy + 9.8 * timer.frametime() end local Balls = {Ball:new(), Ball:new(), Ball:new(), Ball:new()} for _, v in ipairs(Balls) do v:think() end ``` -------------------------------- ### Adding a PlayerNoClip Hook Source: https://github.com/thegrb93/starfallex/wiki/[Tutorial]-Hooks This snippet demonstrates how to add a hook that triggers when a player uses noclip. It requires a unique name for the hook. ```lua --@name DTut: Hooks --@server hook.add("PlayerNoClip", "some_unique_name", function(user, state) if state then print("Oh wee! " .. user:getName() .. " is using noclip!") else print(user:getName() .. " isn't using noclip anymore") end end) ``` -------------------------------- ### Lua Table Iteration with # and ipairs Source: https://github.com/thegrb93/starfallex/wiki/Lua-Starfall-Crash-Course Demonstrates iterating over sequential 'array' parts of a Lua table using the length operator '#' and the 'ipairs' iterator. 'ipairs' is specifically designed for array-like tables. ```lua for i=1, #Table do print(type(Table[i])) end ``` ```lua for k, v in ipairs(Table) do print(type(v)) end ``` -------------------------------- ### 3D Skybox Effect with Multiple Screens Source: https://github.com/thegrb93/starfallex/wiki/Examples&Snippets Implements a 3D skybox effect using multiple screens, global matrix, and camera transformations. Requires texture loading and matrix manipulation. ```lua --@name --@author --@client local scale = 80000 local tex = { render.getTextureID("https://dl.dropboxusercontent.com/u/72472980/cs_tibetft.png"), render.getTextureID("https://dl.dropboxusercontent.com/u/72472980/cs_tibetrt.png"), render.getTextureID("https://dl.dropboxusercontent.com/u/72472980/cs_tibetbk.png"), render.getTextureID("https://dl.dropboxusercontent.com/u/72472980/cs_tibetlf.png"), render.getTextureID("https://dl.dropboxusercontent.com/u/72472980/cs_tibetup.png"), } local m = {} local angles = { Angle(0,0,-90), Angle(0,90,-90), Angle(0,180,-90), Angle(0,-90,-90), Angle(0,90,0), Angle(0,0,180) } local pos = chip():getPos()+Vector(0,0,scale/6) for i=1, 6 do m[i] = Matrix() m[i]:translate(pos) m[i]:rotate(angles[i]) m[i]:scale(Vector(scale,scale,scale)) m[i]:translate(Vector(-0.5,-0.5,0.5)) end hook.add("render","",function() for i=1, 5 do render.pushViewMatrix({type = "3D", zfar = 300000}) render.pushMatrix(m[i], true) render.setTexture(tex[i]) render.drawTexturedRect(0,0,1,1) render.popMatrix() render.popViewMatrix() end end) ``` -------------------------------- ### Copying a Vector in Lua Source: https://github.com/thegrb93/starfallex/wiki/[Tutorial]-References Shows how to create an independent copy of a vector using `table.copy`. The new vector `vec2` will have the same initial values as `vec1` but will not be linked, meaning changes to `vec2` will not affect `vec1`. ```lua local vec1 = Vector(3,2,1) local vec2 = table.copy(vec1) ``` -------------------------------- ### holograms.create — Create a Hologram Entity Source: https://context7.com/thegrb93/starfallex/llms.txt Spawns a hologram entity in the game world at a specified position, orientation, and with a given model and scale. Holograms can be manipulated with standard entity methods. ```APIDOC ## holograms.create ### Description Creates a hologram entity in the world. ### Method holograms.create(pos, ang, model, scale) ### Parameters - **pos** (Vector) - The world position to spawn the hologram. - **ang** (Angle) - The initial orientation of the hologram. - **model** (string) - The model path for the hologram. - **scale** (number, optional) - The scale of the hologram. ### Example ```lua -- Create a G-Man hologram above the chip local holo = holograms.create(c:getPos() + Vector(0,0,60), Angle(), "models/gman_high.mdl") holo:setColor(Color(128, 0, 255)) -- purple tint holo:setAngVel(Angle(0, 90, 0)) -- continuous yaw rotation -- Move it forward each tick hook.add("Tick", "moveHolo", function() holo:setPos(holo:getPos() + Vector(1, 0, 0)) end) -- Stop and animate after 3 seconds timer.simple(3, function() hook.remove("Tick", "moveHolo") holo:setAngVel(Angle()) holo:setAnimation("idle01") end) ``` ``` -------------------------------- ### prop.createSent Source: https://context7.com/thegrb93/starfallex/llms.txt Spawns a scripted entity (SENT) like a vehicle seat or lamp, returning a controllable entity. This function is useful for creating dynamic objects within the game world. ```APIDOC ## prop.createSent — Spawn Scripted Entities (SENTs) `prop.createSent(pos, ang, class, frozen, keyvalues)` spawns a SENT (scripted entity) like a vehicle seat or lamp, returning a controllable entity. ### Parameters - **pos** (Vector) - The position to spawn the entity at. - **ang** (Angle) - The angle to spawn the entity at. - **class** (string) - The class name of the entity to spawn. - **frozen** (boolean) - Whether the entity should be frozen. - **keyvalues** (table, optional) - Keyvalues to set on the entity. ### Returns - (Entity) - The spawned scripted entity. ``` -------------------------------- ### Coroutine for Spreading Work Source: https://context7.com/thegrb93/starfallex/llms.txt Utilizes Lua coroutines to distribute computationally intensive tasks across multiple ticks, integrating with the quota system to pause execution when CPU limits are approached. ```lua --@name Coroutine Sieve of Eratosthenes --@server local function quotaOK(n) return quotaAverage() < quotaMax() * n end local erato = coroutine.create(function(limit) local sieve = {} local sq = math.sqrt(limit) for i = 2, sq do if not sieve[i] then for j = i * i, limit, i do if not quotaOK(0.95) then coroutine.yield() end sieve[j] = true end end end local primes = {} for i = 2, limit do if not quotaOK(0.95) then coroutine.yield() end if not sieve[i] then primes[#primes + 1] = i end end return primes end) hook.add("think", "computePrimes", function() if coroutine.status(erato) ~= "dead" and quotaOK(0.8) then local result = coroutine.resume(erato, 50000) if result then print("Largest prime ≤ 50000:", result[#result]) hook.remove("think", "computePrimes") end end end) ```