Global store
The global store holds values shared by any number of entities: a faction's score, a world-puzzle flag, a bond between two players. Variables and lists give each holder its own copy.
- Addressed by a key like
mypack:bond/alice. A key without a namespace getsorigins-powerful-powers:, so"score"isorigins-powerful-powers:score. Keys use lowercase letters, digits and_ - . /. - Typed like variables:
int,long,float,double,booleanorString, or a list of one of those. A key's type is fixed when it's created, and later writes follow Java's assignment rules. - Saved with the world (
data/origins-powerful-powers_global.dat), like scoreboards. It's shared across dimensions and never resets itself. Put the dimension or the day in the key when you need that. - Server only. A client-checked condition such as a
hud_rendercondition counts globals as false and logs an error.
Ways in:
| Way | Use it for |
|---|---|
Global.* in code | any key, including keys built while the code runs |
global_variables power | fixed, declared fields that every holder uses by plain name |
modify_global and delete_global actions | JSON, like modify_variable |
/opp global | looking at and fixing the store as an operator |
In code
Global works everywhere code runs: execute, expression, modify_variable values, for_each, and ${…} in with_variables and /opp with.
| Method | Returns | |
|---|---|---|
Global.has(key) | boolean | whether the key exists |
Global.get(key) | the value | an error if the key is missing or is a list |
Global.set(key, value) | the value | creates the key with the value's type, or sets an existing one |
Global.delete(key) | boolean | removes the key. true if it existed |
Global.bind(key, self) / Global.bind(key, other) | ties the key to an entity. See cleanup | |
Global.lock(key, owner) / Global.unlock(key) | see locking | |
Global.list(key) | a list | an existing global list, used with list methods: Global.list(key).size() |
Global.list(key, type) | a list | the same, and creates an empty list of type ("int", "String", …) if it's missing |
set,delete,bind,lock,unlock,list(key, type)and list methods that change a list only work in actions (execute,for_each).- Keys are Strings, so they can be built from variables:
Global.set("mypack:kills/" + team, Global.get("mypack:kills/" + team) + 1). Globalis a reserved name.- Global lists hold at most 1024 elements. Adding past that is an error.
Example: count every zombie kill on the server.
{
"type": "origins:self_action_on_kill",
"target_condition": {
"type": "origins:entity_type",
"entity_type": "minecraft:zombie"
},
"entity_action": {
"type": "origins-powerful-powers:execute",
"code": "Global.set(\"mypack:zombie_kills\", Global.has(\"mypack:zombie_kills\") ? Global.get(\"mypack:zombie_kills\") + 1 : 1);"
},
"cooldown": 1
}Loops: for_each and for_each_read take a global list as their list:
{
"type": "origins-powerful-powers:for_each_read",
"list": "Global.list(\"mypack:members\")",
"action": {
"type": "origins:heal",
"amount": 1
}
}Global variables
origins-powerful-powers:global_variablespower type
Declares fields like variables, with one copy in the global store shared by every holder. Code on a holder uses them by plain name.
| Field | Type | Default | Description |
|---|---|---|---|
fields | String or array of Strings | required | Java field declarations: int faction_score = 0; boolean gate_open; |
lock | Boolean | false | When true, keys this power creates are locked to its namespace. |
- The key for field
namein powermypack:whateverismypack:name, in lowercase. Any power in themypacknamespace declaring the same name shares it.Global.get("mypack:name")reads it from anywhere. - The initial value is only used to create the key.
- If the key already exists with another type, using the field is an error.
- A name must be unique across the
variablesandglobal_variablespowers an entity holds. variable_barand client-side checks can't read global fields.
Example: a shared faction score. Every member has this power, and a member's kill adds to everyone's total.
{
"type": "origins-powerful-powers:global_variables",
"fields": "int faction_score = 0;"
}{
"type": "origins:self_action_on_kill",
"entity_action": {
"type": "origins-powerful-powers:execute",
"code": "faction_score += 1;"
},
"cooldown": 1
}Modify global
origins-powerful-powers:modify_globalentity action and bi-entity action
The JSON form of changing one global, like modify_variable.
| Field | Type | Default | Description |
|---|---|---|---|
key | String | required | The key. |
operation | String | "set" | set, add, subtract, multiply, divide, modulo, min, max, and, or, xor, shift_left, shift_right, unsigned_shift_right |
value | String | required | An expression, like "1" or "coins / 10". It can read variables and globals. |
bind | String | "none" | After the change, bind the key to self, other (bi-entity only), or both. |
setcreates a missing key. Any other operation needs the key to exist already.
Delete global
origins-powerful-powers:delete_globalentity action and bi-entity action
| Field | Type | Default | Description |
|---|---|---|---|
key | String | required | The key to remove. A missing key does nothing. |
Example: turn on a world flag the first time anyone enters the Nether.
{
"type": "origins:action_over_time",
"interval": 20,
"condition": {
"type": "origins:dimension",
"dimension": "minecraft:the_nether"
},
"entity_action": {
"type": "origins-powerful-powers:modify_global",
"key": "mypack:nether_opened",
"value": "true"
}
}Locking
By default any pack can change any key. Locking keeps several packs, or several copies of one origin, on the same server from changing each other's keys.
- A locked key has an owner: a namespace (
mypack) or a single power id (mypack:bond). - Only an entity that holds a power in that namespace, or that exact power, can
set,delete,bind, change list contents,lockorunlockthe key. Anything else gets an error naming the owner. - Anyone can read a locked key.
- Lock with
Global.lock(key, owner). The entity doing it must hold the owner.global_variableswith"lock": truelocks the keys it creates to its namespace. /opp globalcommands ignore locks.
Cleanup
Globals stay until something deletes them:
- Explicit delete:
Global.delete,delete_global, or/opp global delete. Binding.
Global.bind(key, self)(orbindonmodify_global) ties the key to an entity. A key can be bound to several entities, and it's deleted once all of them are gone:- a non-player is gone when it's killed or removed. Chunk unloading keeps it.
- a player is gone after being offline longer than the gamerule
oppPlayerExpiryDays(real days, default30,0= never). Death keeps them.
- Admin pruning:
/opp global prune, run by an operator.
Example: a bond between two players that disappears once both have been away for good. See the cookbook.
/opp global
opp global get <key>
opp global set <key> <value>
opp global delete <key>
opp global list [<prefix>]
opp global prune <prefix>
opp global prune --older-than <ticks>
opp global lock <key> <owner>
opp global unlock <key>| Subcommand | What it does | Result |
|---|---|---|
get | prints the value | the value if it's a whole number, 1/0 for booleans, the size for a list, and 1 for anything else |
set | sets or creates a key. The value is a Java literal: 5, 2.5, 10L, true, "text" | the new value if it's a number, and 1 for anything else |
delete | removes a key | 1 |
list | every key, or those starting with <prefix>, with type, value, how long since it was written, its lock owner and how many entities it's bound to | the number listed |
prune <prefix> | deletes every key starting with <prefix> | how many were deleted |
prune --older-than <ticks> | deletes every key last written at least that many ticks ago | how many were deleted |
lock / unlock | locks a key to an owner, or removes the lock | 1 |
- Commands need permission level 2 and ignore locks.
- A key or prefix without a namespace gets
origins-powerful-powers:.