Skip to content

BPL_BL_ModCopies

BurrowLib 0.1.0, in the palette under BurrowLib › Mod copies.

Making sure only one copy of a mod runs.

Two copies of one mod can be installed at once, and the game loads both: a player installs the zip from Discord and subscribes on the Workshop as well, a renamed mod leaves its old pak behind, or a Workshop item arrives while the game is running. Each copy spawns its own BP_MapLoad, and everything the mod does happens twice.

A copy cannot find the other by looking for actors of its own class: the two are different classes in different paks, even when their files are identical. So each copy names itself with actor tags, which any copy can search for, and they settle which one runs. The tags start with “BurrowLib.ModCopies.v1.”, whatever the library’s version, so copies built against different versions still see each other:

on ReceiveBeginPlay {
BPL_BL_ModCopies.Announce(self, "my-mod", 3)
}
on ReceiveTick(dt: float) {
if !Settled {
Settled = true
if !BPL_BL_ModCopies.ShouldRun(self, "my-mod", 3) {
K2_DestroyActor()
return
}
}
...
}

The id must stay the same for the life of the mod, across renames, and the build must go up with every release. A newer build always wins. Copies of the same build are the same mod, so exactly one of them runs, whichever asks first.

fn Announce(mod: Actor, id: string, build: int)

Tags this copy with its id and its build, so other copies can find it. Call it in BeginPlay, before any copy calls ShouldRun.

fn ShouldRun(mod: Actor, id: string, build: int) -> bool

Whether this copy is the one to run. Call it once, on the first Tick rather than in BeginPlay: by the first Tick every copy has announced itself, and a copy deciding earlier could miss one. When it returns false, destroy this copy (DestroyActor) before it does anything else. It stops ticking at once, though it stays in memory until the next garbage collection.

fn Tag(id: string, what: string, n: int) -> name

The tag Announce and ShouldRun use, “BurrowLib.ModCopies.v1...”. A mod does not need to call it.

fn Prefix(id: string) -> string

Every tag of a mod’s copies starts with this. v1 is the tags’ format, not the library’s version: a library that changes the format announces both, so older copies still see it.