file
File I/O + image assets.
File paths are relative to the application directory. Any path string containing the substring .. is rejected (sandbox); absolute paths are also rejected. Note: substring match — my..file.txt is also rejected.
File
file.read(path) → string | nil
Parameters: path : string
file.write(path, content) → bool
Parameters: path : string, content : string
Parent directories are created automatically.
file.exists(path) → bool
file.remove(path) → bool
file.rename(old, new) → bool
Sandboxed rename / move. The target parent directory is created automatically. Both endpoints pass the sandbox check (no .., no absolute paths).
file.list(dir) → table<string>
Lists filenames inside dir (non-recursive, files only, not subdirectories). Empty / missing dir returns an empty table.
file.scan(pattern) → table<string>
Glob match returning full relative paths (non-recursive). Supports * (any sequence) and ? (single char).
local logs = file.scan("logs/*.log") -- {"logs/a.log", "logs/b.log", ...}
local cfgs = file.scan("scripts/state/*.json")
local r24 = file.scan("logs/2024-??-??.log") -- single-char wildcardImage assets (file.image)
handle is an opaque texture handle, passed to draw.image to display.
When the script unloads, all image handles it created are released automatically.
file.image:load(path) → handle | nil
Parameters: path : string
Also accepts (path, w, h) to force a target size.
file.image:svg(svg_str, w, h) → handle | nil
Parameters: svg_str : string, w : int, h : int
file.image:create(rgba, w, h) → handle | nil
Parameters: rgba : table byte array of length w*h*4, w/h : int
file.image:get(name) → handle | nil
file.image:has(name) → bool
file.image:list() → table<string>
Lists all texture names in TextureManager — including project-internal ESP icons and textures created by other scripts, not just the ones owned by the current script. When pairing with file.image:remove, filter by owner first or you'll wipe someone else's textures.
file.image:remove(name) → bool
file.image:load_gif(path) → AnimatedTexture | nil
Parameters: path : string — GIF file path (sandboxed relative path)
Returns an AnimatedTexture userdata containing all frames + per-frame delays (ms). Frame SRVs are owned by the AnimatedTexture and released as a unit when the script unloads.
AnimatedTexture methods / fields
| Name | Description |
|---|---|
:advance(dt_sec) → handle | Advance by dt_sec. Returns the current-frame handle — feed directly to draw.image. Skips frames if dt is large, never drops frames. |
:current_frame() → handle | Returns current-frame handle without advancing |
:reset() | Reset to frame 0 |
.frame_count | int — total frames |
.width / .height | int — GIF dimensions (consistent across frames) |
.current_index | int — current frame index (0-based) |
.current_delay_ms | int — current frame's delay in milliseconds |
local gif = file.image:load_gif("scripts/assets/loading.gif")
event.on("frame_update", function(e)
if gif then
local frame = gif:advance(e.delta_time)
draw.image(frame, 100, 100, gif.width, gif.height)
end
end)Example
-- Config persistence
local cfg_path = "scripts/state/my_script.json"
if file.exists(cfg_path) then
local raw = file.read(cfg_path)
-- parse JSON / ...
end
file.write(cfg_path, [[{"flag":true}]])
-- Load a logo
local logo = file.image:load("scripts/assets/logo.png")
event.on("frame_update", function(e)
if logo then draw.image(logo, 10, 10, 64, 64) end
end)
-- Procedurally generated SVG icon
local icon = file.image:svg(
[[<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" fill="#ff5050"/></svg>]],
24, 24)