Automatic Hooks
No more manually connecting Players.PlayerAdded or CharacterAdded yourself. If a method with one of these exact names exists on your Service or Controller, Owl wires it up automatically during OwlStart you just define the method and it fires when it should.
Server hooks (Services)
| Method | Signature | Fires when |
|---|---|---|
OwlOnPlayerAdded |
(plr: Player) |
A player joins or is already in-game when the Service starts |
OwlOnPlayerRemoving |
(plr: Player) |
A player leaves the game |
OwlOnCharacterAdded |
(plr: Player, char: Model) |
A character spawns (initial spawn or respawn) |
OwlOnCharacterRemoving |
(plr: Player, char: Model) |
A character is about to be removed |
OwlOnSpawnReady |
(plr: Player, char: Model) |
⚠️ CharacterAutoLoads = false mode only - see Owl vs Knit |
Client hooks (Controllers)
| Method | Signature | Fires when |
|---|---|---|
OwlOnCharacterAdded |
(char: Model) |
The LocalPlayer's character spawns |
OwlOnCharacterRemoving |
(char: Model) |
The LocalPlayer's character is about to be removed |
OwlOnLocalPlayerReady |
(plr: Player) |
The LocalPlayer is ready and PlayerGui has loaded, the right place for UI setup |
OwlOnPlayerCharacterReady |
(plr: Player, char: Model) |
A character has fully loaded (Humanoid + HumanoidRootPart both present) |
OwlOnPlayerLeft |
(plr: Player) |
A player leaves (visible client-side, for other players leaving) |
Using them
Just define the method with the exact name and signature from the tables above, no registration call, no Connect:
function DataService:OwlOnPlayerAdded(plr: Player)
self._playerData[plr.UserId] = { Points = 0 }
end
function DataService:OwlOnPlayerRemoving(plr: Player)
self._playerData[plr.UserId] = nil
end
OwlOnPlayerAddedfiring "for players already present at startup" matters more than it looks: without it, a Service that starts after players have already joined (a redeploy scenario or a Service with heavyDependencies) would silently skip initializing data for anyone already connected. Owl handles that edge case for you, you never need an extrafor _, plr in Players:GetPlayers()loop alongsidePlayerAdded.
Hooks run inside the module's OwlStart phase, so everything covered in Lifecycle still applies, by the time any hook fires, every Service and Controller has already finished OwlInit.
Where to go next
- Lifecycle - how these hooks fit into
OwlInit/OwlStart/OwlDestroy. - Owl vs Knit - more on
OwlOnSpawnReadyand manual-spawn mode. - Services and Controllers - where these hooks are typically defined alongside the rest of a module's logic.