Lost Data When Updating PlayerProfileDataMap
Twice in One Flow
Hey creators!
I wanted to share a subtle bug I ran into while using persistent weak_map
data like PlayerProfileDataMap
. If you modify a player’s data and then later update it again using the same base data, you can accidentally overwrite earlier changes, even from other functions. The key point is: only the last update you make will persist; any previous ones will be lost.
The Problem
Let’s say you have this:
var PlayerProfileDataMap:weak_map(player, player_profile_data) = map{}
And this function to add score:
AddScore(Player:player, Amount:int):void =
if (Data := PlayerProfileDataMap[Player]):
set PlayerProfileDataMap[Player] = player_profile_data:
MakePlayerProfileData<constructor>(Data)
Score := Data.Score + Amount
Then in another function:
HandleButtonPress(Player:player):void =
if (Data := PlayerProfileDataMap[Player]):
AddScore(Player, 100) # <-- Problem here
if:
set PlayerProfileDataMap[Player] = player_profile_data:
MakePlayerProfileData<constructor>(Data)
Level := Data.Level + 1
What happens:
AddScore
writes an updated score into the map, but immediately after, the second set
uses the same original Data
, overwriting the map with stale information. This means the score increase is lost, because only the last set
call’s data is saved.
The Solutions
You don’t need to rewrite or merge the data manually. Just make sure the AddScore
call happens after the last overwrite, or outside/before any conditional assignment using Data
.
Option 1: Move the call after the set
HandleButtonPress(Player:player):void =
if (Data := PlayerProfileDataMap[Player]):
if:
set PlayerProfileDataMap[Player] = player_profile_data:
MakePlayerProfileData<constructor>(Data)
Level := Data.Level + 1
AddScore(Player, 100) # ✅ Now this change won't be overwritten
Or Option 2: Move the call outside the Data
scope
HandleButtonPress(Player:player):void =
AddScore(Player, 100) # ✅ Now this change won't be overwritten
if (Data := PlayerProfileDataMap[Player]):
if:
set PlayerProfileDataMap[Player] = player_profile_data:
MakePlayerProfileData<constructor>(Data)
Level := Data.Level + 1
Key takeaway
- When you modify
PlayerProfileDataMap
multiple times in a single logical flow, only the last update will be saved. - Earlier updates done with a stale reference will be overwritten and lost.
- To prevent losing data, make sure function calls that update persistent data occur after all other writes, or outside the
Data
conditional block.
I hope this helps someone avoid this tricky problem that took me hours to figure out on my map!