Current design decisions for my game engine:
-
AABBs (partially) implemented
They don't support scaling and rotations yet, but for starters it's good enough for (1) visualizing selected nodes and (2) testing raycasts from the cursor position against.
Got node selection working, without a physics engine or CPU-side triangle raycasting! Used this idea from a colleague:
- Put mouse position and node ID into push constants
- In the fragment shader, check if current pixel is under the mouse
- If so, write node ID and depth into a list in a storage buffer
- On CPU, read back the buffer and sort by depthUpside: No need for AABB testing, proxy meshes, or duplicating skinning code on the CPU
Downside: Has to be included in most shaders
-
Got node selection working, without a physics engine or CPU-side triangle raycasting! Used this idea from a colleague:
- Put mouse position and node ID into push constants
- In the fragment shader, check if current pixel is under the mouse
- If so, write node ID and depth into a list in a storage buffer
- On CPU, read back the buffer and sort by depthUpside: No need for AABB testing, proxy meshes, or duplicating skinning code on the CPU
Downside: Has to be included in most shaders
Weekend progress update: we have a transform gizmo!
It can't actually transform anything yet but it jumps to the average position of the selected nodes and disappears when nothing is selected.
-
Weekend progress update: we have a transform gizmo!
It can't actually transform anything yet but it jumps to the average position of the selected nodes and disappears when nothing is selected.
Bonus screenshot: one of the fun things that can happen when you mess up and bind invalid descriptor handles. Had a lot of GPU hangs today :P
-
Bonus screenshot: one of the fun things that can happen when you mess up and bind invalid descriptor handles. Had a lot of GPU hangs today :P
The translate gizmo is now functional :D
-
For a second there I thought my refactor of the materials system just worked on first try, but no, it only seemed to work by accident and now my GPU crashed. Time to go to bed :D
-
For a second there I thought my refactor of the materials system just worked on first try, but no, it only seemed to work by accident and now my GPU crashed. Time to go to bed :D
The refactor being: First I had a global buffer of materials with albedo color, roughness, metallic, bindless texture indices etc that's always bound to every shader and I pass a material ID via push constants with each object. But not every material is PBR, there's going to be custom shaders using different data. So now the global buffer is an array of pointers to material buffers of different types, and I send an additional material type index via push constants as well.
-
The refactor being: First I had a global buffer of materials with albedo color, roughness, metallic, bindless texture indices etc that's always bound to every shader and I pass a material ID via push constants with each object. But not every material is PBR, there's going to be custom shaders using different data. So now the global buffer is an array of pointers to material buffers of different types, and I send an additional material type index via push constants as well.
Update:
- Proper dynamic point lights based on nodes (previously the light was just hardcoded in the fragment shader)
- Billboard shader
- Badly drawn icons for point lights in the editor using billboard shader
- Icons have the color of the light -
Update:
- Proper dynamic point lights based on nodes (previously the light was just hardcoded in the fragment shader)
- Billboard shader
- Badly drawn icons for point lights in the editor using billboard shader
- Icons have the color of the lightUpdate: KTX2 texture support. Smaller VRAM usage due to GPU block encoding, much faster loading times since I also downscaled some textures, and much better looking textures from afar due to mimapping that comes for free (the toktx tool I use to convert to ktx can automatically generate them).
Conversion to KTX isn't automated yet, but I hope to do that as part of the import process in the future.
Again mostly copied from the old engine and slightly adjusted
-
Update: KTX2 texture support. Smaller VRAM usage due to GPU block encoding, much faster loading times since I also downscaled some textures, and much better looking textures from afar due to mimapping that comes for free (the toktx tool I use to convert to ktx can automatically generate them).
Conversion to KTX isn't automated yet, but I hope to do that as part of the import process in the future.
Again mostly copied from the old engine and slightly adjusted
The temptation to rush ahead and implement the the fun stuff is real :§ But before that I really gotta make a proof of concept at least for a core architectural system.
In Godot you have individual .tres / .tscn files for custom resources and scenes. I want to instead use a single SQL database for everything (or at very least for resources like items etc., but ideally also for whole scene hierarchies). That idea needs testing.
-
The temptation to rush ahead and implement the the fun stuff is real :§ But before that I really gotta make a proof of concept at least for a core architectural system.
In Godot you have individual .tres / .tscn files for custom resources and scenes. I want to instead use a single SQL database for everything (or at very least for resources like items etc., but ideally also for whole scene hierarchies). That idea needs testing.
Mods would then just be collections of insert / update statements. Upside is you could very easily modify the whole game based on complex parameters, like dimming all light sources in dungeons or changing the stats city guards based on the economic status of the town they're posted in calculated by the wealth of local shopkeepers, in a single SQL statement. No need to touch hundreds of files.
-
Mods would then just be collections of insert / update statements. Upside is you could very easily modify the whole game based on complex parameters, like dimming all light sources in dungeons or changing the stats city guards based on the economic status of the town they're posted in calculated by the wealth of local shopkeepers, in a single SQL statement. No need to touch hundreds of files.
Downside is I'm lazy and only want to maintain a single source of truth regarding data structure, so I'm experimenting with automatically generating an SQL table for every data class in my game by analyzing source code (with annotations). Let's see how that goes!
-
Downside is I'm lazy and only want to maintain a single source of truth regarding data structure, so I'm experimenting with automatically generating an SQL table for every data class in my game by analyzing source code (with annotations). Let's see how that goes!
Testing it by making a tiny text-based RPG in a separate project first. Depending on how much fun that is it will either stay a tech demo or become something to practice writing as well. Could be like a demo to put on itch to give a preview of the world and its characters.
-
Testing it by making a tiny text-based RPG in a separate project first. Depending on how much fun that is it will either stay a tech demo or become something to practice writing as well. Could be like a demo to put on itch to give a preview of the world and its characters.
Slowly hacking away at prototyping a data resource system that's backed by sqlite. Not really sure what I'm doing...
Currently I have C++ classes representing data which have an equivalent table in the database. The classes have a static getter taking the ID as input. This does a select statememt on the DB, creates an instance of the class, puts it into a pool, and returns a handle to get a reference to the instance.
-
Slowly hacking away at prototyping a data resource system that's backed by sqlite. Not really sure what I'm doing...
Currently I have C++ classes representing data which have an equivalent table in the database. The classes have a static getter taking the ID as input. This does a select statememt on the DB, creates an instance of the class, puts it into a pool, and returns a handle to get a reference to the instance.
I'm wondering how to handle relations between classes / tables. E.g. Actors have an inventory of Items. I know how to represent this on the DB, but on the C++ side I need to replace the foreign keys and utility tables for many-to-many relations with arrays of handles / pointers etc. But how much do I want to load into memory? Loading an actor shouldn't always load all items in their inventory and everything those items have relations to, not until actually needed.
-
I'm wondering how to handle relations between classes / tables. E.g. Actors have an inventory of Items. I know how to represent this on the DB, but on the C++ side I need to replace the foreign keys and utility tables for many-to-many relations with arrays of handles / pointers etc. But how much do I want to load into memory? Loading an actor shouldn't always load all items in their inventory and everything those items have relations to, not until actually needed.
So I guess I'll use getter methods which query the DB on the first time, and later just directly return the already loaded data. The database will not change during runtime of the game so it seems reasonable.
But it WILL change when using the editor... hmm...
Wondering if it'd be reasonable to skip the C++ class instances entirely and query the DB every time any data gets accessed using helper functions 🤔
-
So I guess I'll use getter methods which query the DB on the first time, and later just directly return the already loaded data. The database will not change during runtime of the game so it seems reasonable.
But it WILL change when using the editor... hmm...
Wondering if it'd be reasonable to skip the C++ class instances entirely and query the DB every time any data gets accessed using helper functions 🤔
Whatever approach I end up using I think it's gonna involve a lot of magic code generation to make it palatable. Adding new resource types must be a breeze and not involve 15 different boilerplate steps
-
Whatever approach I end up using I think it's gonna involve a lot of magic code generation to make it palatable. Adding new resource types must be a breeze and not involve 15 different boilerplate steps
Ok scratch that last idea about always querying the DB, it'd be way too slow.
Now thinking about the almost opposite idea: When the app starts, load _everything_ into memory. Not assets of course, but all the plain data like stats and positions of nodes and such which is nothing in comparison to a few 4k textures. I think that's how Skyrim works actually.
-
Ok scratch that last idea about always querying the DB, it'd be way too slow.
Now thinking about the almost opposite idea: When the app starts, load _everything_ into memory. Not assets of course, but all the plain data like stats and positions of nodes and such which is nothing in comparison to a few 4k textures. I think that's how Skyrim works actually.
Ok this might actually be going somewhere :) Just had to overcome the mental hurdle of thinking the database schema needs to be generateable from source code / at compile time. Instead of annotations (which aren't as powerful as I hoped) I just explicitely register classes and properties during initialization, similar to how Godot does it, and from that I can generate the schema at startup. I guess I would have needed to do something like that anyway for editor and scripting language interop.
-
Ok this might actually be going somewhere :) Just had to overcome the mental hurdle of thinking the database schema needs to be generateable from source code / at compile time. Instead of annotations (which aren't as powerful as I hoped) I just explicitely register classes and properties during initialization, similar to how Godot does it, and from that I can generate the schema at startup. I guess I would have needed to do something like that anyway for editor and scripting language interop.
I want to emphasize that #Godot is a wonderful gift to humanity. Not only is it a highly competent leightweight 2D and 3D engine, with it being open source you can inspect, learn from, and get inspired by its code. It's easier than ever to roll your own hobby engine since when in doubt you can just check how this production ready engine does things.
Godot's architecture seems quite sound and well organized from what I can tell so it sets a good example.
-
undefined Oblomov shared this topic on