Workspace & Auto-Execute
The sandboxed folder your scripts read and write, and how to run a script automatically on join.
Every filesystem function is relative to the workspace folder that sits next to the client. Paths never escape it — readfile("../secrets.txt") fails rather than reaching up.
| Folder | What lives there |
|---|---|
| workspace/ | The root every path in readfile, writefile and friends resolves against. |
| autoexec/ | Scripts here run automatically each time you join a game. |
| scripts/ | Where the editor saves tabs by default, and what the file explorer shows. |
| assets/ | A convention, not a rule — a tidy place for images and fonts you pass to getcustomasset. |
Drop a .lua or .txt file into autoexec/ and it runs on every join, in the order the folder lists it. This is how most people load a hub or a personal utility script without touching the editor.
-- autoexec/always.lua
-- Runs on every join. Keep it defensive: the game may not
-- be fully loaded when this fires.
if not game:IsLoaded() then
game.Loaded:Wait()
end
local Players = game:GetService("Players")
local me = Players.LocalPlayer
warn(("joined %s as %s"):format(game.PlaceId, me.Name))
-- Only load the heavy stuff in the places it is meant for.
if game.PlaceId == 1234567890 then
loadstring(readfile("scripts/that-game.lua"))()
endAuto-execute runs before you can stop it
A broken script in autoexec/ runs on every single join. If a join starts erroring the moment you land, empty the folder first and add files back one at a time.
The filesystem chapter has the full surface. The short version:
-- Write, read back, append.
writefile("notes.txt", "first line\n")
appendfile("notes.txt", "second line\n")
print(readfile("notes.txt"))
-- Folders and listings.
if not isfolder("logs") then
makefolder("logs")
end
for _, path in ipairs(listfiles("logs")) do
print(path)
end
-- Load Luau straight off disk.
local chunk = loadfile("scripts/util.lua")
if chunk then chunk() endgetcustomasset turns a file in the workspace into a rbxasset:// URL the Roblox renderer will accept, which is how you get a local image onto an ImageLabel or into a Drawing object.
local url = getcustomasset("assets/crosshair.png")
local gui = Instance.new("ScreenGui", gethui())
local image = Instance.new("ImageLabel", gui)
image.Image = url
image.Size = UDim2.fromOffset(32, 32)
image.BackgroundTransparency = 1