Hooks
The four end-of-game callbacks and what each one is handed.
Server/Hooks.luau ships empty. Add any of the four functions below and it is called;
leave it out and nothing happens. Each runs inside a pcall, so an error in your code
cannot break a game.
local Hooks = {}
function Hooks.onWin(player, ctx) end
function Hooks.onLoss(player, ctx) end
function Hooks.onDraw(player, ctx) end
function Hooks.onGameEnd(info) end
return Hooks
The per-player hooks
onWin, onLoss and onDraw are called once for each human in the game, from that
player's point of view. A human beating a human calls onWin for one and onLoss for the
other.
ctx = {
mark = "X", -- the side this player played
opponent = Player, -- the other player, or nil against the bot
vsBot = false,
reason = "line", -- how the game ended
}
This is where your own economy goes:
function Hooks.onWin(player, ctx)
if not ctx.vsBot then
MyEconomy.addCoins(player, 100)
end
end
Checking ctx.vsBot matters. Without it a player can sit alone at a table and beat Easy
for as long as they like.
onGameEnd
Called once per game, whoever was playing.
info = {
winner = "X", -- "X", "O", or nil for a draw
reason = "line",
vsBot = true,
x = { player = Player, isBot = false },
o = { player = nil, isBot = true },
}
Use it for logging, announcements and analytics: it is the one call that sees the whole game rather than one side of it.
function Hooks.onGameEnd(info)
if not info.vsBot then
Analytics.log("ttt_pvp", { winner = info.winner, reason = info.reason })
end
end
Ordering
For a finished game the order is:
leaderstatsare updated, subject toCountBotGames- the configured rewards are paid, subject to
PayBotGames onWin/onLoss/onDrawfire, once per humanonGameEndfires
So by the time your hooks run, the built-in counters already reflect the result. Reading them inside a hook gives the new numbers, not the old ones.
A resignation is a result
Standing up mid-game, leaving the server, or pressing resign ends the game with the other
side as the winner and a reason naming it. The hooks fire normally.
Do not treat a resignation as a non-event in your own scoring: the players will find it within an hour if you do.
Was this page helpful?