Hacker News new | ask | show | jobs
by skohan 2186 days ago
As a hobbyist who likes to tinker with game and interactive media development, a sentiment I often come across is that in 2020 it makes no sense to implement a game engine, and that I should just use something which already exists to avoid re-inventing the wheel. Code like this is one thing which helps me to calmly ignore than sentiment.

I came across the same kind of thing when I was kicking the tires on the Unreal Engine, and I wanted to attempt to add a double jump. I thought surely this should be an easy task, I would just need to find where the jump occurs, add a counter, and remove the restriction which only lets a character jump when touching the ground. What I found was a monstrous tangle of indirection similar to this one.

Now that's not to say that these engines are "bad code" - when you look at all the things a modern game engine does, including supporting interactive editing for non-coders, I'm sure there is some explanation for the level of complexity seen in code like this just because of how many systems must be layered on top of each-other. But that is the thing which makes me question whether general-purpose game engines are really a good idea at all.

In most other domains of software we've long ago eschewed this type of do-everything monolithic software design in favor of more loosely coupled composible toolsets. I'm not entirely sure why it seems that game development has yet to escape this paradigm.

4 comments

I have a feeling you may have been approaching this problem in UE4 the wrong way. Adding a double jump can be done in numerous ways, but one simple way is with Blueprints. See below link where the exact functionality is implemented with a really simple blueprint.

https://m.youtube.com/watch?v=hFAr7gYV1rA

Oh I am certain I was not approaching the problem in the UE4 way. But the issue is that the way UE4 expects me to do things is not the way I would like to approach game development.

UE4 has a strong bias about the way things should work. If I am making something which is fairly well aligned to that bias, then it's fairly easy to make it work. But if I want to achieve something which is quite far from what the engine expects, then I have to invest significant effort undoing or circumventing what UE4 already does before adding my own functionality on top. I would greatly prefer to start from a blank slate, and only add precisely the behavior I actually want.

So basically this experience with the double jump just gave me a window into the level of complexity I would have to work around in terms of realizing my own goals.

I know what you mean. One of the first things I looked into when trying out Unreal was Version Control. The amount of hoops I had to jump through just to get things on git made me reach the exact same conclusion you did.
UE4 works hard to make you not edit its source code, yes. But the biggest reason for this is allowing you to update through versions, with no struggle.

Games like Valorant are using their own modified version, and from their own admission, every version bump must be carefully considered and takes upwards of a month to reintegrate their changes in a painstakingly slow process.

To me this would be an argument against a tightly coupled monolithic engine like UE4. For instance, imagine if Valorant is only interested in a new version of the engine for new post-processing effects introduced into the renderer. Why should they have to migrate gameplay code to get benefits which have nothing to do with gameplay?
They actually _are_ changing things like the renderer, hence their need to take a long time for migrations. Basic gameplay code is written with blueprints, base classes are in C++ but do not replace the core code.
My point is not about what Valorant is doing specifically, it's about the drawbacks of a tightly coupled, opinionated system
Well duh, this is a physics engine. Implement double jump by placing an invisible floor underneath the player object when you decrement the counter.
I cannot tell if you are joking or not, but needing to place an entity into the world for a single frame to accomplish this rather than simply applying an impulse to the player is precisely the kind of over-complication I'm referring to
Without having read any of the Unreal Engine movement code, there's a complication here, and that is that "jump" might be influenced by the floor that the player is standing on. The force impulse might be related to the slope in some way. You have to figure out what "double jump" means in the context of there being no floor.

Placing a floor that has the influences you want under the player is, in a sense, a hack, but not an entirely misguided one. A better design might be not relying on whatever the "jump" button does, but writing your own, e.g. applying an impulse to the player directly.

If this sounds like semantics, consider a game like Super Mario Galaxy, which has spherical worlds. How do you determine the correct impulse for which way a "jump" goes? This is where these sorts of complications come from.

I think that captures an issue I have with engines like UE4 which I am trying to describe: it has to support virtually every type of game, so even things which could be relatively simple gain complexity because the engine has to cover cases which may be entirely irrelevant to the project I am working on.
Well to be honest UE4 codebase is one of the biggest garbage dumps I've ever had the displeasure to work with. I think the biggest problem is that it's just been accumulating 20 years worth of code and features without anything ever being refactored. And because of the current status you'd never actually want to modify any existing functionality because you're bound to break something. It's also super badly documented and riddled with bugs and really bad and confusing design deductions such as using instances of your UClasses to represent the "types" and and then having to use flags at runtime to see if "this" is archetype or not.
We haven't at place where deciplines interact.