Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Repository files navigation

SG Engine (toy engine)

For now, this is just a toy engine, with many missing features, and breaks every 3 minutes.

Demo

IMAGE ALT TEXT HERE

This project is intended to be my first stab at a complete game engine - but it is by no means complete yet. The main ideas around architecture are:

  • Modular system design - allowing hot code loading
  • composition over inheritance (but it's Rust so of course)

What works:

  • Module runtime reloading
  • Vulkan rendering using vulkano
  • Scene graph (Rc-based ADG) and push-constants
  • Loading obj models using nom-obj
  • Diffuse textures, UVW coordinates

To do:

  • Multiple textures
  • Extremely inefficient shaders (per-vertex matrix operations, for no good reason)
  • pretty much anything else...

As I said, this is very much a work in progress, but I'd love input or PRs or criticism.

My *opinionated architecture

*We all have our opinions. :)

Hot loading

For any project that I work on, I like to move quickly and try ideas fast. I'm a monkey coder; I bash on this part and that until I get things to work. I don't want to wait for a full-compile cycle to try out a new idea... So a lot of my effort is spent in this library to optimize for that case. One way to do this is to reload sections of the program at runtime.

Credits for inspiration:

- [null program](http://nullprogram.com/blog/2014/12/23/)
- [handmade hero](https://handmadehero.org/)

game_state

The system is comprised of a base library for shared state, in addition to modules. game_state defines all shared, base types in the system, including the most global State, but also shared types and traits defining behavior and structure of input, ui, events, rendering, world entities, etc.

The State struct is central to the design, as it represents the state the game passes between each module. This allows each module, when not operating on the state, to be reloaded and the old state they are responsible for to be cleared. The actual loading of the modules is handled in the main project under src/libloading.

Access traits

Several traits are defined and implemented on State to serve as a window of responsibility for common operations on the State object itself. This decouples the modules from any exact internal structure of State, but also allows common functionality to be shared between access traits. At a higher level, access traits to State serve as a way for a mod to state which aspects of State it really wants access to.

Modules

Modules are compiled rust code, but are loaded at runtime and can be modified during the course of execution. When a new version is built, it will be picked up by libloading and loaded, while the old library will be unloaded.

In contrast, any changes to the game_state crate or it's dependencies (nom-obj - an .obj model parser, for instance) will need everything to be rebuilt that depends on it, otherwise strange things may happen, or worse.

mod_dummy

This is a template mod, and is not built or linked, but rather serves as a starting point for creating a new mod.

mod_asset_loader

A simple mod intended to load assets and prepare them for use by attaching them to the State object.

Access traits used: RenderLayerAccess

TODO:

  • Expand on asset loading strategy

mod_input

This module is responsible for coordinating and gathering input events in the internal format described in game_state::input.

Access traits used: InputAccess

TODO:

  • Gather input from joysticks
  • ...

mod_rendering_x

Responsible for the implementation of renderers, adding the capacity for orthogonal changes to each renderer at runtime. Of course the renderers need to know how to clean themselves up in addition to initialize.

Renderer Status:

  • VulkanRenderer - model and texture loading, needs work to expand asset pipeline support
  • OpenGLRenderer - Stubbed, little more

Access Traits Used:

  • RenderAccess
  • RenderLayerAccess

TODO:

  • Implement OpenGL renderer so this can run on any machine supporting OpenGL
  • Renderer specific, but lots of work needs to be done here, probably dependent on mod_asset_loader and expansion of access traits
  • Software renderer

mod_simulation

Simulation of the game world itself.

Access Traits Used: SimulationAccess

Todo:

  • everything - this mod is just stubbed at this point

Building on linux

Dependencies:

  • libudev-dev
  • libsdl2-dev
  • python-is-python3

Environment

You may have to set

export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

Or similar, depending on your device.

About

Modularized (hot-swapping) game engine in Rust

Topics

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - dwerner/sg-engine: Modularized (hot-swapping) game engine in Rust · GitHub
Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Repository files navigation

SG Engine (toy engine)

For now, this is just a toy engine, with many missing features, and breaks every 3 minutes.

Demo

IMAGE ALT TEXT HERE

This project is intended to be my first stab at a complete game engine - but it is by no means complete yet. The main ideas around architecture are:

  • Modular system design - allowing hot code loading
  • composition over inheritance (but it's Rust so of course)

What works:

  • Module runtime reloading
  • Vulkan rendering using vulkano
  • Scene graph (Rc-based ADG) and push-constants
  • Loading obj models using nom-obj
  • Diffuse textures, UVW coordinates

To do:

  • Multiple textures
  • Extremely inefficient shaders (per-vertex matrix operations, for no good reason)
  • pretty much anything else...

As I said, this is very much a work in progress, but I'd love input or PRs or criticism.

My *opinionated architecture

*We all have our opinions. :)

Hot loading

For any project that I work on, I like to move quickly and try ideas fast. I'm a monkey coder; I bash on this part and that until I get things to work. I don't want to wait for a full-compile cycle to try out a new idea... So a lot of my effort is spent in this library to optimize for that case. One way to do this is to reload sections of the program at runtime.

Credits for inspiration:

- [null program](http://nullprogram.com/blog/2014/12/23/)
- [handmade hero](https://handmadehero.org/)

game_state

The system is comprised of a base library for shared state, in addition to modules. game_state defines all shared, base types in the system, including the most global State, but also shared types and traits defining behavior and structure of input, ui, events, rendering, world entities, etc.

The State struct is central to the design, as it represents the state the game passes between each module. This allows each module, when not operating on the state, to be reloaded and the old state they are responsible for to be cleared. The actual loading of the modules is handled in the main project under src/libloading.

Access traits

Several traits are defined and implemented on State to serve as a window of responsibility for common operations on the State object itself. This decouples the modules from any exact internal structure of State, but also allows common functionality to be shared between access traits. At a higher level, access traits to State serve as a way for a mod to state which aspects of State it really wants access to.

Modules

Modules are compiled rust code, but are loaded at runtime and can be modified during the course of execution. When a new version is built, it will be picked up by libloading and loaded, while the old library will be unloaded.

In contrast, any changes to the game_state crate or it's dependencies (nom-obj - an .obj model parser, for instance) will need everything to be rebuilt that depends on it, otherwise strange things may happen, or worse.

mod_dummy

This is a template mod, and is not built or linked, but rather serves as a starting point for creating a new mod.

mod_asset_loader

A simple mod intended to load assets and prepare them for use by attaching them to the State object.

Access traits used: RenderLayerAccess

TODO:

  • Expand on asset loading strategy

mod_input

This module is responsible for coordinating and gathering input events in the internal format described in game_state::input.

Access traits used: InputAccess

TODO:

  • Gather input from joysticks
  • ...

mod_rendering_x

Responsible for the implementation of renderers, adding the capacity for orthogonal changes to each renderer at runtime. Of course the renderers need to know how to clean themselves up in addition to initialize.

Renderer Status:

  • VulkanRenderer - model and texture loading, needs work to expand asset pipeline support
  • OpenGLRenderer - Stubbed, little more

Access Traits Used:

  • RenderAccess
  • RenderLayerAccess

TODO:

  • Implement OpenGL renderer so this can run on any machine supporting OpenGL
  • Renderer specific, but lots of work needs to be done here, probably dependent on mod_asset_loader and expansion of access traits
  • Software renderer

mod_simulation

Simulation of the game world itself.

Access Traits Used: SimulationAccess

Todo:

  • everything - this mod is just stubbed at this point

Building on linux

Dependencies:

  • libudev-dev
  • libsdl2-dev
  • python-is-python3

Environment

You may have to set

export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

Or similar, depending on your device.

About

Modularized (hot-swapping) game engine in Rust

Topics

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - dwerner/sg-engine: Modularized (hot-swapping) game engine in Rust · GitHub
Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Repository files navigation

SG Engine (toy engine)

For now, this is just a toy engine, with many missing features, and breaks every 3 minutes.

Demo

IMAGE ALT TEXT HERE

This project is intended to be my first stab at a complete game engine - but it is by no means complete yet. The main ideas around architecture are:

  • Modular system design - allowing hot code loading
  • composition over inheritance (but it's Rust so of course)

What works:

  • Module runtime reloading
  • Vulkan rendering using vulkano
  • Scene graph (Rc-based ADG) and push-constants
  • Loading obj models using nom-obj
  • Diffuse textures, UVW coordinates

To do:

  • Multiple textures
  • Extremely inefficient shaders (per-vertex matrix operations, for no good reason)
  • pretty much anything else...

As I said, this is very much a work in progress, but I'd love input or PRs or criticism.

My *opinionated architecture

*We all have our opinions. :)

Hot loading

For any project that I work on, I like to move quickly and try ideas fast. I'm a monkey coder; I bash on this part and that until I get things to work. I don't want to wait for a full-compile cycle to try out a new idea... So a lot of my effort is spent in this library to optimize for that case. One way to do this is to reload sections of the program at runtime.

Credits for inspiration:

- [null program](http://nullprogram.com/blog/2014/12/23/)
- [handmade hero](https://handmadehero.org/)

game_state

The system is comprised of a base library for shared state, in addition to modules. game_state defines all shared, base types in the system, including the most global State, but also shared types and traits defining behavior and structure of input, ui, events, rendering, world entities, etc.

The State struct is central to the design, as it represents the state the game passes between each module. This allows each module, when not operating on the state, to be reloaded and the old state they are responsible for to be cleared. The actual loading of the modules is handled in the main project under src/libloading.

Access traits

Several traits are defined and implemented on State to serve as a window of responsibility for common operations on the State object itself. This decouples the modules from any exact internal structure of State, but also allows common functionality to be shared between access traits. At a higher level, access traits to State serve as a way for a mod to state which aspects of State it really wants access to.

Modules

Modules are compiled rust code, but are loaded at runtime and can be modified during the course of execution. When a new version is built, it will be picked up by libloading and loaded, while the old library will be unloaded.

In contrast, any changes to the game_state crate or it's dependencies (nom-obj - an .obj model parser, for instance) will need everything to be rebuilt that depends on it, otherwise strange things may happen, or worse.

mod_dummy

This is a template mod, and is not built or linked, but rather serves as a starting point for creating a new mod.

mod_asset_loader

A simple mod intended to load assets and prepare them for use by attaching them to the State object.

Access traits used: RenderLayerAccess

TODO:

  • Expand on asset loading strategy

mod_input

This module is responsible for coordinating and gathering input events in the internal format described in game_state::input.

Access traits used: InputAccess

TODO:

  • Gather input from joysticks
  • ...

mod_rendering_x

Responsible for the implementation of renderers, adding the capacity for orthogonal changes to each renderer at runtime. Of course the renderers need to know how to clean themselves up in addition to initialize.

Renderer Status:

  • VulkanRenderer - model and texture loading, needs work to expand asset pipeline support
  • OpenGLRenderer - Stubbed, little more

Access Traits Used:

  • RenderAccess
  • RenderLayerAccess

TODO:

  • Implement OpenGL renderer so this can run on any machine supporting OpenGL
  • Renderer specific, but lots of work needs to be done here, probably dependent on mod_asset_loader and expansion of access traits
  • Software renderer

mod_simulation

Simulation of the game world itself.

Access Traits Used: SimulationAccess

Todo:

  • everything - this mod is just stubbed at this point

Building on linux

Dependencies:

  • libudev-dev
  • libsdl2-dev
  • python-is-python3

Environment

You may have to set

export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

Or similar, depending on your device.

About

Modularized (hot-swapping) game engine in Rust

Topics

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - dwerner/sg-engine: Modularized (hot-swapping) game engine in Rust · GitHub
Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Repository files navigation

SG Engine (toy engine)

For now, this is just a toy engine, with many missing features, and breaks every 3 minutes.

Demo

IMAGE ALT TEXT HERE

This project is intended to be my first stab at a complete game engine - but it is by no means complete yet. The main ideas around architecture are:

  • Modular system design - allowing hot code loading
  • composition over inheritance (but it's Rust so of course)

What works:

  • Module runtime reloading
  • Vulkan rendering using vulkano
  • Scene graph (Rc-based ADG) and push-constants
  • Loading obj models using nom-obj
  • Diffuse textures, UVW coordinates

To do:

  • Multiple textures
  • Extremely inefficient shaders (per-vertex matrix operations, for no good reason)
  • pretty much anything else...

As I said, this is very much a work in progress, but I'd love input or PRs or criticism.

My *opinionated architecture

*We all have our opinions. :)

Hot loading

For any project that I work on, I like to move quickly and try ideas fast. I'm a monkey coder; I bash on this part and that until I get things to work. I don't want to wait for a full-compile cycle to try out a new idea... So a lot of my effort is spent in this library to optimize for that case. One way to do this is to reload sections of the program at runtime.

Credits for inspiration:

- [null program](http://nullprogram.com/blog/2014/12/23/)
- [handmade hero](https://handmadehero.org/)

game_state

The system is comprised of a base library for shared state, in addition to modules. game_state defines all shared, base types in the system, including the most global State, but also shared types and traits defining behavior and structure of input, ui, events, rendering, world entities, etc.

The State struct is central to the design, as it represents the state the game passes between each module. This allows each module, when not operating on the state, to be reloaded and the old state they are responsible for to be cleared. The actual loading of the modules is handled in the main project under src/libloading.

Access traits

Several traits are defined and implemented on State to serve as a window of responsibility for common operations on the State object itself. This decouples the modules from any exact internal structure of State, but also allows common functionality to be shared between access traits. At a higher level, access traits to State serve as a way for a mod to state which aspects of State it really wants access to.

Modules

Modules are compiled rust code, but are loaded at runtime and can be modified during the course of execution. When a new version is built, it will be picked up by libloading and loaded, while the old library will be unloaded.

In contrast, any changes to the game_state crate or it's dependencies (nom-obj - an .obj model parser, for instance) will need everything to be rebuilt that depends on it, otherwise strange things may happen, or worse.

mod_dummy

This is a template mod, and is not built or linked, but rather serves as a starting point for creating a new mod.

mod_asset_loader

A simple mod intended to load assets and prepare them for use by attaching them to the State object.

Access traits used: RenderLayerAccess

TODO:

  • Expand on asset loading strategy

mod_input

This module is responsible for coordinating and gathering input events in the internal format described in game_state::input.

Access traits used: InputAccess

TODO:

  • Gather input from joysticks
  • ...

mod_rendering_x

Responsible for the implementation of renderers, adding the capacity for orthogonal changes to each renderer at runtime. Of course the renderers need to know how to clean themselves up in addition to initialize.

Renderer Status:

  • VulkanRenderer - model and texture loading, needs work to expand asset pipeline support
  • OpenGLRenderer - Stubbed, little more

Access Traits Used:

  • RenderAccess
  • RenderLayerAccess

TODO:

  • Implement OpenGL renderer so this can run on any machine supporting OpenGL
  • Renderer specific, but lots of work needs to be done here, probably dependent on mod_asset_loader and expansion of access traits
  • Software renderer

mod_simulation

Simulation of the game world itself.

Access Traits Used: SimulationAccess

Todo:

  • everything - this mod is just stubbed at this point

Building on linux

Dependencies:

  • libudev-dev
  • libsdl2-dev
  • python-is-python3

Environment

You may have to set

export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

Or similar, depending on your device.

About

Modularized (hot-swapping) game engine in Rust

Topics

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - dwerner/sg-engine: Modularized (hot-swapping) game engine in Rust · GitHub
Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Repository files navigation

SG Engine (toy engine)

For now, this is just a toy engine, with many missing features, and breaks every 3 minutes.

Demo

IMAGE ALT TEXT HERE

This project is intended to be my first stab at a complete game engine - but it is by no means complete yet. The main ideas around architecture are:

  • Modular system design - allowing hot code loading
  • composition over inheritance (but it's Rust so of course)

What works:

  • Module runtime reloading
  • Vulkan rendering using vulkano
  • Scene graph (Rc-based ADG) and push-constants
  • Loading obj models using nom-obj
  • Diffuse textures, UVW coordinates

To do:

  • Multiple textures
  • Extremely inefficient shaders (per-vertex matrix operations, for no good reason)
  • pretty much anything else...

As I said, this is very much a work in progress, but I'd love input or PRs or criticism.

My *opinionated architecture

*We all have our opinions. :)

Hot loading

For any project that I work on, I like to move quickly and try ideas fast. I'm a monkey coder; I bash on this part and that until I get things to work. I don't want to wait for a full-compile cycle to try out a new idea... So a lot of my effort is spent in this library to optimize for that case. One way to do this is to reload sections of the program at runtime.

Credits for inspiration:

- [null program](http://nullprogram.com/blog/2014/12/23/)
- [handmade hero](https://handmadehero.org/)

game_state

The system is comprised of a base library for shared state, in addition to modules. game_state defines all shared, base types in the system, including the most global State, but also shared types and traits defining behavior and structure of input, ui, events, rendering, world entities, etc.

The State struct is central to the design, as it represents the state the game passes between each module. This allows each module, when not operating on the state, to be reloaded and the old state they are responsible for to be cleared. The actual loading of the modules is handled in the main project under src/libloading.

Access traits

Several traits are defined and implemented on State to serve as a window of responsibility for common operations on the State object itself. This decouples the modules from any exact internal structure of State, but also allows common functionality to be shared between access traits. At a higher level, access traits to State serve as a way for a mod to state which aspects of State it really wants access to.

Modules

Modules are compiled rust code, but are loaded at runtime and can be modified during the course of execution. When a new version is built, it will be picked up by libloading and loaded, while the old library will be unloaded.

In contrast, any changes to the game_state crate or it's dependencies (nom-obj - an .obj model parser, for instance) will need everything to be rebuilt that depends on it, otherwise strange things may happen, or worse.

mod_dummy

This is a template mod, and is not built or linked, but rather serves as a starting point for creating a new mod.

mod_asset_loader

A simple mod intended to load assets and prepare them for use by attaching them to the State object.

Access traits used: RenderLayerAccess

TODO:

  • Expand on asset loading strategy

mod_input

This module is responsible for coordinating and gathering input events in the internal format described in game_state::input.

Access traits used: InputAccess

TODO:

  • Gather input from joysticks
  • ...

mod_rendering_x

Responsible for the implementation of renderers, adding the capacity for orthogonal changes to each renderer at runtime. Of course the renderers need to know how to clean themselves up in addition to initialize.

Renderer Status:

  • VulkanRenderer - model and texture loading, needs work to expand asset pipeline support
  • OpenGLRenderer - Stubbed, little more

Access Traits Used:

  • RenderAccess
  • RenderLayerAccess

TODO:

  • Implement OpenGL renderer so this can run on any machine supporting OpenGL
  • Renderer specific, but lots of work needs to be done here, probably dependent on mod_asset_loader and expansion of access traits
  • Software renderer

mod_simulation

Simulation of the game world itself.

Access Traits Used: SimulationAccess

Todo:

  • everything - this mod is just stubbed at this point

Building on linux

Dependencies:

  • libudev-dev
  • libsdl2-dev
  • python-is-python3

Environment

You may have to set

export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

Or similar, depending on your device.

About

Modularized (hot-swapping) game engine in Rust

Topics

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - dwerner/sg-engine: Modularized (hot-swapping) game engine in Rust · GitHub
Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Repository files navigation

SG Engine (toy engine)

For now, this is just a toy engine, with many missing features, and breaks every 3 minutes.

Demo

IMAGE ALT TEXT HERE

This project is intended to be my first stab at a complete game engine - but it is by no means complete yet. The main ideas around architecture are:

  • Modular system design - allowing hot code loading
  • composition over inheritance (but it's Rust so of course)

What works:

  • Module runtime reloading
  • Vulkan rendering using vulkano
  • Scene graph (Rc-based ADG) and push-constants
  • Loading obj models using nom-obj
  • Diffuse textures, UVW coordinates

To do:

  • Multiple textures
  • Extremely inefficient shaders (per-vertex matrix operations, for no good reason)
  • pretty much anything else...

As I said, this is very much a work in progress, but I'd love input or PRs or criticism.

My *opinionated architecture

*We all have our opinions. :)

Hot loading

For any project that I work on, I like to move quickly and try ideas fast. I'm a monkey coder; I bash on this part and that until I get things to work. I don't want to wait for a full-compile cycle to try out a new idea... So a lot of my effort is spent in this library to optimize for that case. One way to do this is to reload sections of the program at runtime.

Credits for inspiration:

- [null program](http://nullprogram.com/blog/2014/12/23/)
- [handmade hero](https://handmadehero.org/)

game_state

The system is comprised of a base library for shared state, in addition to modules. game_state defines all shared, base types in the system, including the most global State, but also shared types and traits defining behavior and structure of input, ui, events, rendering, world entities, etc.

The State struct is central to the design, as it represents the state the game passes between each module. This allows each module, when not operating on the state, to be reloaded and the old state they are responsible for to be cleared. The actual loading of the modules is handled in the main project under src/libloading.

Access traits

Several traits are defined and implemented on State to serve as a window of responsibility for common operations on the State object itself. This decouples the modules from any exact internal structure of State, but also allows common functionality to be shared between access traits. At a higher level, access traits to State serve as a way for a mod to state which aspects of State it really wants access to.

Modules

Modules are compiled rust code, but are loaded at runtime and can be modified during the course of execution. When a new version is built, it will be picked up by libloading and loaded, while the old library will be unloaded.

In contrast, any changes to the game_state crate or it's dependencies (nom-obj - an .obj model parser, for instance) will need everything to be rebuilt that depends on it, otherwise strange things may happen, or worse.

mod_dummy

This is a template mod, and is not built or linked, but rather serves as a starting point for creating a new mod.

mod_asset_loader

A simple mod intended to load assets and prepare them for use by attaching them to the State object.

Access traits used: RenderLayerAccess

TODO:

  • Expand on asset loading strategy

mod_input

This module is responsible for coordinating and gathering input events in the internal format described in game_state::input.

Access traits used: InputAccess

TODO:

  • Gather input from joysticks
  • ...

mod_rendering_x

Responsible for the implementation of renderers, adding the capacity for orthogonal changes to each renderer at runtime. Of course the renderers need to know how to clean themselves up in addition to initialize.

Renderer Status:

  • VulkanRenderer - model and texture loading, needs work to expand asset pipeline support
  • OpenGLRenderer - Stubbed, little more

Access Traits Used:

  • RenderAccess
  • RenderLayerAccess

TODO:

  • Implement OpenGL renderer so this can run on any machine supporting OpenGL
  • Renderer specific, but lots of work needs to be done here, probably dependent on mod_asset_loader and expansion of access traits
  • Software renderer

mod_simulation

Simulation of the game world itself.

Access Traits Used: SimulationAccess

Todo:

  • everything - this mod is just stubbed at this point

Building on linux

Dependencies:

  • libudev-dev
  • libsdl2-dev
  • python-is-python3

Environment

You may have to set

export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

Or similar, depending on your device.

About

Modularized (hot-swapping) game engine in Rust

Topics

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - dwerner/sg-engine: Modularized (hot-swapping) game engine in Rust · GitHub
Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Repository files navigation

SG Engine (toy engine)

For now, this is just a toy engine, with many missing features, and breaks every 3 minutes.

Demo

IMAGE ALT TEXT HERE

This project is intended to be my first stab at a complete game engine - but it is by no means complete yet. The main ideas around architecture are:

  • Modular system design - allowing hot code loading
  • composition over inheritance (but it's Rust so of course)

What works:

  • Module runtime reloading
  • Vulkan rendering using vulkano
  • Scene graph (Rc-based ADG) and push-constants
  • Loading obj models using nom-obj
  • Diffuse textures, UVW coordinates

To do:

  • Multiple textures
  • Extremely inefficient shaders (per-vertex matrix operations, for no good reason)
  • pretty much anything else...

As I said, this is very much a work in progress, but I'd love input or PRs or criticism.

My *opinionated architecture

*We all have our opinions. :)

Hot loading

For any project that I work on, I like to move quickly and try ideas fast. I'm a monkey coder; I bash on this part and that until I get things to work. I don't want to wait for a full-compile cycle to try out a new idea... So a lot of my effort is spent in this library to optimize for that case. One way to do this is to reload sections of the program at runtime.

Credits for inspiration:

- [null program](http://nullprogram.com/blog/2014/12/23/)
- [handmade hero](https://handmadehero.org/)

game_state

The system is comprised of a base library for shared state, in addition to modules. game_state defines all shared, base types in the system, including the most global State, but also shared types and traits defining behavior and structure of input, ui, events, rendering, world entities, etc.

The State struct is central to the design, as it represents the state the game passes between each module. This allows each module, when not operating on the state, to be reloaded and the old state they are responsible for to be cleared. The actual loading of the modules is handled in the main project under src/libloading.

Access traits

Several traits are defined and implemented on State to serve as a window of responsibility for common operations on the State object itself. This decouples the modules from any exact internal structure of State, but also allows common functionality to be shared between access traits. At a higher level, access traits to State serve as a way for a mod to state which aspects of State it really wants access to.

Modules

Modules are compiled rust code, but are loaded at runtime and can be modified during the course of execution. When a new version is built, it will be picked up by libloading and loaded, while the old library will be unloaded.

In contrast, any changes to the game_state crate or it's dependencies (nom-obj - an .obj model parser, for instance) will need everything to be rebuilt that depends on it, otherwise strange things may happen, or worse.

mod_dummy

This is a template mod, and is not built or linked, but rather serves as a starting point for creating a new mod.

mod_asset_loader

A simple mod intended to load assets and prepare them for use by attaching them to the State object.

Access traits used: RenderLayerAccess

TODO:

  • Expand on asset loading strategy

mod_input

This module is responsible for coordinating and gathering input events in the internal format described in game_state::input.

Access traits used: InputAccess

TODO:

  • Gather input from joysticks
  • ...

mod_rendering_x

Responsible for the implementation of renderers, adding the capacity for orthogonal changes to each renderer at runtime. Of course the renderers need to know how to clean themselves up in addition to initialize.

Renderer Status:

  • VulkanRenderer - model and texture loading, needs work to expand asset pipeline support
  • OpenGLRenderer - Stubbed, little more

Access Traits Used:

  • RenderAccess
  • RenderLayerAccess

TODO:

  • Implement OpenGL renderer so this can run on any machine supporting OpenGL
  • Renderer specific, but lots of work needs to be done here, probably dependent on mod_asset_loader and expansion of access traits
  • Software renderer

mod_simulation

Simulation of the game world itself.

Access Traits Used: SimulationAccess

Todo:

  • everything - this mod is just stubbed at this point

Building on linux

Dependencies:

  • libudev-dev
  • libsdl2-dev
  • python-is-python3

Environment

You may have to set

export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

Or similar, depending on your device.

About

Modularized (hot-swapping) game engine in Rust

Topics

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - dwerner/sg-engine: Modularized (hot-swapping) game engine in Rust · GitHub
Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Repository files navigation

SG Engine (toy engine)

For now, this is just a toy engine, with many missing features, and breaks every 3 minutes.

Demo

IMAGE ALT TEXT HERE

This project is intended to be my first stab at a complete game engine - but it is by no means complete yet. The main ideas around architecture are:

  • Modular system design - allowing hot code loading
  • composition over inheritance (but it's Rust so of course)

What works:

  • Module runtime reloading
  • Vulkan rendering using vulkano
  • Scene graph (Rc-based ADG) and push-constants
  • Loading obj models using nom-obj
  • Diffuse textures, UVW coordinates

To do:

  • Multiple textures
  • Extremely inefficient shaders (per-vertex matrix operations, for no good reason)
  • pretty much anything else...

As I said, this is very much a work in progress, but I'd love input or PRs or criticism.

My *opinionated architecture

*We all have our opinions. :)

Hot loading

For any project that I work on, I like to move quickly and try ideas fast. I'm a monkey coder; I bash on this part and that until I get things to work. I don't want to wait for a full-compile cycle to try out a new idea... So a lot of my effort is spent in this library to optimize for that case. One way to do this is to reload sections of the program at runtime.

Credits for inspiration:

- [null program](http://nullprogram.com/blog/2014/12/23/)
- [handmade hero](https://handmadehero.org/)

game_state

The system is comprised of a base library for shared state, in addition to modules. game_state defines all shared, base types in the system, including the most global State, but also shared types and traits defining behavior and structure of input, ui, events, rendering, world entities, etc.

The State struct is central to the design, as it represents the state the game passes between each module. This allows each module, when not operating on the state, to be reloaded and the old state they are responsible for to be cleared. The actual loading of the modules is handled in the main project under src/libloading.

Access traits

Several traits are defined and implemented on State to serve as a window of responsibility for common operations on the State object itself. This decouples the modules from any exact internal structure of State, but also allows common functionality to be shared between access traits. At a higher level, access traits to State serve as a way for a mod to state which aspects of State it really wants access to.

Modules

Modules are compiled rust code, but are loaded at runtime and can be modified during the course of execution. When a new version is built, it will be picked up by libloading and loaded, while the old library will be unloaded.

In contrast, any changes to the game_state crate or it's dependencies (nom-obj - an .obj model parser, for instance) will need everything to be rebuilt that depends on it, otherwise strange things may happen, or worse.

mod_dummy

This is a template mod, and is not built or linked, but rather serves as a starting point for creating a new mod.

mod_asset_loader

A simple mod intended to load assets and prepare them for use by attaching them to the State object.

Access traits used: RenderLayerAccess

TODO:

  • Expand on asset loading strategy

mod_input

This module is responsible for coordinating and gathering input events in the internal format described in game_state::input.

Access traits used: InputAccess

TODO:

  • Gather input from joysticks
  • ...

mod_rendering_x

Responsible for the implementation of renderers, adding the capacity for orthogonal changes to each renderer at runtime. Of course the renderers need to know how to clean themselves up in addition to initialize.

Renderer Status:

  • VulkanRenderer - model and texture loading, needs work to expand asset pipeline support
  • OpenGLRenderer - Stubbed, little more

Access Traits Used:

  • RenderAccess
  • RenderLayerAccess

TODO:

  • Implement OpenGL renderer so this can run on any machine supporting OpenGL
  • Renderer specific, but lots of work needs to be done here, probably dependent on mod_asset_loader and expansion of access traits
  • Software renderer

mod_simulation

Simulation of the game world itself.

Access Traits Used: SimulationAccess

Todo:

  • everything - this mod is just stubbed at this point

Building on linux

Dependencies:

  • libudev-dev
  • libsdl2-dev
  • python-is-python3

Environment

You may have to set

export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json

Or similar, depending on your device.

About

Modularized (hot-swapping) game engine in Rust

Topics

Resources

Stars

19 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages