Alona Engine.js
a project of great proportions for JavaScript
Alona is a JavaScript engine to simulate complex physics performantly, and with ease of use. That is the elevator pitch, the one I practiced in front of the mirror. The honest version is a little longer: it is a sandbox where I could throw particles, forces and strange attractors at the browser and see what sticks. It is still in its humble beginnings, with some bugs and some features, but you can already try it yourself if you want to. The links are down there, at the end, in case you want to wallow in my messes.
Alona is being made with TypeScript, Three.js and lots of math. And by "lots of math" I mean the kind that makes me open three tabs of documentation and one tab of a forum from 2014 where someone named vectorEnjoyer explains a cross product better than my professor did. I will probably use some physics libraries for simulations that do not affect the core principles of the engine, because at some point you have to admit that not everything needs to be rewritten from scratch by a guy in a bedroom on his 5th can of Red Bull.
The four foundations
The idea is to divide it into four parts: Particles, Relations, Spaces and Forces.
Particles represent an individual point with mass in space. It can be literally a vector with no appearance or significant size, or it can be a fully grown bear, with big claws and a cute hat. Basically anything with mass and position.
Relations are the relations between particles. They glue them together and tell them how to affect their surroundings and each other. It is important to notice that relations will not directly affect the related particles; they will tell the particles how to act together when a force is applied. Also, a particle always has a relation with its space, so one particle or a group of particles can affect the space itself and, therefore, affect other particles. It is a little bit like a group project: nobody does anything directly, but everyone affects everyone, and somehow the final result comes out of that.
Spaces are a fluid stage in which the particles play an act. A space can be manipulated to achieve different conditions, from gravity to humidity, friction, universal constants and more. Maybe quantum physics when the time comes to move the engine to WebAssembly, but let us not promise that before lunch. The space is the room, the weather and the rules of the house all at once.
And finally, the forces. The forces are manipulations in state and position matrices and "inner particles". This engine is being made with low fidelity simulations of atoms and elemental particles in mind. The idea here is to be able to represent complex forces or influences with ease and speed, in exchange for precision. It is a trade I am happy to make, because a beautiful approximation that runs at 60 fps on the web is something I can brag about to the nerds among my friends.
And, again... why JavaScript?
Okay, okay, I know what you are probably thinking. JavaScript is not performant, it is buggy, clunky and problematic. Oh, and how could I forget? It has this little-big problem of being single threaded.
To argue against all this, all I can offer is a hug and some basic statements. First of all, JavaScript can compete with Python regarding performance in some scenarios, as you can see in this benchmark. Second, you can achieve some sort of multithreading with some neat tricks, like Web Workers, which are basically tiny rooms where you can lock a computation so it does not block the rest of the party. And finally, I have some V8 publications that I stole from SimonDev about speed, memory and performance. I recommend you check those out; they are in the references below, and they explain the engine much better than I ever could.
The truth is that I like the browser as a research lab. Everyone has one. Nobody needs to install a runtime, compile a binary or read a README with seventeen prerequisites. You open a tab and the physics starts. That accessibility is worth a lot to me, even if I have to fight the garbage collector every once in a while.
Where it stopped, for now
Unfortunately, I do not think I will be focusing on Alona that much in the next few months. I am writing this in 2023, on a day that smells like five other projects, so you can consider it paused on its current version: SprottLinzD 1.3.0-alpha. This version does not have much in it. I was messing around with Three.js, pipelines and different approaches for rendering before actually doing physics. Which is a very fancy way of saying I spent a long time making the simulation sexy before making anything move.
But it has some gorgeous chaotic attractors for you to play with. And, for now, that is all there will be. There is something magical about typing a few numbers, hitting run, and watching a shape that looks like a galaxy decide to exist on your screen. Take a peek.
Running it yourself
You will need to compile the TypeScript code before running the engine. The basic ritual is:
npm install
npm run devThen you grab the parent element, call the engine, create a simulation and overwrite the physics process with your own render loop:
const parent = document.querySelector("#app");
const Alona = new AlonaEngine(parent);
const Lorenz = new LorenzAttractor(Alona, { scale_factor: 7 });
Alona.physics_process = (delta: number) => {
Lorenz.render(delta);
};
Alona.run();It is a small API on purpose. I wanted the barrier to be "do you know what a variable is?", not "do you have a PhD in differential equations?". The math can come later, with time, curiosity and a couple of broken simulations.
The repository, with the full source and the current state of the engine, is here: DrayanInterfaceDesigner/alona-engine. If you find a bug, that is not a bug, that is a feature I have not documented yet.