3 ms·
I'm not a professional programmer and I rarely work with large code bases. So the fact that my code has drifted steadily over the years towards the large-main-f
by tgb 12y ago
I'm not a professional programmer and I rarely work with large code bases. So the fact that my code has drifted steadily over the years towards the large-main-function I thought was a factor of several things, first being my general amateurism. I still think that, but there are definitely other reasons too: I now use more expressive languages (Python instead of C) and more expressive idioms within those languages (list comprehensions instead of while loops) and more expressive structures/libraries (NumPy instead of lists of structures), so I can afford to put more in one spot. I also write smaller but more numerous programs.
But there are very real advantages. I learned through game programming and still do some for fun and I absolutely prefer having a main loop that puts its fingers into all the components of the game than to have a main loop which delegates everything to mysterious entity.update()-style functions. The lack of architecture allows me to structure the logic of the game more clearly for exactly the reasons Carmack outlines. Everything is sequenced - what has already happened in the frame can be seen by scrolling up a bit instead of digging through a half-dozen files.
But the real win here is for the beginner programmer. I strongly dislike the trend these days towards programming education being done in a "fill in the blanks" manner where the student takes an existing framework and writes a number of functions. The problem is that the student rarely has any idea what the framework is doing. I would rather not have beginners write games by make on_draw(), on_tick(), etc. functions but much rather have them write a for loop and have to call gfx_library_init() at program start and gfx_library_swap_buffers() at the end of a frame. That way they can say "The program starts here and steps through these lines and then exits here" versus having magic frameworks do the work for them. There is plenty of magic done these days behind the scenes for any beginner, but it is too much to have a completely opaque flow-control.
- angersock 12y agoSo, that's the difference between beginners and professional engineers, right? If you use a framework (or at least a common pump_messages->update_ents->render cycle), it's a hell of a lot easier for other people to work on your code for a longer period of time (and those other people include yourself). Imagine if you decide to change your gfx_library with something new, especially if you had decided to scatter it's draw calls all over the "game logic" (instead of, say, a dedicated entity draw() method). What about when you start allowing data-driven entity updates? What about <insert practical concern here>? To be fair, you take it too far (as I'd once done) and you destroy performance. So, eventually, you work out how to have nice architectures that still support the fast hacky stuff. Anyways, the beginner is allowed to make such mudballs for a while--but no longer than necessary!
- tgb 12y agoSure, I couldn't get away with that in a AAA game. But you can still have separation of physics, game logic, networking, and drawing. Honestly my previous attempts at fancy architecture encouraged more intermingling of those than my simpler approaches (which is not to say that there aren't strategies that get the best of both, just that they're either hard to design or hard to use correctly for a beginner/amateur).
- akkartik 12y agoI particularly liked your last paragraph about beginner programmers, and I want to strengthen it. Abstraction is not just a drag on learning programming, it's also a drag on learning new codebases, even if you're already fairly experienced. Abstraction is good for people experienced with a codebase, but as codebases grow larger and more complex that usually means the first few people, because newcomers are rarely able to attain the same grasp of the big picture. This suggests that authors of say open source projects who want to gain more collaborators might want to go against their instincts for abstraction. (This thought crystallized for me after conversations on HN in the past couple of weeks: https://news.ycombinator.com/item?id=8308881 https://news.ycombinator.com/item?id=8308881 and https://news.ycombinator.com/item?id=8327008 https://news.ycombinator.com/item?id=8327008)
- Rapzid 12y agoI would like to second a lot of you're thinking here. I know it's a bit cliched to bring up rails, but I believe this is why a lot of the magic trips people up. It seems to me that the higher level the abstraction the more you end up NEEDING to know about it as you start straying from the tutorials. Nobody cares how puts gets text to the screen, but it doesn't take long before all the magic relationship and routing stuff becomes nagging issue, particularly for new comers and non full-timers. And thus, micro frameworks are becoming super popular for many and especially those jumping between languages/ecosystems regularly. Also, open source projects could seriously do with some dev docs. A UML diagram or two wouldn't hurt either.
- userbinator 12y agoThe key difference is that those who built the abstraction understand exactly what it abstracts, and thus what its capabilities and limitations are. Those who didn't, don't get quite the same picture. I'm not a fan of excessive abstraction either - the main thing I use it for is to reduce code duplication, which IMHO is one of the real benefits. Code that contains lots of functions-called-once or classes-used-once feels like a terribly inefficient and obfuscated way to do something, and far less straightforward than it could be. The whole "abstraction is good because it allows us to build large complex systems" notion is all too common in beginning courses in programming/software engineering architecture, and it tends to make people think that large complex systems are also good. Thus the feeling that somehow all software should be large and complex, and the resulting architecture-astronautism and disturbingly inefficient software. I completely disagree - abstraction should be taught as being a necessary evil for managing complexity, for use only when that complexity is actually justified and cannot be simplified further. Abstraction hides complexity but does not eliminate it; in fact it could be said that it probably adds to it. Code hidden by abstraction is still code that gets executed, consumes resources, and could contain bugs.
- GhotiFish 12y agoYou are part of the demographic of programmers who are "anti-magic" welcome to the club. We don't have cookies, but we have flower sugar and eggs, you can make cookies. :)