Hello Everyone! My name is Alex, and I’m working on an open source, modular game engine called Cobble.js, built on top of Three.js. The idea is that the engine starts super small — by default it just sets up a basic Three.js scene with a camera and renderer — and then you expand it by using plugins.
These plugins are just exported Javascript classes that you can apply to the engine. Plugins range from essentials like Entity, Audio, Particles, and Physics, to bigger systems like WorldGen, Zones (for things like biomes and trigger areas), Weather, etc.
Plugins hook into a central game loop, and some plugins depend on others (e.g. Weather depends on Particles). I’m currently working on the core architecture and would love some advice and help from people experienced with Three.js — especially around how to best structure the base so plugins can hook in cleanly without stepping on each other.
Here is the GitHub repo link: https://github.com/SuperGamer001/COBBLE/
2 Likes
I may need to restructure what I currently have on the given GitHub Repo. This is just a demonstration as of right now.
best structure
really depends on who the audience is.
What you have here looks a lot like an Entity Component System (ECS) as popularized by Unity and elsewhere. It’s a decent architecture.
1 Like
Thanks. It’s still in the works, and might not be the most efficient.
The audience I’m going for are those who want minimal, but structured, non-verbose code. It’s also for those who what to control how big of an engine they want.
Edit: Also for those who don’t know how to efficiently do difficult tasks, like voxel world generation, water, etc.
2 Likes
I’ve been experimenting with modular browser based 3D environments built on Three.js where scenes, assets, and systems can evolve incrementally. Your Cobble.js concept of a minimal core with expandable plugins is a solid direction, especially if the engine loop stays centralized and plugins hook into lifecycle stages like init, update, and dispose.
Keeping plugins loosely coupled helps avoid conflicts. One approach is letting systems register themselves with the engine instead of calling each other directly. Dependencies like Weather requiring Particles can be declared in the plugin metadata and resolved when the engine initializes the plugin stack.
A small event or message bus inside the core also helps a lot. Instead of plugins referencing each other directly, they emit and listen to events which keeps modules independent and easier to maintain as the engine grows.
I’ve been building browser based environments and virtual spaces using GLTF pipelines and modular systems where assets can be dropped directly into the scene and tested in real time. The idea is similar to what you described: keep the base environment lightweight and allow features to layer on top.
Demo
https://theneoverse.web.app/#threeviewer&&crateria
Some other work and experiments
https://theneoverse.web.app/#services
Happy to look at the repo structure and suggest ways to organize the plugin lifecycle and engine loop if you want another set of eyes on it.
1 Like