MCCompiled Wiki 1.19 Help

Values

Values are the backbone of all runtime logic. Values are just scoreboard objectives under the hood, but their representation in MCCompiled is much different. There are a couple of key differences about values:

  1. Values act identical to variables in other programming languages.

    • Regular math operations: a + b

    • Compound assignment: a += b

    • Declaration: define int a

  2. Values can have types.

  3. Values have no length restrictions on names.

  4. Values are formatted when displayed to a player.

Defining Values

Defining a value is done using the syntax define [type] [name]. The most common type is int, short for integer. An integer can be any whole number between -2,147,483,648 and 2,147,483,647. It's versatile, and is the closest to a Minecraft scoreboard objective.

define int score

Assigning Values

To assign something to a value, use the assignment = symbol. By default, the assignment always happens to the executing entity, @s. If you want to change which entity gets the value assigned, see clarification.

score = 0

Values can be assigned to other values as well; notice that the difference between scoreboard operation and scoreboard set is abstracted away entirely.

define bonus bonus = 10 score = bonus

Merging Define and Assignment (and type omission)

If you wish to combine an assignment and a definition into one line, you can do that! Specify the assignment just after the define command is completed. When merging definition/assignment, you can omit the type if you want, as it will be inferred from the value you're assigning.

The following two examples have identical behavior. Note that in the second example, the type int is omitted because the compiler can tell what type 'number' should be based on the input 21.

define int example example = 21
define example = 21

Initializing Values

If you're familiar with scoreboard objectives in Minecraft, you may know that score-holders may not have any score at all. Not zero, but nothing at all. You can use the init command to initialize a value so that if a score-holder doesn't hold it, the value will be set to the default (usually 0).

init example

Simple Math

All the math operations in MCCompiled are listed here:

No Compound Assignment

Adds the left and right values.


define a = 10 define b = 4 define result ‎ result = a + b assert result == 14

Subtracts the right value from the left value.


define a = 10 define b = 4 define result ‎ result = a - b assert result == 6

Multiplies the left and right values.


define a = 10 define b = 4 define result ‎ result = a * b assert result == 40

Divides the left value by the right value.


define a = 10 define b = 4 define result ‎ result = a / b assert result == 2

Divides the left value by the right value, but returns the remainder.


define a = 10 define b = 4 define result ‎ result = a % b assert result == 2

Compound Assignment

When you need the left value to store the result of the operation, you can use what is called compound assignment. Compound assignment is specified by using an equals-sign = after the operator you wish to use.

With Compound Assignment

Adds the right value to the left value.


define a = 10 define b = 4 ‎ a += b assert a == 14

Subtracts the right value from the left value.


define a = 10 define b = 4 ‎ a -= b assert a == 6

Multiplies the left value with the right value.


define a = 10 define b = 4 ‎ a *= b assert a == 40

Divides the left value by the right value.


define a = 10 define b = 4 ‎ a /= b assert a == 2

Divides the left value by the right value, but sets the left value to the remainder.


define a = 10 define b = 4 ‎ a %= b assert a == 2

Complex Statements

MCCompiled fully supports the use of operations inline, as well as PEMDAS ordering. Using inline operations keeps code size way down and communicates its purpose much more clearly than separating operations per-line.

The order that MCCompiled evaluates complex statements mostly conforms to PEMDAS along with some extra steps added for the other features in the language:

  1. Evaluate everything inside parentheses recursively. () []

  2. Run any dereferences. $

  3. Run function calls. name(...)

  4. Apply any indexers. [...]

  5. Evaluate multiplication/division operations. a * b

  6. Evaluate addition/subtraction operations. a - b

The following example shows the use of a complex statement to calculate the amount of score remaining until a player reaches the next level of a theoretical game:

define int untilNextLevel define int betweenLevels = 1000 untilNextLevel = ((score / betweenLevels + 1) * betweenLevels) - score

Clarification

By default, values point to @s, or the executing entity. This default works for a majority of cases; however, when you need to change who the value points to, clarifiers are the answer.

A clarifier is defined as a selector encased in square brackets (indexers). For example, a clarifier pointing to all cows would look like [@e[type=cow]], and one pointing to the nearest non-self player would look like [@p[rm=0.1]].

The following example shows adding one to losses for all players with the tag 'touched'

losses[@a[tag=touched]] += 1

Other ways of doing the above example

Miscellaneous Operations

Some operations don't follow the rules of the five main math operations, those of which are listed here. None of the operations listed here are mentioned as assignment or not, they just exist as-is.

Miscellaneous Operations

Swaps the left and right values.


define a = true define b = false ‎ a >< b assert a == false assert b == true

Attributes

Attributes can change the way values behave. Any number of attributes can be applied pretty much anywhere in the definition; before or after the type. See attributes for all attributes across the language.

global

Makes the attached value global, meaning that the value's scoreboard objectives are always tied to the global fakeplayer _.


Any attempts to use clarifiers on the value will result in a compile-time error. The value is guaranteed to never be attached to an entity.

Examples & Use-case

Making values global is useful for anything that applies to the world, and not a specific player/entity. If you were designing a mini-game, for example, you would want the game-related code to be global, along with the compile-time guarantees that it will remain global.

define global int playersPassed define global time timeRemaining ‎ function display { globalprint "PASSED: {playersPassed} | TIME LEFT: {timeRemaining}" }
bind

Binds the value to a given MoLang query. Requires one parameter, being a string that contains the query to use. The current list of supported bindings is here.


Most bindings come with pre-defined entities they attach to, but in cases where they don't, the entities can be manually specified by adding more string parameters to the end of the function, i.e., bind("query.is_sleeping", "fox") to bind specifically to foxes.

Examples & Use-case

Binding replaces all cases where animation controllers were needed to access extra information about entities.

define bool bind("query.is_sleeping") isSleeping ‎ if not isSleeping { summon lightning_bolt print @a "{@s} IS RUINING THE SMP!!!" }
Last modified: 28 October 2024