VJ UNION

Cover image for Hedron is Back: A Brand New Beginning from the Ground Up
vdmo
vdmo

Posted on

Hedron is Back: A Brand New Beginning from the Ground Up

https://github.com/nudibranchrecords/hedron/releases

If you’ve been following Hedron project, you may have noticed things have been quiet for a few years. recently Hedron team announced that the silence is over. Hedron is not just waking up—it's being reborn.

In a new GitHub issue titled "A fresh start - v1.0.0", project member @funwithtriangles announced that work has officially begun on a completely new version of Hedron. This isn't just a patch or an update; it's a total rewrite from the ground up, built to leverage the best of modern development tools and practices.

Led by @funwithtriangles and @cale-bradbury, this new chapter for Hedron is an exciting moment for the project and its community.

Starting from Scratch with a Modern Toolkit

The decision to start over wasn't taken lightly. The goal is to build a more robust, secure, and flexible platform for the future. The team is embracing a powerful new tech stack that promises to elevate Hedron to a new level.

Here’s a look at what’s under the hood:

  • TypeScript: By building with TypeScript from the start, the new Hedron will be more scalable, easier to maintain, and less prone to common bugs, providing a more reliable experience for everyone.
  • Security-First Electron App: The new desktop application will be built following Electron's latest security recommendations, ensuring a safer environment for users and their data.
  • A Modular Monorepo: The project is being structured as a monorepo, which will house several distinct packages. The most exciting part of this is the new hedron-engine.
    • hedron-engine for Everyone: The core engine will not only power the main desktop app but will also be published as a standalone package. This is huge! It means you'll be able to use the power of Hedron in your own web projects.
  • Zustand for State Management: Leveraging Zustand, a small, fast, and scalable state-management solution, will keep the application's logic clean and performant.
  • A Future with Plugins: The team is exploring a potential plugin system, which would open the door for incredible community contributions and customization down the line.

A Clean Slate for a Fresh Start

To match the fresh start in the codebase, all old issues on the GitHub repository have been closed.

As @funwithtriangles explains, "Because it's a completely fresh project, I've closed all the issues. Some are definitely still relevant, but I'd rather only see issues that people care about recently rather than from years ago."

This move is designed to focus the project's energy on what's relevant to the new architecture. For now, the team encourages everyone to consolidate feedback and discussions into the official announcement thread to keep the conversation centralized and productive.

Get Involved and Help Shape the Future of Hedron

This is more than just an announcement; it's an invitation. The team is actively looking for community members who are excited about this new direction and want to be a part of the journey.

Here’s how you can get involved right now:

  1. Explore the Code: Dive into the brand new codebase on the alpha branch on GitHub. (Note: Replace with the actual link)
  2. Join the Conversation: The main hub for all discussion is Issue #444. Say hello, share your thoughts, and connect with the developers. (Note: Replace with the actual link)
  3. Follow the Progress: Keep an eye on the project's progress by checking out their development board or project tracker. (Note: Add link to project board if available)

The revival of Hedron is a testament to the passion of its developers and the enduring potential of the project. It’s an exciting time to be a part of the community, and we can't wait to see what grows from this brand new seed.

How does Hydra work? Let's break it down.

High-Level Overview: What Does This Code Do?

This HTML file creates a complete, interactive 3D physics simulation that runs in your web browser. It sets up a "room" and fills it with different types of polyhedral objects (like dice). These objects fall, bounce off the walls and each other, and can be manipulated using a control panel.

It achieves this by using three main JavaScript libraries:

  1. Three.js: A powerful library for creating and displaying 3D graphics in a web browser. It handles everything you see.
  2. Cannon-es: A lightweight 3D physics engine. It handles all the invisible calculations for gravity, collisions, bouncing, and friction.
  3. lil-gui: A simple library for creating the interactive control panel with sliders and buttons.

The fundamental concept to understand is that there are two parallel worlds:

  • The Visual World (Three.js) that you see on the screen.
  • The Physics World (Cannon-es) which is an invisible simulation running in the background.

The code's main job is to keep these two worlds perfectly synchronized in every frame.


Code Breakdown

Let's go through the file from top to bottom.

Part 1: HTML and CSS (<head> section)

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js Physics Room Demo</title>
    <style>
        body { margin: 0; overflow: hidden; background-color: #111; }
        canvas { display: block; }
    </style>
</head>
Enter fullscreen mode Exit fullscreen mode
  • <style>: This is basic CSS. It removes the default margin from the page, hides scrollbars, and sets a dark background color. It makes the <canvas> element (where the 3D scene is drawn) fill the entire browser window.

Part 2: JavaScript Setup (<script type="importmap">)

<script type="importmap">
    {
        "imports": {
            "three": "https://unpkg.com/[email protected]/build/three.module.js",
            "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/",
            "cannon-es": "https://unpkg.com/[email protected]/dist/cannon-es.js",
            "lil-gui": "https://unpkg.com/[email protected]/dist/lil-gui.esm.js"
        }
    }
</script>
Enter fullscreen mode Exit fullscreen mode
  • importmap: This is a modern browser feature that makes using libraries easier. It's like a shortcut list. It tells the browser: "When the code says import * as THREE from 'three', go to this specific URL to get the Three.js library." This avoids complex build tools for a simple project.

Part 3: The Main JavaScript Logic (<script type="module">)

This is where all the action happens.

Section 3.1: Basic Setup (Three.js)
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// ... other imports

// The "Trinity" of Three.js
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });

// Initial setup
camera.position.set(0, 5, 15);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);
Enter fullscreen mode Exit fullscreen mode
  • import: Loads all the required libraries using the shortcuts from the importmap.
  • scene: The virtual stage where all objects, lights, and cameras exist.
  • camera: The virtual camera—it determines what we see.
  • renderer: The engine that takes the scene and camera and draws the result onto a <canvas> element.
  • controls: Allows you to use your mouse to orbit, pan, and zoom the camera.
Section 3.2: Physics World Setup (Cannon-es)
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
Enter fullscreen mode Exit fullscreen mode
  • This creates the invisible physics world.
  • It sets a standard downward gravity along the Y-axis.
Section 3.3: Creating the Scenery (Room)
function createRoom() {
    // ...
    const createWall = (size, position, rotation) => {
        // Create the invisible physics wall (a static body that doesn't move)
        const wallBody = new CANNON.Body({ mass: 0, /* ... */ });
        world.addBody(wallBody);

        // Create the visible 3D wall that we can see
        const wallMesh = new THREE.Mesh(/* ... */);
        scene.add(wallMesh);
    };
    // ... calls to createWall for floor, ceiling, etc.
}
Enter fullscreen mode Exit fullscreen mode
  • This function builds the container. Notice how for each wall, it creates two objects:
    1. A CANNON.Body: An invisible, immovable physics object that other objects can collide with.
    2. A THREE.Mesh: The visible, gray-colored box that you actually see on the screen.
Section 3.4: Creating the Falling Objects
function createObject(type) {
    // 1. Create the VISIBLE 3D object (a Three.js Mesh)
    const mesh = new THREE.Mesh(objectGeometries[type], objectMaterials[type]);
    scene.add(mesh);

    // 2. Create the INVISIBLE physics body
    const body = new CANNON.Body({
        mass: 1, // It has mass, so it's affected by gravity
        shape: cannonShapes[type], // Its collision shape
        material: objectPhysicsMaterial
    });
    world.addBody(body);

    // 3. Link them together for later
    objectsToUpdate.push({ mesh, body });
}
Enter fullscreen mode Exit fullscreen mode
  • This is the most important function for understanding the core concept. It does three things:
    1. Creates a visible object (mesh) and adds it to the scene.
    2. Creates a corresponding invisible physics object (body) and adds it to the world.
    3. Pushes a small object containing both the mesh and the body into an objectsToUpdate array. This array is the link between the two worlds.
Section 3.5: The User Interface (lil-gui)
const gui = new GUI();
const settings = { /* ... */ };

// Example: Create a slider for gravity
physicsFolder.add(settings.physics, 'gravity', -20, 20, 0.1)
    .name('Gravity Y')
    .onChange(v => world.gravity.y = v);
Enter fullscreen mode Exit fullscreen mode
  • This section creates the control panel.
  • gui.add() creates a new UI element (like a slider or button).
  • The .onChange() function is a callback. It says: "Whenever the user moves this slider, run this function." In this case, it instantly updates the gravity in the physics world.
Section 3.6: The Animation Loop (The Engine)
function animate() {
    requestAnimationFrame(animate); // Loop this function forever

    // 1. Advance the Physics World
    world.step(1 / 60, deltaTime, 3);

    // 2. Synchronize the Worlds
    for (const obj of objectsToUpdate) {
        obj.mesh.position.copy(obj.body.position);
        obj.mesh.quaternion.copy(obj.body.quaternion);
    }

    // 3. Render the Visual World
    controls.update();
    renderer.render(scene, camera);
}
animate();
Enter fullscreen mode Exit fullscreen mode
  • This is the heart of the application, which runs about 60 times per second.
  • Step 1: world.step(...): This tells the Cannon-es physics engine to calculate everything that has happened in the last fraction of a second (where all the objects moved, what they collided with, etc.).
  • Step 2: The for loop: This is the synchronization step. It iterates through our objectsToUpdate array. For each object, it copies the new position and rotation from the invisible physics body to the visible 3D mesh. This is what makes the objects on the screen move.
  • Step 3: renderer.render(...): Finally, after everything has been updated, this tells Three.js to draw the new frame to the screen.

Discussion (0)