Skip to main content

Easel is now an expression language! (March 2026 update)

· 5 min read
raysplaceinspace
Creator of Easel

Match blocks, statements as expressions, itch.io export and more! Keep reading to learn what is new with Easel this month.

info

Easel is a 2D webgame engine backed by an exceptionally productive programming language. Intrigued? Visit our home page to learn more.

Exporting to itch.io or other platforms

Game developers often publish their games to itch.io or other platforms to share their games with a wider audience. With a click, you can now generate a zip file which you can upload to itch.io or any other website. The zip file will embed your hosted game on Easel using an HTML iframe. See Exporting to learn more.

Expressions Everywhere!

Statement Expressions

Every control flow statement can now be used as an expression. The last value in the block determines the result:

let x =
if happy && youKnowIt {
Clap { hands }
123
} else {
0
}

Within a loop, the break statement determines the resulting value:

let hit = loop {
let that = await BeforeCollide
if that.Category.Overlaps(Category:Projectile) {
break that
}
}

See Control Flow to learn more.

Multiple Statements in Parentheses

Sometimes a calculation involves many steps. You can now include multiple statements inside parentheses (), which means you can split your calculation into multiple lines and use intermediate variables to make it easier to read. The last value in the parentheses becomes the resulting value:

let x = (
let a = 123
let b = 456
a + b
)

Any statement is valid inside the parentheses, so you can use control flow statements, call functions, create behaviors, etc:

let x = (
let a = 123
let b = 456
if happy && youKnowIt {
Spawn unit { HappyDancer }
} else {
on Paint {
Spark(color=#ff0000)
}
}
a + b
)

See Block Scopes to learn more.

Match Blocks

Easel now has match blocks! Match blocks are a concise way to choose a code path using pattern matching:

let x = "Pineapple"
match x {
123 => Print { "It's 123!" },
"Banana" => {
Print { "It's a banana!" }
Spawn unit { BananaMonster }
},
IsString => Print { "It's a string!" },
[x, y, z] => Print { "It's a array of length 3!" },
{ type = $apple } => Print { "It's a Map of type apple!" },
_ => Print { "It's something else!" },
}

Match blocks can return values and can be used in expressions:

let scoreChange = match x {
$apple => 100,
$banana => 200,
$pineapple => 100,
}

See Match Blocks to learn more.

Multiple return values from callbacks

Previously, callbacks could only ever return 1 value. Now they can return as many or as few as you want:

let giveMeSomeValues = || {
return 123, 456
}
let x, y = giveMeSomeValues()

Under the hood

The Easel compiler is a very precise machine. For every line of code, it needs to perform accurate accounting of all the operands and their runtime memory layout. Even the tiniest off-by-one error would crash your game. This is one of the reasons the language was kept simple until now, not allowing for statements and expressions to mix, and limiting callbacks to returning a single value.

Changing Easel into an expression language was a very delicate undertaking, but they say if you did everything right, it should seem like you did nothing at all. Enjoy the new syntax and features, we hope you never need to give a thought to the complexity under the hood that made this possible!

Accumulator Operators

You can now modify accumulators directly using the =, += and -= operators, which is much more intuitive:

owner.NumGamesPlayed(overwrite=123) // old way
owner.NumGamesPlayed = 123 // new way

owner.NumGamesPlayed(overwrite=123, showOnLeaderboard=true) // old way
owner.NumGamesPlayed(showOnLeaderboard=true) = 123 // new way

owner.NumGamesPlayed(delta=1) // old way
owner.NumGamesPlayed += 1 // new way

owner.NumGamesPlayed(delta=1, showOnLeaderboard=true) // old way
owner.NumGamesPlayed(showOnLeaderboard=true) += 1 // new way

The compiler automatically interprets += or -= as a delta modification, which means it will merge the change correctly in the event that other deltas are happening at the same time. This is now the standard way to update accumulators, but the old way with delta and overwrite parameters will still continue to work. See Accumulators to learn more.

The above syntax is only possible because you can now override the += and -= operators. If you want to get fancy and use it in your own code, see Set Functions to learn how to do this.

On a related note, Easel now has a special codepath that makes it faster when using += with Strings or Arrays because it can now reuse the same allocation.

Want 50 MB of free storage forever?

Easel now has a gift code system: easel.games/Redeem

Join the Easel discord, find the Welcome channel, and in there you'll find a gift code for 50 MB of free storage that you can redeem as a thank you for being an early supporter of Easel.

Using this new gift code system, we also are now able to giveaway 12-month subscriptions to Easel+ for promotional purposes. Are you running a game jam and looking for prize sponsors? Are you an influencer with an established audience, looking to either test Easel or do some giveaways? Get in touch with us if you are interested.