Skip to content

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.