Variables
Typed variables you declare in a power and work with using Java expressions. Every entity holding the power gets its own copy, like instances of a Java class. Values are saved with the entity's powers.
| Id | Kind | What it does |
|---|---|---|
variables | power type | declares variables |
variable_bar | power type | links one number variable to Origins' resource system and a HUD bar |
execute | entity and bi-entity action | runs code that changes variables |
modify_variable | entity and bi-entity action | one change, written as JSON like change_resource |
expression | entity and bi-entity condition | checks variables |
Related pages:
- Page 9 puts variables into any Origins field (
with_variables) and any command (/opp with), and reads scoreboards in code. - Page 10 is the full language reference.
- Page 11 covers lists and loops.
A complete example: mana
data/mypack/powers/mana.json declares the variables:
{
"type": "origins-powerful-powers:variables",
"fields": [
"int mana = 100;",
"int maxMana = 100;",
"boolean casting; // true while a spell is being cast"
]
}data/mypack/powers/mana_regen.json regenerates 5 mana per second:
{
"type": "origins:action_over_time",
"interval": 20,
"entity_action": {
"type": "origins-powerful-powers:execute",
"code": "mana = Math.min(mana + 5, maxMana);"
}
}data/mypack/powers/fireball.json costs 30 mana, and only works when you have enough:
{
"type": "origins:active_self",
"condition": {
"type": "origins-powerful-powers:expression",
"expression": "mana >= 30 && !casting"
},
"entity_action": {
"type": "origins:and",
"actions": [
{
"type": "origins-powerful-powers:execute",
"code": "mana -= 30;"
},
{
"type": "origins:execute_command",
"command": "summon fireball ~ ~1.5 ~"
}
]
},
"cooldown": 20
}data/mypack/powers/mana_bar.json shows mana on the HUD:
{
"type": "origins-powerful-powers:variable_bar",
"variable": "mana",
"min": 0,
"max": 100,
"hud_render": {
"should_render": true,
"bar_index": 1
}
}One string or an array of lines. fields, code and expression each take one string or an array of strings. Each array element is one line of code, and a // comment ends at the end of its element. Error messages say line N, meaning the Nth element. Statements need their ;, as in Java.
Variables
origins-powerful-powers:variablespower type
Declares variables with Java field declarations.
| Field | Type | Default | Description |
|---|---|---|---|
fields | String or array of strings | required | Java field declarations, like int mana = 100, maxMana = mana; |
int mana = 100, maxMana = mana;
double speedBonus = 0.1 * 3;
boolean casting;
String mode = "idle";
long lastCast;- Types:
int,long,float,double,boolean,String. Lists are a separate power (page 11). - Reserved names:
value,indexandsize(used by loops),Scoreboard, and Java keywords can't be variable names. - Without an initializer, a variable starts at Java's default (
0,0.0,false), and aStringstarts at"". - Initializers run once, when the pack loads. They can use literals,
Math.*and the other built-ins, and variables declared earlier in the same power. Scores are unavailable. Java's assignment rules apply, soint x = 1.5;is a load error. Writeint x = (int) 1.5;. - Each holder has their own values, saved with the entity's powers. They survive relogs and death. Losing the power discards them, and getting it again starts from the initializers.
- Changing
fieldsin a pack update: variables that still exist keep their saved values. A number variable whose type changed has its value cast, for example frominttodouble. Anything else resets to its initializer. - Names must be unique per entity across all the
variablesandlistpowers it holds. If two powers declare the same name, code that uses it fails withvariable mana is declared by both mypack:a and mypack:b. This is checked when the name is used.
Variable bar
origins-powerful-powers:variable_barpower type
Links one number variable to Origins' resource system. A variable bar is the same kind of power as origins:resource, so everything that works on a resource works on it. Use the bar's power id where Origins asks for a resource.
| Field | Type | Default | Description |
|---|---|---|---|
variable | String | required | Name of an int, long, float or double variable |
min | Integer | required | The value at which the bar is drawn empty |
max | Integer | required | The value at which the bar is drawn full |
hud_render | HUD render | required | How the bar looks, as for origins:resource |
What works through the bar's id:
- The
origins:resourcecondition reads the variable. origins:change_resourceandorigins:modify_resourcewrite the variable.- The HUD bar shows it.
- The
resourcefield of an Origins modifier reads it (page 9).
Values are unclamped. min and max only set how full the bar looks. With max: 100 and mana = 150, the bar is drawn full, origins:resource sees 150, and change_resource +1 makes it 151. To limit it, clamp in code: mana = Math.min(mana, maxMana);.
- A
longordoublebeyond the int range reads asInteger.MAX_VALUEorMIN_VALUE. - Decimals are cut off, so a
doubleof 7.9 reads as 7.
Example: use Origins' own actions on a variable.
{
"type": "origins:active_self",
"key": {
"key": "key.origins.secondary_active"
},
"entity_action": {
"type": "origins:change_resource",
"resource": "mypack:mana_bar",
"change": 25
}
}mypack:mana_bar is the variable bar from the example above, so this adds 25 to mana.
Execute
origins-powerful-powers:executeentity action and bi-entity action
Runs statements that change variables.
| Field | Type | Default | Description |
|---|---|---|---|
code | String or array of strings | required | Statements, each ending in ; |
{
"type": "origins-powerful-powers:execute",
"code": "mana -= 30; casting = true; mode = \"fire\";"
}- A statement must be an assignment (
=,+=, …), a++/--, or a method call likehistory.add(5). A bare expression such asmana + 5;is an error, as in Java. There are no
ifstatements, loops or local variables. Use?:for choices:mana = casting ? mana - 1 : Math.min(mana + 2, maxMana);- Statements run in order. If one fails while running, the rest are skipped and earlier changes stay.
- Changed values are synced to the client once, after the code finishes.
Modify variable
origins-powerful-powers:modify_variableentity action and bi-entity action
One change to one variable, written as JSON in the style of origins:change_resource.
| Field | Type | Default | Description |
|---|---|---|---|
variable | String | required | A variable name. In the bi-entity version also self.name or other.name. |
operation | String | "add" | See the table below |
value | Number, Boolean or String | required | A JSON number or boolean (10, 0.5, true), or an expression as a string or array of lines ("coins / 100"). A String value needs inner quotes: "\"gold\"". The expression is read-only. |
operation | Same as the Java statement |
|---|---|
set | x = value |
add | x += value (joins Strings too) |
subtract / multiply / divide / modulo | x -= value / x *= value / x /= value / x %= value |
min / max | x = Math.min(x, value) / x = Math.max(x, value) |
and / or / xor | x &= value / x |= value / x ^= value. On a boolean, xor with true toggles it. |
shift_left / shift_right / unsigned_shift_right | x <<= value / x >>= value / x >>>= value |
{
"type": "origins-powerful-powers:modify_variable",
"variable": "coins",
"operation": "add",
"value": 10
}
{
"type": "origins-powerful-powers:modify_variable",
"variable": "frozen",
"operation": "xor",
"value": true
}These are coins += 10; and frozen ^= true;.
In the bi-entity version, other. reaches the target. This gives whoever you hit 1% of your coins (other.coins += coins / 100;):
{
"type": "origins:action_on_hit",
"bientity_action": {
"type": "origins-powerful-powers:modify_variable",
"variable": "other.coins",
"operation": "add",
"value": "coins / 100"
}
}The types follow Java:
setonly widens, sosetwith1.5on anintis an error, as with=.- Every other operation, including
minandmax, casts the result back to the variable's type, like Java's compound assignment.maxwith9.9on anintgives9.
Expression
origins-powerful-powers:expressionentity condition and bi-entity condition
True when a Java expression is true.
| Field | Type | Default | Description |
|---|---|---|---|
expression | String or array of strings | required | One expression that produces a boolean |
{
"type": "origins-powerful-powers:expression",
"expression": "mana >= 30 && mode.equals(\"fire\")"
}- Conditions are read-only.
=,+=,++and list changes are load errors here. - If the expression fails while running (an unknown variable, a missing score), the condition is
falseand the error is logged. - A condition Origins checks on the client, like a
hud_rendercondition, sees the values last synced from the server.
Bi-entity versions
execute, modify_variable and expression also work anywhere a bi-entity action or condition goes, such as origins:action_on_hit, origins:target_action or a bientity_condition.
self.nameis the actor: Origins' first entity, usually the power holder.other.nameis the target: Origins' second entity.- A bare
namemeansself.name.
Example: drain 10 mana from whoever you hit.
{
"type": "origins:action_on_hit",
"bientity_action": {
"type": "origins-powerful-powers:execute",
"code": "other.mana -= 10; mana = Math.min(mana + 10, maxMana);"
}
}Both entities must hold a variables power that declares the names used. Otherwise the code stops with a "cannot find variable" error in the log. Add a bientity_condition that checks the target has the power.
Errors
- Load errors fail that power when the pack loads. The log shows the column and nearby text, such as
expected ';' but found 'casting' (at column 16, near "casting = true"). - Errors while running are logged once per distinct message, prefixed
[variables], with the code that caused them. A failing action stops at that statement. A failing condition counts asfalse. - Types are checked when code runs.
mana = "full";loads and fails the first time it runs.