mario-game-engine.webp

When you write apps for fun the trickiest part is to come up with an idea that will keep you engaged long enough to actually build something useful. I've had lots of ideas die on the vine after coding for a while, but this one crossed the finish line - or at least close enough to be interesting.

I'm a big fan of tools like Mermaid.js and PlantUML, which let you create UML diagrams using a simple text language. Both tools have their own custom language optimized for creating UML diagrams.

If you use these tools I'm sure you've noticed that LLMs like ChatGPT can create great diagrams from text - just describe your domain and ChatGPT does the rest. Copy/paste the output into Mermaid or PlantUML, and voila, you've got a cool, probably reasonably accurate diagram to visually represent your text.

This works so well because the language is simple and self-contained. There are no libraries to include, files to reason across and so on. Just a nice, simple, self-contained language.

My idea: create something in the same spirit but use a more traditional, javascript-like mostly-declarative language and let the user create diagrams using both the text language and a drag-and-drop UI.

How to Write a Programming Language in Three Paragraphs

There are hundreds of programming languages out there, most of which you've never heard about. Why? Because they're fun to write! Very few catch on with developers so they languish in obscurity (like my Medium articles).

While each language has its own unique characteristics, they all work in basically the same way:

  1. First, translate the program's text into a tree structure called an Abstract Syntax Tree (AST)
  2. Next, either compile the AST into machine code (ultimately, that's what the computer understands) or interpret the AST on the fly using an Interpreter, which is basically a program that runs your program

When you include a graphical editor it needs to both "edit" the AST and then regenerate source code from it- which can be a little tricky.

My "Gizmo" language runs in the browser, so there's no chance of compiling to machine code. So I wrote an interpreter.

Baby Steps

The first step is to let users create simple diagrams like the animal taxonomy below using drag-and-drop. You can run this program by clicking this link.

Simple Animal Taxonomy

In Mermaid.js, the code looks like this:

classDiagram
Animal <|-- Mammal
Animal <|-- Bird
Mammal <|-- Dog
Mammal <|-- Cat
Bird <|-- Eagle

And you get a diagram like this:

Mermaid Class Diagram

In Gizmo, you create shapes using a simple declarative language that looks like this:

let animalClass = rect {
x: 300,
y: 50,
width: 100,
height: 60,
fill: "#e3f2fd",
stroke: "#1976d2",
strokeWidth: 2,
label: "Animal"
}()

To create a simple shape start like this:

rect{}()

Which will render a default rectangle. Then add properties like position, color, and so on. You can alternatively drag a rectangle from the palette of shapes onto the canvas, and the code will be automatically created for you.

Easy peasy.

Links between shapes are created like this:

animalClass's--mammalClass'n

Where 'n' and 's' represent the positions of the connection points on the shapes (north, south). You can also drag-and-drop connection lines to create links.

Here's Where Things Start to Get Interesting

So that's all well and good. And honestly, that's solves 99% of my own use cases. Maybe I'll use it to create AWS diagrams (I included lots of built-in AWS icons) or maybe I'll use it to create a mind map if I'm thinking deep thoughts.

Time to claim victory and throw in the towel? Heck no.

What about Reactivity? That would be cool. Maybe add some simple controls to let users manipulate shapes in real time.

Here's what a simple example looks like, and you can run this program using this link. If you drag the slider, the image moves around.

Reactive Slider Example

Building this was considerably harder, because the reactive code needs to manipulate both the AST and the canvas in real time. Doable, but it took some thinking.

Quit While I'm Ahead? Nope.

So this is getting interesting and there are a few more things I can use it for. Maybe for simple calculations, like a mortgage calculator

Since we've got these shapes moving around on the canvas, maybe it's time to integrate a physics engine? There are some interesting choices out there, but the one that really caught my eye is Rapier. Rapier is written in Rust - which isn't of much use for a browser app. But, they've compiled it to WebAssembly, which runs super fast in the browser. Voila!

Now things get really interesting, because it's morphed into a simple Game Engine. Since the language is so simple ChatGPT can do a pretty good job using it to create simple games. Give it a try, here's one I created with a little help from my new chatty friend. It looks like this:

Cannon Game

It's not exactly Unity, but it is novel, fun to play, and super easy to build. The real power of this "game engine" is Rapier, which, because of its hyper-fast WebAssembly implementation, makes the rendering realistic, fast and smooth. I'm always amazed at what can be done in a browser alone, which makes it my development platform of choice.

Where To Go From Here?

I'm not really sure. It's been fun to build, but burnout is settling in. Maybe time for a new project. 

If you like free apps you can find some others I've written at app.gizmocms.com.