Getting started

Make a project with one command, give it a program and run it, then build its instances from the command line, every change one step you can take back.

A project is one text file, <Name>.shotsystem. Run every command from the folder that holds it: shot run takes the file's name, and the commands that read or change a project take --project <Name>.shotsystem.

Make a project

One command, and the whole project is a file you can read.

shot new Shop.shotsystem

prints

made Shop.shotsystem

and writes three lines:

Shop.shotsystem

shotsystem 1

id 13a973ac3b035e714a971498193242ca

The lines above the empty line are the header. Under it come the project's id and, soon, its instances (see One-file projects).

Run your first program

Add four lines and it runs. Open Shop.shotsystem in any text editor, name the program in the header and add it:

Shop.shotsystem

shotsystem 1
export Main

id 13a973ac3b035e714a971498193242ca
Luau Main
    source
        print("Shop is open")
  • export Main says what the project offers. A plain Luau module export is a program: shot run runs it once.
  • Luau Main is that module, with its code one tab deeper than source. Indent with tabs: a line indented with spaces is refused, with its line number. Leave out the # id the tools write on every instance line; the project gets one when it next saves.

Run it:

shot run Shop.shotsystem

It prints

Shop is open

A misspelt export stops it before anything runs, with exit code 1:

Shop.shotsystem exports Mian, and it has no Mian

Make this edit right after shot new, before any command with --project. Those commands keep the project open and save it a moment after each change, so a hand edit made while it is open is lost without a word. Once you have used them, change the header as a folder instead: export the project, edit its .shotsystem file and import it as a new project (FROM A FOLDER AND BACK).

Add instances

Build the project from the command line: folders, values, scripts. shot tree shows what is in it:

shot tree --project Shop.shotsystem

prints

Shop.shotsystem
./  (the project)
  Main.luau  (Luau)

Make a folder in the root (.), a StringValue in it, and give it a value:

shot create Folder . Settings --project Shop.shotsystem
shot create StringValue Settings Currency --project Shop.shotsystem
shot set Settings/Currency Value Coins --project Shop.shotsystem

They print one line each. Most changes also print a files changed: line, left out on this page.

created Settings (Folder)
created Settings/Currency.instance (StringValue)
Settings/Currency.instance.Value = Coins (was "")

shot props shows one instance:

shot props Settings/Currency --project Shop.shotsystem

prints

Settings/Currency.instance  (StringValue)
  Value = Coins
attributes: none
children: none

The classes are Folder, Script (a .shot file), Luau (a plain Luau module), StringValue, NumberValue, IntValue, BoolValue, ObjectValue, Color3Value and Vector3Value. In the file they are lines like the ones you wrote:

Shop.shotsystem

Folder Settings #77b37c9c
    StringValue Currency #71bd145c
        Value = "Coins"

Change scripts

Write a whole script, or swap one piece of text, and it is checked on the spot. Put the new text of Main in a file:

main.luau

local currency = script.Parent.Settings.Currency
print("Shop is open, prices in " .. currency.Value)

Then write it into the project:

shot write Main.luau --project Shop.shotsystem --input main.luau

prints

replaced Main.luau (2 lines)

check:
0 errors (1 files checked, 0.1 s)

Main sits in the root, so script.Parent is the project's root and the program reads Settings by its path. A run saves the project first, so it sees every change the commands made:

shot run Shop.shotsystem

prints

Shop is open, prices in Coins

shot edit replaces one piece of text, given as JSON:

edit.json

{"old": "Shop is open", "new": "Welcome to the shop"}

Then:

shot edit Main.luau --project Shop.shotsystem --input edit.json

prints

edited Main.luau line 2

check:
0 errors (1 files checked, 0.1 s)

and the next run prints Welcome to the shop, prices in Coins. Without --input, both read the text from stdin. A file that doesn't exist yet is created by shot write.

Attributes and tags

Hang your own data on any instance. A new attribute is a number, true or false, or text, unless --type names another type (Color3, Vector3, ...; see One-file projects for all of them):

shot attr Settings/Currency Max 500 --project Shop.shotsystem
shot attr Settings/Currency Tint "1, 0.8, 0" --type Color3 --project Shop.shotsystem
shot tag Settings/Currency Tuning --project Shop.shotsystem

print

Settings/Currency.instance @Max = 500  (number, new)
Settings/Currency.instance @Tint = 1, 0.8, 0  (Color3, new)
tagged Settings/Currency.instance Tuning

and props now shows them:

Settings/Currency.instance  (StringValue)
  Value = Coins
attributes:
  Max = 500  (number)
  Tint = 1, 0.8, 0  (Color3)
tags: Tuning
children: none

--remove takes one off:

shot attr Settings/Currency Max --remove --project Shop.shotsystem
shot tag Settings/Currency Tuning --remove --project Shop.shotsystem

print

removed Settings/Currency.instance @Max
removed tag Tuning from Settings/Currency.instance

Rename, move and delete

Rename and move with shot set, delete with shot destroy. Setting Name renames an instance, setting Parent moves it, and destroy deletes it with everything under it.

shot create Folder . Prices --project Shop.shotsystem
shot create NumberValue . Apple --project Shop.shotsystem
shot set Apple Value 1.5 --project Shop.shotsystem
shot set Apple Parent Prices --project Shop.shotsystem
shot set Prices/Apple Name Pear --project Shop.shotsystem

print

created Prices (Folder)
created Apple.instance (NumberValue)
Apple.instance.Value = 1.5 (was 0)
moved Apple.instance to Prices/Apple.instance
renamed Prices/Apple.instance to Prices/Pear.instance

and the tree is now

Shop.shotsystem
./  (the project)
  Main.luau  (Luau)
  Prices/
    Pear  (NumberValue)
  Settings/
    Currency  (StringValue)

Then delete the folder:

shot destroy Prices --project Shop.shotsystem

prints

deleted Prices and the 1 instance under it (shot undo brings it back)

Checked paths

Point at any instance by its path from the project's root (see Checked paths):

Settings/Currencyfolders joined by /
.the root itself
Settings/Currency.instancethe same instance by its file name
Cart/Item[2]the second of two children called Item

shot create never makes two children with one name, but a file written by hand may hold them:

Cart.shotsystem

shotsystem 1

Folder Cart
    IntValue Item
        Value = 1
    IntValue Item
        Value = 2

Then a path to one of them needs its number. shot props Cart/Item --project Cart.shotsystem says

2 things in Cart are called Item; say which: Item[1] (IntValue), Item[2] (IntValue)

and shot props Cart/Item[2] --project Cart.shotsystem shows the second:

Cart/Item[2]  (IntValue)
  Value = 2
attributes: none
children: none

Take it back

Every change is one step, and any step can be taken back. shot undo takes back the last change, whoever made it, and shot redo puts it back; shot write and shot edit are steps too.

shot undo --project Shop.shotsystem

prints

undid destroy Prices (by cli): Prices/Pear.instance

and Prices and Pear are back in the tree. Then

shot redo --project Shop.shotsystem

prints

redid destroy Prices (by cli): Prices/Pear.instance

and they are gone again.

Go back to an earlier save

Every save can come back. The project saves itself a moment after each change; shot save writes it now and keeps a dated copy:

shot save --project Shop.shotsystem

prints

saved Shop.shotsystem; dated copy Shop_2026-10-19_00-41-03

shot history --project Shop.shotsystem lists the copies, newest first. They are plain .shotsystem files in a folder Shop.history beside the project (the line naming that folder is left out here):

 Shop_2026-10-19_00-41-030 KB
 Shop_2026-10-19_00-40-510 KB
 Shop_2026-10-19_00-40-490 KB
 Shop_2026-10-19_00-40-470 KB

Restore the copy from before the attributes:

shot restore Shop_2026-10-19_00-40-51 --project Shop.shotsystem

prints

restored Shop_2026-10-19_00-40-51 (shot undo takes it back)

and Tint is gone. shot props Settings/Currency --project Shop.shotsystem prints

Settings/Currency.instance  (StringValue)
  Value = Coins
attributes: none
children: none

A restore is one step: shot undo brings back Tint and everything else the copy didn't have.

From a folder and back

Prefer plain files? Turn the project into a folder, edit it in any editor, and make a project from it again.

shot export Shop.shotsystem ShopFiles

writes one file per script and per instance, and the header as .shotsystem:

ShopFiles/
    .shotsystem
    Main.luau
    Settings/
        Currency.instance

An instance file holds its class, then its own lines from the project file:

ShopFiles/Settings/Currency.instance

StringValue
Value = "Coins"
attribute Tint = Color3(1, 0.8, 0)

Change "Coins" to "Gems" there, then make a new project from the folder:

shot import ShopFiles Shop2.shotsystem

prints

imported 3 files from ShopFiles into Shop2.shotsystem

and the new project runs with the change:

shot run Shop2.shotsystem

prints

Welcome to the shop, prices in Gems

The folder's .shotsystem file is the header, so this is also how you change export once commands have the project open. shot import makes a new project and never writes over one:

Shop.shotsystem already exists (export it or pick another name)

What works on a project

shot help --project Shop.shotsystem lists every command that works on a project, with its arguments. Besides the ones above, the reading tools work on it too, like shot show Main.luau --project Shop.shotsystem and shot check --project Shop.shotsystem. For what a run can reach and how its errors read, see Running a project; to start other programs from yours, see ProcessService. To work on a project in a window instead, see The window.