Hacker Newsnew | past | comments | ask | show | jobs | submit | BSTRhino's commentslogin

https://easel.games

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!


That sounds awesome, going to try in morning :)

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.

https://easel.games

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.


Make your invalid states unrepresentable


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.


> at what level the constraint should be

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 get it - thanks.


That sounds like this (in)famous stackowerflow question: https://stackoverflow.com/a/6198257


Wonder how old is this advice. Must be at least 20 years?


What a neat idea!


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.


I'm making a beginner-friendly 2D game programming language for online games. This month I added stencils, which limit rendering to particular shapes, and can be used for scene transitions but also some other cool effects like fog-of-war. One day I hope to see thousands of teenagers learning to code with Easel!


How are you currently retrieving feedback on the language design? Have you worked with teenagers and parents on it?

I went through the demo on the first page and found it quite complex (but then I am stuck in existing patterns of course).


I’ve got a Discord from my previous game of about 2000 people, mostly teenagers, and my testers have mostly come from there. To name one example, just yesterday a teenager completed a chess game after 3-4 weeks on Easel. I’ve been incorporating tons of feedback from the testers over the past year and a half.

I think that it may look strange to a person who has coded before because the language is semi-declarative. Most teenagers come to Easel as players with no prior programming experience, and begin by remixing their favourite game, and that’s when the semi-declarative model really shines. Many interesting changes can be done in a single edit because the code is clumped together in a hierarchy. Whereas in another programming language there may be more indirection and you might need to edit 3 separate parts in different files to make 1 change, and people who haven’t coded before don’t know how to find all the parts. I think Easel works for players becoming makers but can feel strange for people who come from other languages.


It is very interesting though! I have been interested in this kind of language design for interactive UI for a while. If there was a quick article outlining how all the "with" and "on" and "own" work to more experienced developers using references to existing language features, I'd love to read it. Right now it reminds me of the declarative style of qt ui and online primitives introduced in godot, but i haven't looked at it in more details. Also love your take on async. Wish you all the best luck, this seems like a really thought through language design!


This is a very kind comment, thank you! Yes it has been a LOT of iteration to make the language what it is. I think it would make sense to have a page for experienced developers to better understand what Easel is. Right now maybe the closest is this page: https://easel.games/docs/learn/key-concepts

Thanks again for your kind words!


This is really cool, these patterns (run once now and then once triggered) surface all the time and usually turn into ugly code! How many interations did it take?

So most lines like A { B{ on D{ print() } } C{} } equivalently desugar into something like a = A; b = B(); a.mount(b); d = D(); d.on(f); b.mount(d); .. ?

I got confused by a couple of things. One of them is whether object parameters act like context parameters and there for depend on names in the caller variable scope? Ie if i define 'fn ship.Explode', i must have variable ship at call site? But i can still otherwise pass it explicitly as alien_ship.Explode(), right? How do i know if a particular call takes the current object into account? If i have two variables in my nested scope: ship and asteriod and both have ship.Explode and asteroid.Explode, which one is picked if i do just `Explode`? The innermost? Or I can't have two functions like that because the first thing is literally just a named variable and not a "method"?

Overall, if you could provide some examples of how things could have de-sugured into a different language, that'd be very interesting! Maybe with some examples of why this or that pattern is useful? I think it does a good job for things like on / once, but I'm not grokking how one would structure an app using this variable scoping use clause and object parameters.

Also not sure how to define functions that could be on'd or once'd. (Ah, i see, delve)


Your book is awesome!


Crafting Interpreters!


I've actually spent the past 3 years making Easel (https://easel.games) specifically for gameplay logic. It's got behaviors as a first-class language construct, ownership and context is implied hierarchically, it's concurrent and event-driven to match how game worlds work, and the multiplayer is automatic because it's built into the fabric of the programming language.

It also feels like a declarative language because of the high-level constructs, but it is actually imperative because (in general) things get executed in the step-by-step order you specify, which I think is important because games are full of sequences.

It's been a lot of work but also a lot of fun! My aim is for this to be a great next step after Scratch for people learning to code but also a good model for how a more advanced game-making programming language could work in the future!


If I understand correctly, the language is not open source, right? Not even the interpreter?

That's a hard sell


tldr I plan to make the singleplayer at least source available, but keep all parts related to multiplayer/persistence/hosting (anything that requires a server) closed for a few practical reasons:

1. Cheating: There has to be some security by obscurity because in Easel, multiplayer and persistence are actually client authoritative. Why client authoritative? We don't simulate on the server to keep costs down. Why keep server costs down? Easel will never run ads because it is aimed at teenagers/children and we want to be able to vet all content shown on Easel. Without ads, combined with the fact that we want Easel to be free for teenagers, the budget is extremely tight. I would rather die than get VC funding because they would force Easel to put profit before principles, so we have to keep the costs low.

2. Development speed: Easel has changed a lot over the past 3 years, and been constantly refactored over and over again. If you look at Easel now, you might think "I could make that" but when I made it, I didn't have any reference points, so I had to iterate and iterate on a lot of things from first principles and take a lot of wrong turns. My GitHub history shows me adding about 2 million lines of code even though the project is about 150000 lines, which shows how much it has been written and re-written. Anyone who tried to contribute would just get in the way at this point. I want to spend my days coding rather than arguing with people on GitHub.

3. Survival: I don't want someone else to take all the code to make a competing platform which does not have the same principles (like putting profit ahead of child safety and showing ads). My dream is for Easel to be a place where most players are makers, like Scratch, except with more actual real games on it because the engine has built-in game features like a physics engine, particle systems and multiplayer. Like Roblox except actually beginner-friendly coding. I have a vision quest and I want Easel to fund Easel so I can make Easel.

I am looking to open source Easel but only in a way which solves the above 3 problems. The way that I have come up with is that open sourcing the singleplayer parts is the best compromise between everything. It just requires stopping development to splitting it all out, and having all the code split out will mean development would be slower, and I am prioritising development speed at the moment. The engine is not complete enough yet and missing a bunch of key features which would stop numerous games from being made. So maybe in a couple of years I will have the bandwidth to look into this. But I actually want to open source Easel, but I just need those problems solved.


This looks promising. How come I hadn't heard of it??

My own ideas for an ideal syntax included keywords like "on" instead of "func" etc. (i.e. be totally event/signal driven)

Taking a look!


Haha I wish I knew how to reach more people like you!

Yeah exactly! I think the event-driven/signal-driven way of coding is the high-level way of coding a game, and so with Easel I was trying to make a game programming language where that is first class. It's different from the frame-by-frame state machine kind of model that is used by a lot of other game engines, and I find it's super productive.

I know that I am unable to single-handedly compete with Godot or Unity so to make the scope achievable it's aimed at being a good 2D programming language for learners at this point. There's a surprising amount of similarity between Scratch and Easel because Scratch is also event-driven and concurrent like Easel. We often send our learners to Python or JavaScript and I've seen that they just lose engagement. The difference is bigger than just going from visual to text-based coding. Easel makes the gap closer and so I am hoping it'll be a great next step from Scratch into text-based coding.

But I also hope Easel can add to the conversation and interest people like you as a example of how game programming languages could be made. One day I hope to actually bring Easel to more serious games, maybe bringing it to other engines or with its own 3D engine. One reason why I am leaning on making my own 3D engine (long term goal) is that in Easel, the multiplayer is automatic and it would be difficult to bring that to another engine.

In either case it's great to meet someone who has been thinking about this kind of problem like I have.


> I know that I am unable to single-handedly compete with Godot

You could package your language as a GDExtension for Godot.

I'm planning my fantasy language from the top-down, syntax first: how it would look like to users/developers to use it, then think about how to implement that language if ever :')

Right now I'm just fiddling with a extension for VSCode/ium to syntax highlight the hypothetical language, then I'll put it up on a brainstorming repository on GitHub.


Yep, it's definitely a possibility down the line.

Maybe a 7-day gamejam is a great way to explore your ideas!


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: