Start order: required, after and before
Mark a start function required and the game can't forget to call it. Say what it runs after or before, and shot check holds the start script to that order.
You'll learn required, after and before, and what the checker says when they break.
Init/Server.shot, top to bottom- 1
Stats.Start()listens first - 2
Bank.Start()required: opens the wallets - 3
Shop.Server.Start()then the shop
before Bank.Start on Stats.Start: swap the two calls and shot check errors at the line that must move.
A start nobody calls
Bank.Start opens every wallet. Today a script that forgets the call runs with no error and no wallets:
-- Call once when the server starts,-- or nobody gets a wallet.function Bank.Start() for _, player in Players:GetPlayers() do Bank.Open(player) end Players.PlayerAdded:Connect(Bank.Open)end
doc { Opens a wallet for every player }required function Start() local here = Players:GetPlayers() for _, player in here do module.Open(player) end Players.PlayerAdded:Connect( module.Open)end
What it compiles toWallet/Bank.luau (part)
--[[$doc Opens a wallet for every player ]] function Bank.Start() local here = Players:GetPlayers() for _, player in here do module.Open(player) end Players.PlayerAdded:Connect( module.Open) end
Tip required leaves no trace in the Luau: it is a promise the checker keeps. On a class it goes on a static function, public required static Setup().
Take Bank.Start() out of Init/Server.shot (the first error comes from the order below):
./Stats/Stats.shot:11:26 before Bank.Start: no script calls Bank.Start() (nearest: Stats.Start): write the name as Init/Server.shot calls it ./Wallet/Bank.shot:44 required Bank.Start is never called: the game runs without it 2 errors in 2 files (16 files checked, 4.9 s)
One start before another
Bank.Start now opens wallets for players already in the server, and Bank.Open tells the game with a second Wallet event:
-- A wallet was opened for a player event WalletOpened(player : Player)
doc { Opens a wallet for the player } function Open(player : Player) module.Wallets[player] = Wallet.new(0) module.Count += 1 WalletOpened.Publish(player) end
Stats counts those, so it must listen before Bank opens the first. The order goes on the header of the function that needs it:
-- Stats before Bank: Stats counts the-- wallets Bank.Start opens.Stats.Start()Bank.Start()Shop.Server.Start()
doc { Wallets opened so far }Opened : number = 0function Start() before Bank.Start WalletOpened.Subscribe(function( player : Player) module.Opened += 1 end) CoinsGiven.Subscribe(function( player : Player, amount : number, reason : Reason) module.Total += amount end)end
What it compiles toStats/Stats.luau (part)
Stats.Opened = 0 function Stats.Start() WalletOpened.Subscribe(function( player : Player) module.Opened += 1 end) CoinsGiven.Subscribe(function( player : Player, amount : number, reason : Reason) module.Total += amount end) end
(Stats/Types.shot now reads import CoinsGiven, WalletOpened, Reason from Wallet.)
after X: X's call must come above this function's call in the script that calls both;before Y: below it. Both may sit on one line, and several names take commas.- Write each name as the start script calls it:
Bank.Start,Shop.Server.Start. - The clause isn't code: it is left out of the compiled Luau.
- Declare an order only when it is true, on the side that breaks: Stats misses the wallets, so Stats says
before Bank.Start.
Checked
Swap the two calls in Init/Server.shot, Bank.Start() above Stats.Start():
./Init/Server.shot:8:1 Stats.Start() runs after Bank.Start() (line 7), but Stats.Start must run before it (Stats/Stats.shot:11: before Bank.Start): move this line above line 7, or if Stats no longer needs that order, drop before Bank.Start there 1 errors in 1 file (16 files checked, 2.6 s)
The order is real. A player already in the server when it starts:
-- Opened: a player already in the server when it starts gets a wallet, and Stats counts it. return function(world) local Stats = world.Server.Require("Stats") local ana = world:AddPlayer("Ana") world:Boot() world:AddPlayer("Bo") world:Step(0.1) world.Logf("Stats.Opened is %s", world.Fmt(Stats.Opened)) assert(Stats.Opened == 2, "Ana, already here, and Bo") end
Swapped, Ana is missed:
==== Opened
[client:Ana print] client started
[client:Bo print] client started
Stats.Opened is 1
---- scenario error
[scenario] Scenarios/Opened.luau:9: Ana, already here, and Bo
Scenarios/Opened.luau:9
==== summary
Opened FAILED (3 lines, 1 errors, 0.1s virtual)
0 of 1 scenario(s) passedIn the right order:
==== Opened [client:Ana print] client started [client:Bo print] client started Stats.Opened is 2 ==== summary Opened OK (3 lines, 0 errors, 0.1s virtual) 1 of 1 scenario(s) passed
Give the clause a reason in braces, before Bank.Start {it counts the wallets Bank opens}, and swap the two lines again. The error now quotes your reason, and says how to keep the other order if you ever need it.
