Storage (soft memory)¶
Storage is a simple key‑value store your script can read and write — counters, flags, "have I seen this player," small bits of state. It's soft memory: fast, in‑memory, and scoped to your script.
int visits = Storage.GetInt("visits", 0) + 1;
Storage.SetInt("visits", visits);
Storage.SetString("last_winner", playerName);
string who = Storage.GetString("last_winner", "nobody");
API¶
| Call | Returns |
|---|---|
Storage.SetString(key, value) / GetString(key, default = "") |
string |
Storage.SetInt(key, value) / GetInt(key, default = 0) |
int |
Storage.SetFloat(key, value) / GetFloat(key, default = 0) |
float |
Storage.HasKey(key) |
bool |
Storage.DeleteKey(key) / Storage.DeleteAll() |
— |
What "soft" means — read this¶
In‑memory, per‑instance — lost on restart
Storage lives in RAM on the running world instance. It is not saved to disk.
- ✅ A player who leaves and rejoins while the instance is up is remembered.
- ❌ When the world instance restarts (or empties out and shuts down), Storage is wiped.
So it's perfect for "this session" — scores, round state, who's here now — but not for anything that must survive a restart.
It's also sandboxed per script class: each NexusScript gets its own isolated store, so two scripts can't read each other's keys (no accidental collisions). Limits: 256 keys per script, 4 KB per value.
Shared variables for scripts¶
Storage is private to your script. To share session state with the no‑code World Triggers / Interactables (or another script), use World.* (one instance‑wide value) and Player.* (per‑player), which read/write the same server‑authoritative store the no‑code variables use:
World.Add("score", 1); // atomic on the server — no races
int s = World.GetNumber("score", 0);
World.SetString("notice", "Round 2!"); // a no-code "Set text" can display this
Player.SetNumber("lives", 3); // this player's own value
Call (World.* and Player.*) |
Returns |
|---|---|
GetNumber(name, default = 0) / SetNumber(name, value) / Add(name, amount) |
number |
GetString(name, default = "") / SetString(name, value) |
string |
GetBool(name, default = false) / SetBool(name, value) |
bool |
These are server‑authoritative session memory (synced to clients, still wiped on restart — durable saves go to your DB, below). Declare the variable as a World/Player variable on a World Trigger or Interactable so its type is known and the no‑code editor can reference it too. Player.* targets the current player context (e.g. an OnPlayerJoined flow).
When you need it to last — durable storage¶
For anything that must persist across restarts (visit counts, rewards, progression, leaderboards), write to your own database with the HTTP API (Supabase, Firebase, PlayFab, Nhost, or Neon), keyed by the player's stable account id (Player.GetUserId):
string userId = Player.GetUserId(playerId); // stable across sessions
// Http.* → POST/PATCH a row keyed by userId (see the HTTP page)
A common pattern is both: Storage as a fast cache for the current session, your DB as the durable record.
Example — returning‑visitor greeting¶
string userId = Player.GetUserId(playerId);
if (userId != "")
{
int visits = Storage.GetInt("visits_" + userId, 0) + 1;
Storage.SetInt("visits_" + userId, visits);
NPC.Notify("player_entered",
"{\"visit\": \"" + (visits == 1 ? "first" : "returning") + "\"}");
}
The NPC can now say "Hello there!" vs "Welcome back!" — without ever speaking a name. (Within‑session here; swap the counter to your DB to make it survive restarts.) Full version: the IdentityGreeter example.