I would say like almost everyone here, advanced setups, code management, and a tool like Increadibuild.
@Tefel 120k lines of code in a single class? I mean holy ■■■■ I know that AAA games can get complex, but to me this just sounds wrong. It’s an example of how bad/hard managment can get if 100 people have to work with the same class I guess?. I’m pretty sure that everything is getting dumped into that base class for no good reason.
heh… I’ve seen over 20 lines of “if ( … || … )” just for a GTA character to enter a car without being thrown to the moon.
AAA code can become very dumb very often.
@strife I wonder how it all started. I think this happens when another project starts on top of existing codebase. Before I didn’t know it’s was possible to have so many lines in just one class. If you don’t plan splitting your code since the beginning it’s hard to do it later on, even code reviews are not changing much.
Holy thread necromancy.
Clearly things have improved quite a lot in the 4 years since this thread started – with live reloads, and the newer options to hot reload into a live session, obviously things have become better.
That said, C++, and as much, the structure of Unreal don’t really make it super easy to crunch code down into small units.
— sort of a tangent follows —
Gaming, as an industry, itself is lightyears behind the rest of the world in processes, quality, and quite frankly, pay scales. While there may be some (and likely are!) places where you’ll find modern processes that include things like code review, pair programming, continuous integration, automated testing, actually caring about not just “does the code work” but “is the code of high quality”, these things are not the norm. That relates back to the idea that places might potentially have code units that are thousands of lines long. Very few care about the cognitive overload involved with working with such insanely sized code units. Very few care about the amount of time spent to build it (JUST THROW MORE CPU AT IT). Very few care about the code being structured in a better way than just – it works. Because no one will ever have to build anything new with this code, it’s a game, and whatever the next game is, will have totally different code.
— end tangent —
The smaller the code units you write, the less time you’re going to have to spend building them. Don’t build a 10k line anything, ever. I’ve just spent the last several years in Javascript world, and the usual advice these days, is that if a code unit is larger than 2-3 screen displays full, it’s too large.
There’s simply no “one size fits all.” The JavaScript community is known for being dumb about projects at scale, or even just general code engineering. They keep re-inventing wheels the industry already left behind in the '80s. (The leftpad debacle was a perfect illustration, and it really hasn’t gotten much better since then.)
Smaller units are often helpful, as long as they are not coupled. But when you have tons of coupling, a big unit that knows about all the coupling will sometimes serve better. Trying to fracture a large, closely-coupled system will often end up with runtime performance that’s 10x slower because of the necessary indirection. When your application is intended to calculate quarterly reports for the back office of some enterprise, that’s a TOTALLY FINE choice – it’s more important it’s right, and the next developer who comes along can easily read and understand it, than whatever the code runtime is. For games, this is not so – gameplay code needs to deal with tons of special cases because of the inherent problem domain, and performance is absolutely crucial.
That doesn’t mean that every solution requires big, dense classes and files. Sometimes, breaking parts apart actually shows opportunities for optimization, and even parallelization. There are many cases where schedule, inertia, or inexperience means that people write bigger and denser code than they have to, and when you find those, taking a bit of time to make it better delivers value to all parts of the team. It’s just not the case that EVERY large, dense, piece of code can have this hammer applied to it. Sometimes, the problem is just complex, inherently.
The best solutions is in my opinion when you end up building a better vocabulary, typically at a higher level. For example, we don’t need to write a “rolling barrel simulation” and a “fixed rock simulation” and a “falling debris simulation” and then try to make them all talk together – we raise the level of abstraction to rigid bodies with algorithmically defined collision manifolds, and use a general solver for running “the simulation” where everything interacts. The draw-back is that you now have to think in terms of forces, torques, and contacts, rather than whatever features were important to your particular rolling barrel in the “rolling barrel simulation.” Higher layer of abstraction, more powerful primitives, ability to talk about higher-level concepts, ability to parallelize and optimize in the higer-layer domain – all good things and the reason we use a physics engine in most 3D games today.
In fact, that’s what the Unreal Engine is – it defines a Gameplay Framework that lets you talk about Actors, and Pawns, and Components, and Assets, rather than having to talk about structs and pointers and blocks of texture data.
I think there may be a higher-layer set of primitives that can help with gameplay/entity code, but it’s not at all clear what that looks like, and nobody has managed to invent and popularize it yet. If you can define and build it, you may be setting the stage for the next big engine for the 2030s
Epic use meta-programming sporadically in some parts of the engine, but it’s perfectly viable to write gameplay code in almost completely abstract way:
Calling Functions: A Tutorial - Klaus Iglberger - CppCon 2020 - YouTube
Back to Basics: Templates (part 1 of 2) - Andreas Fertig - CppCon 2020 - YouTube
Back to Basics: Templates (part 2 of 2) - Andreas Fertig - CppCon 2020 - YouTube
The thing is… make sure your peers will be happy with that lol
> Sometimes, the problem is just complex, inherently.
Right. I think we just said the same thing – it’s generally better (almost always so) to have well-written, relatively small units. Surely in this environment, you’re not likely to get your class sizes down to 60-80 lines (especially as Epic’s style standard is very heavy on line-breaks ), especially not the ones that compose together a lot of other pieces, but I would say that it would be very very likely that if someone – particularly a professional – had a 10K line Pawn class, that their development processes are probably broken.
(to be fair, I don’t actually believe someone has a pawn that size, but someone upthread claimed it, i think they said 100K though)
In Unreal we compose things together by breaking them up into multiple classes, UObjects, Actors, or Components – in a “normal” structure, you’ll see that you have a PlayerController, and a Pawn, and one of those may have a reference to an InventoryManager, and then that has a reference to your Inventory items. If you have 10K lines that cannot be separated from each other on a basis like that, I’d really have to question that. FWIW, the composition of many things in Unreal could probably be improved by making more use of Components and less use of Actors. (although I really haven’t done any exploration in that vein, as i’ve been away for most of the last decade)
In any case, if you take a basically empty game, and you make a negligible change to an otherwise empty code unit, and it takes longer than a few seconds to rebuild in live update mode, then you’ve got a problem somewhere that is outside of Unreal.
If your specific code takes a very long time to build, whenever you make a change, then maybe you have some poor structuring.
> BTW: Is there any connection between eblade and UE3-UDK-UT: Blade[UG]
It me!