Normally when coding multiplayer you have to worry about following "the rules of multiplayer" like avoiding non-determinism, or not modifying entities your client has no authority over, but all that is just way too hard for someone who just wants to get straight into making games. So my idea was that if we put multiplayer into the fabric of the programming language, below all of your code, we can make the entire language multiplayer-safe. In Easel the entire world is hermetically sealed - there is nothing you can do to break multiplayer, which means it suits someone who just wants to make games and not learn all about networking. I've had people make multiplayer games on their first day of coding with Easel because you basically cannot go wrong.
There were so many other interesting things that went into this project. It's written in Rust and compiled to WebAssembly because I think that the zero-download nature of the web is a better way of getting many people together into multiplayer games. The networking is done by relaying peer-to-peer connections through Cloudflare Calls, which means Cloudflare collates the messages and reduces the bandwidth requirements for the clients so games can have more players.
I also took inspiration from my experience React when creating this language, here's how you would make a ship change color from green to red as it loses health:
`with Health { ImageSprite(@ship.svg, color=(Health / MaxHealth).BlendHue(#ff6600, #66ff00)) }`
There is a lot of hidden magic that makes the code snippet above work - it creates a async coroutine that loops each time Health sends a signal, and the ImageSprite has an implicit ID assigned by the compiler so it knows which one to update each time around the loop. All of this lets you work at a higher level of abstraction and, in my opinion, make code that is easier to understand.
Speaking of async coroutines, my belief is that they don't get used enough in other game engines because their lifetimes are not tied to anything - you have this danger where they can outlive their entities and crash your game. In Easel each async task lives and dies with its entity, which is why we call them behaviors. Clear lifetime semantics makes it safe to use async tasks everywhere in Easel, which is why Easel games often consist of thousands of concurrently-executing behaviors. In my opinion, this untangles your code and makes it easier to understand.
That's just the beginning, there is even more to talk about, it has been a long journey these past 3 years, but I will stop there for now! I hope that, even for those people who don't care about the multiplayer capabilities of Easel, they just find it an interesting proposal of how a next-generation game programming language could work.
The Editor runs in your web browser and is free to play around with, so I would love to see more people try out making some games! Click the "Try it out" button to open the Sample Project and see if you can change the code to achieve the suggested tasks listed in the README.
But it's not a total silver bullet from a UX perspective when rollbacks happen.
Showing a player dying and then come back to life and actually you're dead will absolutely happen. It's very weird if they were ragdolling.
If players don't have high inertia, like a platformer, they'll teleport around the place as you get the information that actually they aren't falling they jumped 100ms ago.
This is all fixable, but requires first class confirmation (i.e has the player you shot been dead longer than the max rollback window), and hand tuned interpolation on critical entities.
Luckily, I'm sure it's possible to add them to this engine.
I'm curious as to why a custom programming language was designed if the system uses WASM anyway - which you can make deterministic.
I wrote my system in C# and it worked great if you Followed The Rules (eg you must use immutable data structures). But WASM would have been a big step up.
Why did I make a custom programming language? Well, making multiplayer automatic was only half of my mission when creating Easel.
It's a bit of a long story but the modding tools for my previous game were surprisingly successful. It became the first experience of any form of coding for a lot of people. The tool used JSON, which might sound primitive, but actually if you look past the JSON what it was really doing was defining a hierarchical declarative language for behaviour. There's something magic about that shape which allowed first-time coders to tinker without much help or documentation. (I have many theories as to why, one of them is that the hierarchy eliminates a lot of indirection that you might see in normal game programming, which means you can just kind of look at it and figure it out without jumping around. Everything is direct and in-place.)
The thing that irked me for years was, the limitations of that modding language limited not just what could be made, but what people could learn. I kept wondering what would happen if people were presented with a programming language in the same shape, but with unlimited power. Could it lay down a path for non-coders to follow all the way until they became expert coders, almost accidentally? Easel is my attempt to marry that magical hierarchical-declarative style with imperative programming in order to make a powerful language that still is extremely accessible.
I hope that, the accessibility and power of the programming language, combined with its ability to make multiplayer games automatically, will make it a super engaging choice for a first programming language for many people. I would love to see it used in schools to teach programming.
Experienced developers are probably better off targeting WASM with Rust, but an easy on ramp to programming is definitely something that can justify a new language.