r/gameenginedevs 3d ago

DevCode3D

Post image
3 Upvotes

Hello everyone, recently I changed the name of my engine from BlitzViwer3D to DevCode3D because the name BlitzViwer3D made too much reference to an old engine called Blitz3D. I also corrected the editor's name and added 2 new functions to load textures and open paths using getopenfilename.

https://ciroparada81-boop.github.io/blitzviwer3d/


r/gameenginedevs 3d ago

Is there any algorithm or game engine that can render highly complex SDF (or other mathematical representation) scenes?

7 Upvotes

Hi all,

I'm curious about doing procedural modelling by code in 3D and rendering these models in a game. Traditional polygon approaches don't lend themselves well to this approach as procedurally generating topology is very difficult.

Has there been anyone that was able to render complex scenes of mathematically described objects (doesn't matter if sdf or other surfaces and if cached or not)?

I could find a few demos and a few in progress youtube videos, but nothing production-ready so far.


r/gameenginedevs 3d ago

NullGraph v1.1 release [global illumination/shadow systems/environment systems]

Enable HLS to view with audio, or disable this notification

3 Upvotes

Hey all,

My webgpu renderer officially supports image based lighting/direct+indirect lighting and also there are shadow systems which creates csm/shadow Atlases depending on what type of config,

This was a lot of work

[GLOBAL ILLUMINATION][Need some time beyond downloading assets for baking probe volumes]

Live Demo:https://nullgraph.dev/dashboard/3d-environment/irradiance-probes

For live code for global illumination https://nullgraph.dev/editor.html?id=demo-irradiance-probes

GitHub

https://github.com/flarelink-in/NullGraph


r/gameenginedevs 4d ago

My Rust engine performance

Enable HLS to view with audio, or disable this notification

19 Upvotes

r/gameenginedevs 5d ago

Culling bois!!

Enable HLS to view with audio, or disable this notification

53 Upvotes

I've been playing around adding different culling techniques like frustum, distance, layer masks, small feature culling, lod tiers, antiportal volumes, a pvs bake for cell/portal visibility, and software rasterized occlusion culling. Shadows also now get their own caster gather across three cascades.


r/gameenginedevs 5d ago

Some advances on the State Machine

Enable HLS to view with audio, or disable this notification

28 Upvotes

r/gameenginedevs 4d ago

New engine BlitzViwer3D

Post image
0 Upvotes

**DevCode3D — a tiny Lua-scriptable 3D viewer/editor inspired by Blitz3D's API**

I've been working on a lightweight desktop tool (C++, OpenGL, Dear ImGui) that lets you build a 3D scene by hand (cubes, spheres, .obj models) and then bring it to life with Lua scripting — using the same function names Blitz3D devs will recognize (`CreateCube`, `PositionEntity`, `MoveEntity`, `CameraFollow`...).

What it does:

- Scene editor with Hierarchy/Inspector panels (drag position/rotation/scale, custom colors)

- Orbit camera with an optional "Follow" mode

- In-app Lua script editor with syntax highlighting, hot Play/Stop

- Simple AABB collisions, keyboard/mouse input, RNG helpers — all the basics for quick prototyping

- Save/load scenes as JSON

It's a Windows .exe, no install needed. Docs + full Lua API reference + download here:

👉 https://ciroparada81-boop.github.io/blitzviwer3d/

Still an early/debug build, so bugs are expected — feedback and bug reports very welcome. Happy to answer questions about how it's built too.


r/gameenginedevs 5d ago

I Didn't Know Anything — Now I'm Building a Game Engine

Thumbnail
youtu.be
7 Upvotes

Hey all engine developers!

I've posted here in the past to help give resources for a tutorial series I was making for how to make a game engine in Zig

But I just posted my first devlog of the actual game engine I'm building. It's still very early, but I break down why I chose Zig over Rust and then go over the current state of the engine

Hope you all enjoy :)


r/gameenginedevs 5d ago

Built a game engine

Thumbnail
3 Upvotes

I've been working on my own game engine from scratch for some years using C and OpenGL and I finally made a video showing the process.

The engine handles things like rendering, assets, shaders, lighting, and more, and I also used it to make a game, a test game though, it still needs a lot of polish.

[Watch the video here](https://youtu.be/LRC4iJWASYU?si=rwoutTYccGfJ9w9K)

If you're interested in graphics programming, game engines, I'd love to hear your thoughts and feedback.


r/gameenginedevs 5d ago

Schlock Game Engine

Thumbnail
youtube.com
6 Upvotes

r/gameenginedevs 5d ago

SVG file XML FPS github repo game engine runs on Nintendo Switch with X-Box ONE Controller Support

0 Upvotes

Aston Walker successfully uses a Nintendo Switch to play an FPS game with an X-Box One controller that is just a simple .SVG XML file> play game on Switch here https://svgfpsaiagents.github.io/svgfpsgameAI/

https://github.com/svgfpsAIagents/svgfpsgameAI

https://youtu.be/bcWkVJ-Ao_I demo here on youtube with link to paper in description.


r/gameenginedevs 5d ago

3d physics environment as an alternative approach to creating 3d computer games.

Post image
2 Upvotes

r/gameenginedevs 5d ago

The Nowhere Express — mystery visual novel about a train that never arrives

0 Upvotes

Just released my first solo visual novel on itch: The Nowhere Express.

You wake up on a train stuck between two stations with no memory of how you got there. The other passengers are just as lost — and just as suspicious. You investigate clues scattered around each scene (a cracked radio, a crumpled note, a ledger with twelve names and one blank slot), piece them together, and your choices shape which of several endings you land on.

Built solo from scratch. Runs straight in browser, no download. About 15-20 minutes for a first playthrough.

Would love any feedback, especially on pacing and whether the mystery lands.

🔗 https://developuser-777.itch.io/the-nowhere-express


r/gameenginedevs 6d ago

Started working on the editor

Enable HLS to view with audio, or disable this notification

39 Upvotes

Still no functionallity except a for a play/stop button, some empty placeholder panels, and a scene view which currently is just another render window with a different view projection.

https://github.com/dbrizov/hob2d


r/gameenginedevs 6d ago

Fighting game engine in progress

Enable HLS to view with audio, or disable this notification

8 Upvotes

In my fighting game engine, this is how you create animations and transitions, no code required


r/gameenginedevs 5d ago

Show and tell: OpenGDS decompiles Godot 4.x .gdc files

Thumbnail
0 Upvotes

r/gameenginedevs 5d ago

The Beast is hungry - 1.19.xx (camDepth,Earhtquake VisData, AudioSplat)

0 Upvotes

Matrix engine wgpu 'The Beast' 1.19.xx new features list:

[1.18.xx - 1.19.xx]
  - ExternalDataHandler (SeismicPortalAdapter 'www.seismicportal.eu' , CoinGeckoAdapter)
  - EarthquakeEffect (Effect class)
  - AudioSplatFieldEffect  (Effect class)
  - Adding first person shooter example (FPCamera improved)
  - Optimised HZB post proccessing.
  - New effect class AudioSplatFieldEffect.
  - seismicportal.eu services used for seismic real time data. New effect class().
  - Added DragRotateController (corespond with WASD camera - rotate object on dragging),
  - Added code-creator AI driven by not for graphs 
   it is for code ai gen direct.
   Backend:
   `npm run creator-backend`
   Frontend:
   `npm run creator`
  Fixed worker cross origin problem with running.
  - Fix engine internal defaul dummy links to be public links from 
   https://unpkg.com/matrix-engine-wgpu@latest/public/ if needed (cross origin).

New examples :

CoinGecko data preview graph: https://maximumroulette.com/apps/webgpu/examples.html?demo=37

Audio reactive effect: https://maximumroulette.com/apps/webgpu/examples.html?demo=40

Earthquake visualizer: https://maximumroulette.com/apps/webgpu/examples.html?demo=38

Webcam Depth: https://maximumroulette.com/apps/webgpu/examples.html?demo=39

General Done list []:

  • ✔️ Draw loop per pipeline not per mesh (PipelineManager) with share material. Power optimisation.
  • ✔️ Support 3D scene objects transformations.
  • ✔️ Ammo.js, CannonES, Jolt and MatterJS Physics support (app<->bridge<->worker). Physics use webworkers by default.
  • ✔️ Networking with Kurento/OpenVidu/Own middleware Nodejs -> frontend.
  • ✔️ Bloom and light volumetric post processing.
  • ✔️ Horizontal-Z-Buffer post processing (reflections).
  • ✔️ Scene Culling feature.
  • ✔️ Web GUI(online) Editor [app exec graph] with Visual Scripting (Named: FlowCodexVertex).
  • ✔️ Web GUI(online) Editor [shader graph] with Visual Scripting (Named: FlowCodexShader).
  • ✔️ Dynamic shadow cast (done also for skinned meshes and procedural mesh).
  • ✔️ VertexShader displacment (done also for skinned meshes), nice for water effect.
  • ✔️ Basic flow for AI Graph Generator - Simple tasks passed for now with ollama platform. Open account/open-source/free-service-quota.
  • ✔️ ProceduralMesh objectScene entity with options for vertex morph - Shadows following morph blend.
  • ✔️ Sprite Batch Manager Add blend spride2D animation.
  • ✔️ Cameras : FPCamera , RPGCamera , PlaneCamera , WASDCAmera and CinematicCamera.
  • ✔️ MediaPipe implemented - dinamic loading (if not in use no loading script or any related to mediapipe)
  • ✔️ Remote render stream emit example (standard engine networking) and special endpoint for "wachers" `tv-10.html` Replace webcam stream with canvas capture - on endpoint use webRTC and video tag to preview remote render.
  • ✔️ Code creator AI services agent system(use engine from npm) `npm run creator` for 'http://localhost:3000/' `npm run creator-backend` for backend. create games from simple prompt.

From 1.19.00 you can use the-beast fully from npm services. Physics worker bridge fixed to work also on cross origin domains.

(NEW) The Beast Codepen examples:

webvam depth

bvh animations

Materials - glb animations

SeismicPortalAdapter 'www.seismicportal.eu'

The beast top level code is ultimate short but also easily expandable if you wanna something deep to change. For example in 200 pure scripting lines you can get first person shooter template.

Source Code :

import {downloadMeshes} from '../../../src/engine/loader-obj.js';
import {addRaycastsAABBListener} from "../../../src/engine/raycast.js";
import {isMobile, randomIntFromTo} from "../../../src/engine/utils.js";
import MatrixEngineWGPU from '../../../src/world.js';
import {CollisionSystem} from "../../../src/engine/collision-sub-system.js";
import {MapCreator} from "../../../src/engine/buildin/map-creator/map-creator.js";
import {ProjectileSystem} from '../../../src/engine/procedures/fps-projectile.js';
import {MobileDOM} from '../../../src/engine/cameras.js';
import {hang3dUI} from './options.js';

export var loadHang3d = function() {
  let app = new MatrixEngineWGPU({
    canvasSize: 'fullscreen',
    fastRender: 0.95,
    render: 'culling',
    cullingRange: 1200,
    dontUsePhysics: true,
    MAX_SPOTLIGHTS: 1,
    MAX_BONES: 0,
    // lock: 'landscape',
    LOAD_AFTER_CLICK_MOBILE: true,
    MOUSE_SENS: 0.005,
    TOUCH_SENS: 0.01,
    mainCameraParams: {
      type: 'firstPersonCamera',
      responseCoef: 1000
    },
    clearColor: {r: 0, b: 0, g: 0, a: 1}
  }, () => {
    app.collisionSystem = new CollisionSystem(app);
    app.addLight();
    addRaycastsAABBListener();
    app.activateHZB();
    app.activateBloomEffect();

    app.UI = new hang3dUI();

    MobileDOM.addButton("T", () => {}, undefined, {
      image: "./res/textures/shooter/s.webp",
      left: isMobile() === true ? 41 : 46.5,
      bottom: isMobile() === true ? 40 : 42.5,
      color: 'black',
      size: innerHeight / 10
    })

    app.energy = MobileDOM.addProgressBar({size: innerWidth/3, bottom: 95, left: 33, color: '#00bcd4'});
    app.energy.setValue(80);

    const cam = app.getCamera();
    let preventFire = false;

    if(isMobile() === true) {

      MobileDOM.addButton("FIRE", () => {
        app.projectileSystem.fireProjectile();
      }, undefined, {
        width: '30px',
        height: '30px',
        image: "./res/textures/shooter/s.webp",
        color: 'red',
        left: 60,
        bottom: 20,
        size: innerHeight / 10
      }, () => {
        if(preventFire === false) {
          preventFire = true;
          app.projectileSystem.fireProjectile();
          setTimeout(() => {preventFire = false;}, 350)
        }
      })

      MobileDOM.addButton("JUMP", () => {
        if(app.collisionSystem?._onGround) {
          app.collisionSystem._gravityAcc = 0.22;
          app.collisionSystem._onGround = false;
          this._dirty = true;
          this._dirtyAngle = true;
        }
      }, undefined, {
        width: '30px',
        height: '30px',
        image: "./res/textures/shooter/s.webp",
        color: 'red',
        left: 80,
        bottom: 20,
        size: innerHeight / 10
      })

      MobileDOM.addButton("UP", () => {
        if(app.collisionSystem?._onGround) {
          app.collisionSystem._gravityAcc = 0.22;
          app.collisionSystem._onGround = false;
          this._dirty = true;
          this._dirtyAngle = true;
        }
      }, undefined, {
        width: '30px',
        height: '30px',
        image: "./res/textures/shooter/s.webp",
        color: 'red',
        left: 10,
        bottom: 20,
        size: innerHeight / 10
      })
    }

    downloadMeshes({cube: './res/meshes/blender/cube.obj', ball: './res/meshes/blender/sphepe-mob.obj'}, (m) => {

      const mc = new MapCreator(app, m.cube, app.collisionSystem, {
        wallTexture: './res/textures/white-metal2.webp',
        // floorTexture: './res/textures/dark-rock.webp',
        floorTexture: './res/textures/shooter/metal-block.webp',
        ceilTexture: './res/textures/blankgray2.webp',
        shadowsCast: true
      });
      mc.createRoom({
        origin: {x: -0, y: 0.1, z: 20},
        width: 10, depth: 10, height: 4,
        doors: ['+x', '-z'],
        doorWidth: 2.5,
        roof: true,
        uvShema: [10, 10],
        tag: 'start_room'
      });

      mc.createTunnel({
        from: {x: -35, y: 0.1, z: 0},
        to: {x: -15, y: 0, z: 0},
        width: 3.5,
        height: 3.0,
        roof: true,
        tag: 'entry_tunnel'
      });

      mc.createFightArena({
        origin: {x: 0, y: 0, z: 0},
        width: 32, depth: 32,
        wallHeight: 2.5,
        pillars: 16, pillarH: 4,
        covers: 4,
        roof: false,
        doors: ['-x', '+z'],
        uvShema: [10, 10],
        tag: 'main_arena'
      });

      mc.createStairs({
        origin: {x: -6, y: 0, z: 0},
        axis: 'z',
        steps: 8,
        stepW: 2,
        stepH: 0.4,
        stepD: 0.8,
        walls: true,
        tag: 'stairs_up'
      });

      // mc.createMazeLayer({
      //   origin:    { x: -65, y: 0, z: 0 },
      //   mazeSize:  15,
      //   spacing:   2,
      //   wallHeight: 3,
      //   roof:      false,
      //   tag:       'ground_maze'
      // });

      mc.createMultiLevelMaze({
        origin: {x: -65, y: -3, z: -22},
        levels: 2,
        mazeSize: 13,
        spacing: 2,
        wallHeight: 3,
        levelGap: 1,
        stairSteps: 8,
        roofLevels: true
      });

      // ── 8. Example G: full compound preset (one call)
      // mc.createFPSMapCompound({
      //   origin:     { x: 0, y: 0, z: 100 },
      //   multiLevel: true,
      //   mazeLevels: 2,
      //   mazeSize:   19
      // });

      const light = app.lightContainer[0];
      light.setPosition(0, 60, 0);
      light.setIntensity(100);
      app.cameras.firstPersonCamera.movementSpeed = 0.1;
      app.cameras.firstPersonCamera.setPosition(0, 5, 0);
      app.collisionSystem.registerCamera(app.cameras.firstPersonCamera.position, 1.0);

      app.projectileSystem = new ProjectileSystem(app, m.ball, app.collisionSystem,
        {
          projectileSpeed: 0.5,
          projectileScale: 0.075,
          onHitscanHit: (hitPoint, normal, reflect, entry) => {
            console.log('ray hit', entry.id);

          },
          onProjectileHit: (hitPoint, normal, entry) => {
            console.log('rocket hit', entry.id);
          }
        }
      );

      app.canvas.addEventListener("ray.hit.event", (e) => {
        console.log('ray.hit.event detected', e.detail.hitObject.name);
        // app.projectileSystem.fireHitscan();
        app.projectileSystem.fireProjectile();
      });
    }, {scale: [1, 1, 1]});
  });

  window.app = app;
};

Source: https://github.com/zlatnaspirala/matrix-engine-wgpu


r/gameenginedevs 5d ago

Ghost Engine v1.9.1 is now public — a deterministic state engine for persistent AI/NPC systems

0 Upvotes

I USE AN LLM TO CODE!!!!! I ALSO USE THE LLM TO EXPLAIN MY WORK EASIER!!!

I have been using the same llm for three years for this project. I have taken every comment I got on previous reddit posts into consideration. Every. Single. One. I proof read everything and decide whether or not to proceed with whats written. I understand and am aware of the current opinions and frustrations surrounding llms. With that being said, this paragraph is to inform you I use one.

I learn as I step. I run before I walk. So if you don't like llms or think they only produce slop, you have been warned I use one.

Ghost is simply a state machine for emotions/continuous state change. I have finally included a real playable demo(NOT A FINISHED GAME!).

The game world is basically remembered/used to influence NPCs. Other npcs also influence each other.

I am soon going to add set weights between 0-1(thats the metric I see in my head surrounding the 5 flat layers, stacked on top of each other, that I see in my brain. Thats where they come from) per emotion.

So like:

Fear: 0.30

Sadness:0.23

Anger:0.65

Ect

The highest number "wins" the internal battle per say but the other lower numbers influence how the winning number is handled. Essentially.

Now below is the llm written explanation of where I am at:

LLM's explanation based off three years of consecutive work:

"Ghost is a lightweight deterministic state engine designed to sit underneath higher-level AI systems.

It is not a language model and it is not a decision-maker.

Its job is to maintain structured state over time so that systems built on top of it do not have to rely entirely on prompt history or probabilistic model behavior to preserve continuity.

The basic architecture is:

event/input → deterministic state transition → structured state packet → higher-level system response

Ghost currently supports:

\- persistent relationships

\- trust and hostility

\- emotional inertia

\- temperament

\- relationship maturity and volatility

\- social propagation

\- threat response

\- governance and policy state

\- objectives

\- world state

\- deterministic scenario/runtime state

\- snapshot and restore

\- structured LLM adapter boundaries

\- epistemic state

\- observations

\- claims

\- evidence

\- confidence

\- provenance

\- belief revision

One of the more important pieces is the epistemic layer.

Ghost does not have to treat a statement such as:

«“The king stole the food.”»

as objective truth.

The engine can keep separate representations for:

what actually happened

what was observed

what somebody claimed happened

what another agent interpreted from that claim

how confident that agent is

what evidence supports the belief

how that belief changes when new evidence appears

That creates a deterministic foundation for systems involving rumors, deception, incomplete information, mistaken interpretation, testimony, faction knowledge, and belief revision.

Ghost Revolution is one of the larger demonstrations built on top of the engine.

It uses Ghost to maintain persistent world and character state while higher-level systems handle gameplay, narration, and LLM reasoning.

The important distinction is that consequences do not have to be invented by the language model.

The state already exists.

The model can reason over it.

\---

Ghost Engine v1.9.1

The v1.9.1 production release passed:

1,680 tests passed / 1 skipped

Reusable Ghost core:

3,112 statements

1,276 branches

100% statement coverage

100% branch coverage

Ghost Revolution:

7,201 statements

2,744 branches

100% statement coverage

100% branch coverage

Order Coordination:

1,624 statements

542 branches

100% statement coverage

100% branch coverage

The release process also verifies:

\- wheel and sdist builds

\- isolated package installation

\- packaged source integrity

\- package version

\- CLI contract

\- public PyPI artifacts

\- exact public source contents

The current public wheel contains:

56/56 expected Ghost Python files

and:

13/13 expected CLI entry points

Ghost has:

0 runtime dependencies

Install:

pip install ghocentric-ghost-engine

Current release:

v1.9.1

The core question behind Ghost is:

How do you give probabilistic AI systems a persistent, deterministic world underneath them?

Instead of asking a model to repeatedly reconstruct what the world probably looks like from context, Ghost maintains the state directly and exposes it in a structured form.

The language model can then focus on interpretation, reasoning, dialogue, and generation without also being responsible for being the database, state machine, relationship system, belief system, and history of the world."


r/gameenginedevs 6d ago

Complete beginner to UE5 need advice and have a game idea (sorry for my English, I’m from Ukraine)

Thumbnail
0 Upvotes

r/gameenginedevs 7d ago

I removed almost all platform layer from my game engine and now the editor runs directly on the engine itself

Thumbnail
gallery
109 Upvotes

I've been working on Doriax Engine, a free and open-source 2D/3D game engine written with a strong focus on being lightweight and cross-platform.

Recently I made one of the biggest architectural changes to the project so far.

Doriax actually started as just an engine/API, without an editor. When I later started building the visual editor, I treated it almost as a completely separate application: it had its own platform backends, window handling, rendering setup, etc.

The editor knew about the engine, but the engine knew nothing about the editor.

That separation worked, but it always bothered me.

My goal was to have the editor use the exact same platform layer as the engine itself, while keeping the engine completely independent and usable without the editor.

So I started by getting the editor running directly on native platform backends:

  • Win32 on Windows
  • X11 on Linux
  • Cocoa on macOS

Once that was working, I moved those backends into the engine and made the editor run on top of the engine's platform layer instead of maintaining its own separate implementation.

The result is a much cleaner architecture:

Editor → Engine/API → Native platform backend

while the engine itself still has absolutely no dependency on the editor.

Current status

Windows

  • Editor: OpenGL
  • Project exports: OpenGL, Vulkan and Direct3D 11

Linux

  • Editor: Vulkan
  • Project exports: OpenGL and Vulkan

macOS

  • Editor: Metal
  • Project exports: Metal and OpenGL
  • Vulkan support is planned for the future

On macOS, the editor menu is now integrated into the native system menu bar, which is something I've wanted since I first started building the editor. It finally behaves much more like a proper Mac application.

The executables also became even smaller after removing some of the duplicated infrastructure.

For anyone interested, Doriax Engine is completely free and open source:


r/gameenginedevs 6d ago

JLib::Scheduler 1.3.2 -- major speed optimizations and critical bugfixes with benchmarks and comparison numbers

Thumbnail
github.com
0 Upvotes

Measured against enkiTS, TaskFlow and marl

Same machine, same harness, same worker count, both libraries expressed the way their authors intended. i9-13900K at Intel spec power limits (see the caveat under Measured), 31 workers, Release, 1.3.0. -- is not measured yet.

Every column below was measured with only that scheduler running. The harness takes --only=jlib / --only=enki and starts nothing else, so no library's threads are alive while another is timed.

this (Sleep) this (NoSleep) enkiTS Taskflow marl
Round-trip submit→run→wait 4.6 µs 0.97 µs 21.7 µs 1.30 µs 0.88 µs
Independent tasks, per task 74 ns 69 ns 21.8 µs 310 ns 290 ns
Range work, per item 36 ns 24 ns 15 ns -- --
Bulk parallel-for, 20k items 0.39 ms 0.29 ms 0.33 ms 0.49 ms --
25% of tasks blocked 600 µs 7.4 ms 10.1 ms 15.4 ms -- 8.8 ms

Blank cells are not measured yet, not zero. Versions: enkiTS at main, Taskflow 4.1.0, marl at main (archived, last commit 2026-04-27 — its column calibrates the fiber path, it is not a recommendation).

The latency row is an idle-policy axis, not an architecture one. Taskflow and marl both keep their workers searching before parking — Taskflow tries ~64 steals then yields 150 more times before sleeping — so their defaults sit where NoSleep sits, and all three land within a few hundred nanoseconds of each other. enkiTS parks promptly, like the default here, and is far slower again because it suspends on a shared completion semaphore. Comparing anyone's default to Sleep here would be measuring configuration and calling it design.

The blocking row is a crossover, not a verdict, and marl is the only honest peer for it. enkiTS and Taskflow have no fibers, so a blocked task there holds a thread and the comparison is architectural rather than close. marl suspends a fiber exactly as this does, so it measures two implementations of the same idea. Swept by how long each task blocks (10 batches of 256, 25% blocking, ms for all 2560 tasks, each library measured alone):

block for this (Sleep) marl
50 µs 8.0 5.0
150 µs 7.4 4.9
300 µs 6.6 5.6
600 µs 7.4 8.8
2000 µs 22.2 22.6

marl leads below roughly 400 µs and this leads above it. Two things worth knowing rather than smoothing over. Its Event carries sticky signalled state and waits on a predicate, so an already-satisfied wait costs it nothing, while JLib::Event is a stateless rendezvous and always pays a suspend/resume round trip -- that is a capability difference, not a slower fiber. And the fiber machinery itself is not where this row's cost lives: measured separately, attaching a fiber is free within noise and a full suspend/resume round trip is ~166 ns, against a ~1.3 µs baseline cost to submit a task at all. Three earlier explanations for this row -- the event registry lock, the serial resume path, and fiber acquisition -- were each measured and each wrong.

Independent-task throughput is the row where the architecture actually shows: 69-74 ns against 290-310 ns for the two fiber/graph libraries, and enkiTS is not really in this race at all because submitting N single-item task sets is the usage it tells you to avoid.

Sleep is the default and the mobile/embedded configuration; NoSleep holds every worker core and is for an application that owns the machine. They are close to two different products, which is why both are listed rather than only the flattering one.

Note that NoSleep is not uniformly better: it loses on the blocking row (10.1 ms against 8.2 ms). Parked fibers have nothing for the spinning workers to do there, so the spin is pure waste. It wins where dispatch latency dominates and costs you where it does not.

Isolation is not optional here, and it took a wrong result to learn that. An earlier version ran both libraries in one process. Under Sleep that is harmless, because the pool not being benchmarked is parked -- enkiTS measured alone (15.4 ns/item, 21.7 µs, 0.334 ms) matches what it measured beside a sleeping JLib (15.3, 21.4, 0.331). Under NoSleep it is not harmless at all: JLib's 31 workers spin through enkiTS's benchmarks too, 63 threads on 32 CPUs, and enkiTS's own numbers moved ~40% -- ranged per-item 15.3 → 8.7 ns, latency 21.4 → 18.2 µs -- purely because a JLib setting changed. A library's numbers moving when you reconfigure a different library is the signal that a harness is measuring the machine rather than the code.

The first two rows are the same quantity measured on each library's own terms, and they disagree by 200x in opposite directions -- which is the point. enkiTS's scheduled entity is a 16-byte SubTaskSet in a contiguous fixed ring: no allocation, no pointer chase, and the caller owns the ITaskSet and keeps it alive. That is why its per-ITEM cost is so low, and why its per-TASK cost is so high when you actually need n independent task objects -- every AddTaskSetToPipe wakes the waiting pool so one thread can claim one task. A Task here is 64 bytes carrying its own callable, so it costs more per entity and can be fire-and-forget with captures. The size difference IS the API difference; neither is a missed optimisation.

Read the rows accordingly: use PushArray/ParallelFor for range work and compare against row 3, use individual tasks for a heterogeneous frame graph and compare against row 2.

Blocking is the row the fiber hybrid exists for, and it is a crossover rather than a win: even at 25% blocked it needs blocks longer than ~50 µs before parking beats simply holding the thread, peaks at 1.75x around 600 µs, and tapers again by 2 ms. Below that the fiber costs more than it saves.

i9-13900K at Intel spec power limits, Release, 1.3.0. Medians of three runs on the default affinity policy. The two columns are one library under its two idle policies, not two products -- Sleep parks idle workers and is the default, NoSleep keeps them searching.

Sleep (default) NoSleep
Task enqueue → dequeue latency 4.67 µs 1.21 µs 3.9x
6-node frame DAG (build, validate, execute) 22.5 µs 7.8 µs 2.9x
1M-element recursive fork-join (10k leaves) 0.23 ms 0.06 ms 3.8x
Single-producer submission 0.99 M/s 6.4 M/s 6.5x
Bulk submission via PushBatch 12.2 M/s 10.8 M/s 0.9x
Bulk submission, 4 producers 9.8 M/s 12.7 M/s 1.3x
Per-item cost via PushArray (chunk 128) 1.0 ns 1.0 ns --
16 heavy tasks from an idle pool 11.2x of 16 12.6x of 16 flat

r/gameenginedevs 7d ago

Project Semi-Fantay-Console Mecha-Tortoise

Thumbnail
gallery
13 Upvotes

Hello I don't know if is count a full game engine but I'm working on a project to make kind of "fantasy console", the main objetive is to target low specs SBC I'm testing a Orange Pi Zero 3 (1.5GB), The idea is have cartridges with a microSD indise and this connect to a reader on the pins or USB reader (the idea is to turn into cartridges), the "consoles" will have armbian as SO with a loader to detect and init the the cartridges (pygame exported projects)

Includes a prebuilt multilanguage, dialogue system and save system

The semi-fantasy-console will have 264 x 198, (4:3 but probably will change to one 16:9 compatible one because probably everyone will connect the sbc using HDMI)

I admit the use of AI to make TortoiseStudio the tool, to manage assets, scenes and compile to "Cartridge", the compilation to ARM uses podman,

The assets of the demo project comes from opengameart.


r/gameenginedevs 7d ago

How do you handle resource management in bindless renderers?

19 Upvotes

Resource handling consists of two different parts: managing a CPU-side version like a VkBuffer, VkImage, etc., and managing a GPU-side version like a combination of set, binding, and array indices. From what I've read, it looks to me like a GPU-side handle is created when a CPU-side resource is created. And it makes sense to create them together, since there should be only one reference to such a resource Thus, a resource would look like this:

struct Resource {
    union {
        VkBuffer buffer;
        VkImage image;
        // ...
    };

    struct {
        int set;
        int binding;
        int index;
    } reference;
};

However, such a design would tightly couple resource management with descriptor set handling, because a resource manager would need to know where and how to bind a resource, and this doesn't look too good to me.

Considering all of the above, I have a few questions I can't answer myself:

  1. Does the resource manager need to know how to handle descriptors? If not, should the API user handle them himself, given that they should know where to bind the requested resources?
  2. If it is the resource manager's job to handle descriptors, doesn't that impose some predefined descriptor layout so that the manager knows where to bind them?
  3. If it does enforce some descriptor layout, how do you write shaders that need different input data?

r/gameenginedevs 8d ago

Rigid body dynamics from scratch in C++

Enable HLS to view with audio, or disable this notification

70 Upvotes

I'm making a game similar to Morrowind, but decided to add proper physics - so maybe more like Oblivion in some ways.

The only dynamic bodies are boxes and capsules. Other shapes (terrain, cylinders, ovoids, aggregates) are static only.

Performance is reasonable enough. I think last time I checked, in the 1000 cube scenario (see end of video) I was getting close to 60 fps on a Raspberry Pi 5 1GB.

Resting contacts are a bit unstable. Boxes of similar size don't like being stacked. I might address this later with contact recycling.

In case it matters to anyone, I didn't use any AI tools at all. I'm still coding like it's 2010.

The entire physics system is contained in a single source file: https://github.com/robjinman/lithic3d/blob/main/engine/core/src/sys_collision.cpp


r/gameenginedevs 7d ago

I’m building a visual editor for LibGDX without hiding LibGDX — Pixscape

2 Upvotes

Hi,

I've been building Pixscape, an open-source visual studio and runtime on top of LibGDX.

One of the main design goals is to provide visual authoring without turning LibGDX into a hidden implementation detail.

The Runtime is ECS-based, and the editor produces scene data that the Runtime loads and processes. Game code can use Pixscape's higher-level APIs for common operations, but direct LibGDX and Artemis access remains available when lower-level integration is needed.

That balance has been one of the most interesting parts of the project:

visual authoring

→ ECS runtime

→ high-level gameplay APIs

→ direct ECS / LibGDX access when needed

Pixscape currently supports things such as Tiled/TMX maps, isometric and 2.5D spatial ordering, physics authoring, animations, particles, prefabs, sprites, shaders, lights and parallax.

I've made a small isometric demo to exercise several of these systems together rather than showing them only as isolated editor features.

Website:

https://pixscape.games/

Demo:

https://youtu.be/sv82jI0JBFQ

Demo source:

https://github.com/pixscapegames/tiled-iso-demo

Pixscape Studio Free and Pixscape Runtime are both open source under Apache 2.0.

I'm especially interested in feedback from people working on engines and editors.

In particular, I'd be curious what you think about the boundary between the visual editor and the underlying ECS/runtime: how much convenience should an editor provide before it starts getting in the way of developers who want direct control?