netOnce
Handle each network message exactly once. `NetOnce.on(channel, handler)` listens on a multiplayer channel so every message on it reaches `handler(fromPeer, ...)` one time, however many times your code reloads, Play is entered and left, or the world is opened again. `NetOnce.send(…
netOnce
Handle each network message exactly once. NetOnce.on(channel, handler) listens on a multiplayer channel so every message on it reaches handler(fromPeer, ...) one time, however many times your code reloads, Play is entered and left, or the world is opened again. NetOnce.send(channel, ...) sends a message stamped with an id, and a receiver drops an id it already handled from that peer.
Why: a function given to multiplayer.on can never be removed (#19267), so every reload or re-subscription leaves one more listener behind, and each one fires for every message. That is how one shot from another player got handled several times. netOnce keeps the id of the one current listener per channel in modules.state() (shared by every run of the module) and every older listener stands down when a message arrives.
weaponsKit's net module sends and receives all its channels (shots, verdicts, reloads, health readings, host announcements) through it. Use it in your own kits the same way:
local NetOnce = require("weaponsKit.netOnce")
NetOnce.on("myGame:score", function(from, points) print(from, points) end)
NetOnce.send("myGame:score", 10)
-- when the session changes (edit to play, a new room), give each channel a fresh listener:
NetOnce.refresh()
print(NetOnce.status().channels["myGame:score"].handled)
NetOnce.status() reports, per channel, how many listeners were registered, how many messages were handled, how many duplicates were dropped and how many times an old listener stood down. NetOnce._arrive(channel, from, ...) calls every listener the module ever registered, the way the engine does when a message arrives, for tests.
Scoped to this part · feeds back into the world's score.