From 44c0f8e25ce5c40e76663906a0cb88710b17d646 Mon Sep 17 00:00:00 2001 From: Samuel Lison Date: Mon, 6 Jul 2026 15:38:26 +1000 Subject: [PATCH 1/2] fix: beacon follows the owner's newest bag; older bags never clear it Dying again mid corpse-run drops a second bag (old + new coexist in the world, each on its own 5-minute timer) and re-points the owner's beacon at the new one. Previously the OLDER bag's later despawn/looting fired the unscoped beacon-clear and wiped the beam pointing at the newer bag. LootBags now tracks each owner's latest bag and only its destruction clears the beacon. docs/loot-bags.md: documented the multi-bag + beacon-follows-newest behavior. Live-verified: two coexisting bags, beacon on the newest; looting the OLD bag left the beacon untouched; looting the NEW bag cleared it. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 7 +++++++ docs/loot-bags.md | 7 ++++++- src/systems/LootBags.luau | 18 +++++++++++++++--- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65ea72a..092e1cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to SurvivorCore are recorded here. The format follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). At release time, `## Unreleased` is promoted to the new version and `main` is tagged `vX.Y.Z`. +## Unreleased + +### Fixed +- **Beacon scoped to the newest bag** — dying again mid corpse-run re-points the owner's beacon at + the new bag (old and new bags coexist, each on its own 5-minute timer); previously the OLDER + bag's later despawn/looting would wipe the beacon that pointed at the newer bag. + ## 0.7.3 — 2026-07-06 ### Fixed diff --git a/docs/loot-bags.md b/docs/loot-bags.md index 15859cb..0e5a9ba 100644 --- a/docs/loot-bags.md +++ b/docs/loot-bags.md @@ -15,7 +15,12 @@ survival stakes system: get back to your bag before it's gone — or before some deaths stay reachable), holding the contents as `IntValue` children (item id → count). A floating **countdown** shows everyone how long it has left; the **owner** also gets a tall golden **beacon** (client-side, only they see it) and a "You died" toast. -4. After `LifetimeSeconds` the bag despawns with whatever is still inside. +4. After `LifetimeSeconds` (default **5 minutes**) the bag despawns with whatever is still inside. + +**Dying again mid corpse-run:** every death drops its own bag — old and new **coexist in the +world**, each on its own 5-minute timer, each lootable. Your **beacon always points at your newest +bag** (a new death re-points it); it clears only when *that* bag is looted empty or expires — an +older bag despawning never touches it. ## Looting diff --git a/src/systems/LootBags.luau b/src/systems/LootBags.luau index bbe4e1b..e4d4f7f 100644 --- a/src/systems/LootBags.luau +++ b/src/systems/LootBags.luau @@ -36,6 +36,12 @@ local LootBags = {} local started = false local looting: { [Player]: boolean } = {} -- re-entry guard per collector +-- Each owner's NEWEST bag — the one their beacon points at. Older bags coexist in the world on +-- their own timers; only the latest bag's fate may clear the owner's beacon (dying again mid +-- corpse-run re-points the beacon at the new bag, and the old bag's later despawn must not +-- touch it). +local latestBag: { [Player]: Instance } = {} + -- ── Bag construction ───────────────────────────────────────────────────────── local function bagTemplate(): PVInstance? @@ -292,12 +298,17 @@ local function dropBag(player: Player, position: Vector3) -- is truly gone (the nil-fire below) or the lifetime lapses. local host2 = bagHost(bag) local beaconPos = if host2 then host2.Position else position + latestBag[player] = bag if cfg.OwnerBeacon ~= false then Remotes.event("LootBagDropped"):FireClient(player, beaconPos, lifetime) bag.Destroying:Connect(function() - -- Truly gone server-side (emptied or expired) → clear the owner's beacon early. - if player.Parent then - Remotes.event("LootBagDropped"):FireClient(player, nil) + -- Clear the owner's beacon ONLY if this is still their newest bag (an older bag + -- despawning/emptying must not wipe the beacon that points at a newer one). + if latestBag[player] == bag then + latestBag[player] = nil + if player.Parent then + Remotes.event("LootBagDropped"):FireClient(player, nil) + end end end) end @@ -357,6 +368,7 @@ function LootBags.start(_options: { [string]: any }?) Players.PlayerAdded:Connect(watchPlayer) Players.PlayerRemoving:Connect(function(player) looting[player] = nil + latestBag[player] = nil end) end From 51426d6e3ad839bf0fe8b8ac710bc8a975262d6d Mon Sep 17 00:00:00 2001 From: Samuel Lison Date: Mon, 6 Jul 2026 15:39:19 +1000 Subject: [PATCH 2/2] chore(release): v0.7.4 Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 2 +- src/init.luau | 2 +- wally.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 092e1cd..15545fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to SurvivorCore are recorded here. The format follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). At release time, `## Unreleased` is promoted to the new version and `main` is tagged `vX.Y.Z`. -## Unreleased +## 0.7.4 — 2026-07-06 ### Fixed - **Beacon scoped to the newest bag** — dying again mid corpse-run re-points the owner's beacon at diff --git a/src/init.luau b/src/init.luau index fc9deca..c970dae 100644 --- a/src/init.luau +++ b/src/init.luau @@ -65,7 +65,7 @@ require(script.shared.LootBagsConfig) local SurvivorCore = {} -SurvivorCore.VERSION = "0.7.3" +SurvivorCore.VERSION = "0.7.4" -- Foundation SurvivorCore.Config = Config diff --git a/wally.toml b/wally.toml index 282ff62..76ad12b 100644 --- a/wally.toml +++ b/wally.toml @@ -1,7 +1,7 @@ [package] name = "temujincalidius/survivorcore" description = "Batteries-included, creator-extensible survival game framework for Roblox." -version = "0.7.3" +version = "0.7.4" license = "MIT" authors = ["Samuel Lison"] registry = "https://github.com/UpliftGames/wally-index"