Hello, I have an extremely strange question for the forumers out there today.
TL;DR if you can’t or don’t want to read all of this: I want to ship my game with a 120hz mode. I’m interested in rewriting possibly very large chunks of UE5’s heavy-duty object-oriented API (e.g. UObject/AActor/UActorComponent) with a massively slimmer and more procedural data-oriented API in a very lazy effort to improve performance and personal maintainability/usability (not by much, but enough that it’s noticeable, also I just work better and more efficiently with procedural APIs, I guess after learning procedural it’s hard to go back to OOP lmao). Is this worth any time at all and is it even realistically possible, or should I just write a custom game engine?
Long Version:
My experience with Unreal Engine 5 has been excellent so far but I’ve been building the engine from source recently and it has me thinking about the extent at which I could modify the engine.
For context, I’m developing games, mostly solo. I’m currently dependent on Unreal Engine related tech to make my first game (such as MetaHumans, the UE Marketplace, and using MegaScans for free with my license agreement as everyone else, since I consider myself to be competent in most facets of development but can’t 3D model or do other kinds of art/animation to save my life).
At the same time, I’d like to help my project stand out from other Unreal Engine 5 indie games. Aside from what I believe to be a unique gameplay experience, I also want my games to be known for excellent performance. As such I’d like my game to ship with a 120hz mode on consoles, possibly as the default option (and am okay with using some gentle upscaling to help reach 4K, maybe base res of 1080-1440).
Usually most developers looking for that will write their own engine, but since I depend so much on those Unreal features (MetaHumans, free Megascans, UE marketplace, etc.) and am not fully sold on writing my own engine, I’m interested in modifying Unreal Engine 5 to be able to reach that frame rate and hold it consistently without fluctuations.
I’ve studied a lot on data-oriented design and writing procedural programming APIs and consider myself to be pretty decent at it. I find that it makes for high-performance, maintainable, and very granular APIs which I very much enjoy using.
Unreal Engine’s source code, at least what I have seen, works almost completely antithetically to this. It’s an object-oriented machine that depends heavily on virtual dispatch, state management, lots of heap allocations which don’t always seem associated with some kind of buffer (scratch block, frame, arena, etc.), and copious amounts of inheritance.
Nothing wrong with that of course - until you’re trying to force 120hz out of a game engine that seems to be designed for cinematic set-pieces. And for me, I don’t hate OOP, but I definitely struggle to work with it and am just far more efficient with procedural code (my background is in raw C, not C++, if that helps at all )
Eventually I have to learn graphics programming and modify the renderer, because it’s not going to be a magic bullet (it’s going to take far more than this to hit 120hz), but basically, I’m asking how feasible it would be to convert some major engine systems such as the gameplay framework (including UObject, AActor, UActorComponent - no, the FLECS integration is not enough for me) to something more procedural and data-oriented, versus just writing a whole new game engine and biting the bullet to hire some 3D modeling help and buy Quixel assets with regular money/credits instead. (I’m going to learn 3D modeling anyway, but look, I’m a programmer, not an artist, I’m not making any good-looking characters any time soon.)
I already know I’ll break stuff doing it (just trying to redo the game loop to not depend on a class larger than two cache lines is probably already going to break everything including PIE), but I’m still curious about anyone else’s opinion on this, primarily those who have modified the engine.
Is it a lost cause to try refactoring such a large chunk of the engine? Should I just write my own at this point or stick with my plan? I don’t mind writing my own and integrating it with UE5 as a third-party library but I’m not fully sold on the feasibility of modifying UE5 directly.
Extension:
Reasons I want to work with a more procedural architecture:
- Sort states by type/array instead of a bunch of booleans/enums
- Efficiency and cache line optimization
- Readability (I find it easier to read and work with)
- Simplicity
- Probably more if you asked, these are just what I already know I want off the top of my head