Hi everyone, I've been making Easel for nearly 4 years now. It's a beginner-friendly programming language that features automatic multiplayer, which means teenagers can make games they can actually play with each other. This is the update for this month :)
A beginner-friendly programming language for 2D games where multiplayer is automatic. Intended to be an engaging way for teenagers to learn to code by making games they can play with their friends. Like a blend of Scratch and Roblox. I've been working on this for 3 years!
A beginner-friendly programming language for 2D games where multiplayer is automatic. Intended to be an engaging way for teenagers to learn to code by making games they can play with their friends. Like a blend of Scratch and Roblox. I've been working on this for 3 years!
If you're asking why Easel is a new programming language and not an existing one, the biggest reason is that building our own programming language meant we could build multiplayer into the fabric of the programming language, making multiplayer 100% automatic. There is a big difference between 99% automatic and 100% automatic. When it's 100% automatic, you really can put it in the hands of a beginner programmer on their first day of coding and they can actually make a multiplayer game. Teenagers these days spend a lot of time playing online multiplayer games and we believe that give them a tool that lets them make them themselves is an attractive enough proposition for them to choose Easel over other choices.
I'm working on a beginner-friendly online programming language for teenagers who want to learn to code. I think there is not a clear enough winner for what teenagers should do after they learn Scratch so I am trying to make it.
I saw this shared recently. The site presents nicely, and I agree there's a gap there. As a university professor, the story of my students' learning has pretty much been; Scratch, some Python, and then they pick up whatever early-college curriculum is. There's a strong preference for scripting languages like Python and JavaScript.
When you say "what teenagers should do after learning Scratch," what do you mean exactly? Should do to what end? How would Easel present as "the clear thing" they should do? I suppose Scratch wasn't really chosen by these young people; it is obviously simple, and has the prestige of MIT. Schools followed suit.
You're in a different situation, where you have to meet this market in the open. When I visit your site, I am met with code. It's not apparently simple, and a beginner wouldn't be able to distinguish it from any other games programming framework. I think it's actually scarier-seeming to a beginner than something like Godot's scene editor, where you can just drag images from your disk into a prototype-view of your game-scene.
I hope my plainness in stating this isn't taken as an insult. You've got so much work there, and the site is impressive. I also care about this topic, age-range and the learning process, so I'm trying to be helpful with my perspective.
Thank you and I am pleased whenever someone engages and gives me their honest thoughts, it is always helpful.
Maybe I'll rewind a bit, and I'm sorry if this is a long post!
I've just had a teenager who finished making a Chess game in Easel after about a month's work, his most advanced programming project so far. This teenager started in Scratch, has done some Python, but the language they have spent the most time in has been Easel. I've also had a couple of teenagers who have said things like "I suck at coding" and yet make spend months making these quite sophisticated Easel projects full of coding. These two teenagers also did a bit of Scratch but also were lost and disengaged when it came to Python. This mirrors what I've seen in Code Clubs as well, where teenagers just lost interest when shown Python.
Eventually, if someone is going to learn to code for real, they must make the transition from a visual programming language to a text-based programming language, and I know that I have seen teenagers get lost attempting to cross that gap. There are teenagers who obviously have had no trouble with this and that's great, they should go straight to Python or JavaScript or whatever is their heart's desire!
The difference between Scratch and most other programming languages is more than just visual vs text-based. Scratch is actually this cool concurrent, asynchronous, event-driven programming language. This makes it easy to write things like "wait 0.3 seconds" then "move 2 steps to the right". Most other game engines, including PyGame and Godot, instead use a frame-by-frame model. This means you often have to code things as state machines, where you pick up and put down state so that an entity can remember what it was doing next frame. That example of "wait 0.3 seconds" then "move 2 steps to the right" would require the control flow to jump up and down the codebase between state and logic, which means the shape of the code no longer mirrors the step-by-step of what it is actually doing. I think Scratch is successful not just because of its visual coding, but because its programming model allows for step-by-step logic to look like step-by-step code. There's no reason a text-based programming language couldn't also have this property.
Easel is concurrent, asynchronous, event-driven, like Scratch, which is why both Easel and Scratch code can be written in this sequential step-by-step way that you can't easily achieve in other programming languages.
Why can't you just write `await sleep(0.3s)` in other programming languages? Their issue is you can't cancel an `await`, which means it is easy for an asynchronous task to outlive its entity and so they are not safe beginner-level constructs. Scratch solves this implicitly because all scripts are part of a sprite, and when your sprite is removed, all its concurrent scripts stop. It's so intuitive that it doesn't really need to be taught. Easel has a similar thing but in text-based form - it is a hierarchical programming language and everything inside of an entity's block`{ }` gets auto-cleaned up when it dies, including all asynchronous tasks belonging to that entity. I think that's why in Easel, I've seen teenagers spinning up hundreds of asynchronous threads all the time without any problems.
All of this is to say that Easel is like halfway between Scratch and Python. It keeps a lot of the intuitive parts of Scratch's cool programming model, but in text form. My hope (and we have seen this already a few times) is that it can help more teenagers cross the gap from visual coding to "grown up" text-based programming languages.
The reason the code sample is at the top is actually because I saw a teenager talk aloud as they were reading that code and understanding it in real-time. It was super cool because that's it, that's what I've been trying to do - make a text-based programming language that is legible to beginners and not convoluted. And I'm trying to figure out whether it is possible to replicate that moment over and over again with new teenagers.
There is a lot more to it. Easel adds a lot of other stuff like a physics engine and automatic multiplayer. But this post is getting long so I will stop there. I really appreciate the thoughts. I am definitely going to be thinking about how that homepage is presenting itself and I think it is fair what you say that it doesn't look simple, and doesn't look different to any other game engine. That is very good feedback!
Interesting. I admit I have to put my prejudice away to accept that in this case a programming model focused on events is probably good for the reasons you're stating, since those sorts of instructions you want to support, because those kids got their start on Scratch. Well you're definitely doing the right work in just making appealing games with it. Learners want to feel like whatever they want is possible, even if the "whatever" isn't yet well-formed. Your bee-line game is a really fun toy.
Indeed. But ... do not confuse your model with reality.
There's a folk story - I don't remember where I read it - about a genealogy database that made it impossible to e.g. have someone be both the father and the grandfather of the same person. Which worked well until they had to put in details about a person who had fathered a child with his own daughter - and was thus both the father and the grandfather of that child. (Sad as it might be, it is something that can, in fact, happen in reality, and unfortunately does).
While that was probably just database constraints of some sort which could easily be relaxed, and not strictly "unrepresentable" like in the example in the article - it is easy to paint yourself into a corner by making a possible state of the world, which your mental model dims impossible, unrepresentable.
Your example doesn’t validate your point. That’s a valid state made unrepresentable, not an invalid state made unrepresentable. Your example simply demonstrates a poorly architected set of constraints.
The critical thing with state and constraints is knowing at what level the constraint should be. This is what trips up most people, especially when designing relational database schemas.
Any assumption made in order to ship a product on time will eventually be found to have been incorrect and will cause 10x the cost that it would have taken to properly design the thing in the first place. The problem is that if you do that proper design you never survive to the stage where have that problem.
I think the solution to that is to continuously refactor, and to spell out very clearly what your assumptions are when you are writing the code (which is an excellent use for comments).
Continuous refactoring is much easier with well constrained data/type schemas. There are fewer edge cases to consider, which means any refactoring or data migration processes are simpler.
The trick is to make the schema represent what you need - right now - and no more. Which is the point of the “Make your invalid states unrepresentable” comment.
I do see how it does, in a way. That something the designer thought is "invalid state" turns out a valid and possible state in real world. In terms or UI/UX, it's the uncomfortable long pause before something happens and screen renders (lack of feedback, feeling that system hangs). Or, content flicker when window is resized or dragged. Just because somebody thought "oh, this clearly is invalid state and can be ignored".
The real world and user experience requirements have a way of intruding on these underspecified models of how the world "should" be.
That’s still a poorly designed system. For UI there should be a ‘view model’ that augments your model, that view model should be able to represent every state your UI can be in, which includes any ‘intermediate’ states. If you don’t do this with a concrete and well constrained model then you’re still doing it, but with arbitrary UI logic, and other ad-hoc state that is much harder to understand and manage.
Ultimately you need to make your own pragmatic decisions about where you think that state should be and how it should be managed. But the ad-hoc approach is more open to inconsistencies and therefore bugs.
Hi, can you give an example? Not sure I understand what you're getting at there.
(My tuppence: "the map is not the territory", "untruths programmers believe about...", "Those drawn with a very fine camel's hair brush", etc etc.
All models are wrong, and that's inevitable/fine, as long as the model can be altered without pain. Focus on ease of improving the model (eg can we do rollbacks?) is more valuable than getting the model "right").
> Hi, can you give an example? Not sure I understand what you're getting at there.
An utterly trivial example is constraining the day-field in a date structure. If your constraint is at the level of the field then it can’t make a decision as to whether 31 is a good day-value or not, but if the constraint is at the record-structure level then it can use the month-value in its predicate and that allows us to constrain the data correctly.
When it comes to schema design it always helps to think about how to ‘step up’ to see if there’s a way of representing a constraint that seems impossible at ‘smaller’ schema units.
I made this little game in 1 day for Ludum Dare 58, and have taken a bit of time to polish it for Hacker News. I am fascinated by the way the multi-vehicle travelling salesman problem seems so simple on the surface, but actually has an almost infinite number of solutions. I thought it might be interesting to put this problem into a game so you can feel the tension between the simplicity and complexity for yourself.
reply