Origins: Powerful Powers
» VariablesPage 8 of 17

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.

IdKindWhat it does
variablespower typedeclares variables
variable_barpower typelinks one number variable to Origins' resource system and a HUD bar
executeentity and bi-entity actionruns code that changes variables
modify_variableentity and bi-entity actionone change, written as JSON like change_resource
expressionentity and bi-entity conditionchecks 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:

json
{
  "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:

json
{
  "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:

json
{
  "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:

json
{
  "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.

FieldTypeDefaultDescription
fieldsString or array of stringsrequiredJava field declarations, like int mana = 100, maxMana = mana;
java
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, index and size (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 a String starts 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, so int x = 1.5; is a load error. Write int 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 fields in a pack update: variables that still exist keep their saved values. A number variable whose type changed has its value cast, for example from int to double. Anything else resets to its initializer.
  • Names must be unique per entity across all the variables and list powers it holds. If two powers declare the same name, code that uses it fails with variable 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.

FieldTypeDefaultDescription
variableStringrequiredName of an int, long, float or double variable
minIntegerrequiredThe value at which the bar is drawn empty
maxIntegerrequiredThe value at which the bar is drawn full
hud_renderHUD renderrequiredHow the bar looks, as for origins:resource

What works through the bar's id:

  • The origins:resource condition reads the variable.
  • origins:change_resource and origins:modify_resource write the variable.
  • The HUD bar shows it.
  • The resource field 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 long or double beyond the int range reads as Integer.MAX_VALUE or MIN_VALUE.
  • Decimals are cut off, so a double of 7.9 reads as 7.

Example: use Origins' own actions on a variable.

json
{
  "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.

FieldTypeDefaultDescription
codeString or array of stringsrequiredStatements, each ending in ;
json
{
  "type": "origins-powerful-powers:execute",
  "code": "mana -= 30; casting = true; mode = \"fire\";"
}
  • A statement must be an assignment (=, +=, …), a ++/--, or a method call like history.add(5). A bare expression such as mana + 5; is an error, as in Java.
  • There are no if statements, loops or local variables. Use ?: for choices:

    java
    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.

FieldTypeDefaultDescription
variableStringrequiredA variable name. In the bi-entity version also self.name or other.name.
operationString"add"See the table below
valueNumber, Boolean or StringrequiredA 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.
operationSame as the Java statement
setx = value
addx += value (joins Strings too)
subtract / multiply / divide / modulox -= value / x *= value / x /= value / x %= value
min / maxx = Math.min(x, value) / x = Math.max(x, value)
and / or / xorx &= value / x |= value / x ^= value. On a boolean, xor with true toggles it.
shift_left / shift_right / unsigned_shift_rightx <<= value / x >>= value / x >>>= value
json
{
  "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;):

json
{
  "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:

  • set only widens, so set with 1.5 on an int is an error, as with =.
  • Every other operation, including min and max, casts the result back to the variable's type, like Java's compound assignment. max with 9.9 on an int gives 9.

Expression

origins-powerful-powers:expressionentity condition and bi-entity condition

True when a Java expression is true.

FieldTypeDefaultDescription
expressionString or array of stringsrequiredOne expression that produces a boolean
json
{
  "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 false and the error is logged.
  • A condition Origins checks on the client, like a hud_render condition, 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.name is the actor: Origins' first entity, usually the power holder.
  • other.name is the target: Origins' second entity.
  • A bare name means self.name.

Example: drain 10 mana from whoever you hit.

json
{
  "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 as false.
  • Types are checked when code runs. mana = "full"; loads and fails the first time it runs.