Experienced Points: Why Do I Need to Restart the Game?

By Shamus
on Sep 29, 2015
Filed under:
Column

My column this week answers the question posed by the title, which means the Title Police can piss off and can’t refer to it as “clickbait”. (Seriously, the Title Police have become almost as annoying as the clickbaiters by this point. But that’s a topic for another day.)

This is yet another topic where you can go an inch deep or a mile deep, and you still won’t hit the bottom. It all depends on how much technical knowledge you demand of your audience. On the Escapist, I tried to keep things broad and accessible for general audiences.

But let’s look a little deeper:

In C-flavored programming, we have pointers. You ask the operating system for a big ol’ wad of memory, and you use that memory to store some crap. Maybe it’s the 3D model of the space marine. Maybe it’s the texture map of his face. Maybe it’s the animation that makes him look angry and constipated when you’re holding down the fire button. Maybe it’s the grunting sound he makes when the player jumps. Whatever. You get some memory and you put stuff in it.

A pointer is just an address of memory: “The space marine face is stored at memory location #1,234,567.” The most expedient way to code is simply to create the object, and then let other systems grab that pointer whenever they need it. To save time, those other systems might save the pointer so they don’t have to keep looking it up.

So far, so good.

But then we change some graphics settings. Maybe the user bumps the texture resolution from “low” to “medium”. Now we need bigger textures. But all the textures we have in memory are for “low” texture mode. So we release the memory for the space marine texture at #1,234,567 and get a new block of memory to hold the bigger texture. This new texture will probably live at a new address. Say, #2,345,678.

Now here is where our programmer starts to worry. How many other systems out there have the old address? What if one of them tries to use it? If they do, they will very likely crash the game. How can we keep this from happening? Various people will offer suggestions:

You can tell everything to always ask for the latest address of everything, always. But that creates a performance overhead. If this thing is something you use ten thousand times a frame, then any performance cost on that object will end up multiplied by ten thousand. This is really important these days when developers seem to be just barely able to maintain 60fps, and they need to save all the CPU cycles they can.

You can tell everything to update itself one a frame. Once at the start of a frame, everything can re-query all the addresses. But this creates a great deal of uncertainty, particularly when dealing with complex systems. Maybe when I’m updating a character, it has the check on the address of the model, and in the process of doing that, the model ends up (for some reason) trying to use (or even just examine) the texture. You end up with this chain of things that need to be checked in just the right order and the programmer has to understand how every single object interacts with every other object.

You can run around updating everything right at the moment it gets changed. So the user changes the texture settings and the game immediately stops everything and forces every object to update just to make sure all the pointers are current. This pushes the problems into the future. Later on, a new programmer joins the team and nobody has explained to her that when you add a new thing, you also need to add that thing to this global refresh. She’ll run around adding all sorts of useful features to the code without noticing anything is wrong. Then a playtester tries to change the graphics settings and the program dies a horrible death. Now we have to go back over the last few weeks of work and find all the things she added and “fix” them. It creates folk knowledge that you “just have to know” in order to work on this game. It doesn’t sound too bad in this example, but when you have thousands of systems that all have these little “by the way, make sure to always do X” things, it becomes dauntingly complex to keep track of them all.

And none of these techniques will help if your game is multi-threaded. Let’s say you’ve got this bit of code:

1
2
3
4
//Let's make sure the pointer is up-to-date!
pointer = GetNewPointerLocation ();
//Okay, that's safe now. We can proceed:
DoSomethingUseful (pointer);

What if some background thread happens to change the location of that thing just after line #2 but before line #4? That’s a ticket to crash city.

People usually try to fix this with programming orthodoxy: Never use simple pointers! Always use classes with constructors / destructors! Comment your code! Use this strict programming paradigm! Those solutions might help mitigate the problem that your code is now ten times as complex, but none of them as as easy, as safe, as clear, and as future-proof as simply wiping the slate clean with a restart.

And that’s why game development sucks and only a fool would try to make a game in this day and age.

Tomorrow! An update on the development of my indie game Good Robot!

Enjoyed this post? Please share!


20206Feeling chatty? There are 46 comments.

From the Archives:

  1. Abnaxis says:

    Is dependency injection not a thing in games programming? Or does it create too much overhead?

    I always assumed that the reason why the game has to restart is because OpenGL/DirectX have ugly initializations that don’t like being re-run in the middle of a program. Better to flush them out and reinitialize the context.

    Back when wide-screens were new, I remember there being different settings for graphics on consoles to take advantage of 720P resolution. The only one I can think of off the top of my head is Metroid Prime, but I don’t remember if it required a restart.

    • Wide And Nerdy says:

      I’d think the only thing you could do is always have your code reference an alias then somehow have each asset contain a property that sends the new pointer to the alias whenever the asset updates. I have no idea if that is practical or makes sense.

      You’d then have scenarios where you might want to do something different with the load order if you’re referencing the large texture instead of the small texture so the alias would also have to track whether its large or small and that property might only make sense for a subset of what you’re implementing this with while other properties make more sense with other assets. And you generally want to use generics rather than referencing specific aliases in your code, so you have different generics for different assets.

      I don’t know. It seems complicated. Knowing the technical prowess of a lot of the commenters here, I just know there’s gonna be some facepalming over my comment.

      • guy says:

        Having a fixed pointer to a variable pointer is pretty much how you do dynamically updated shared resources of variable size in most cases*. But that means you have to go to the pointer and then go to the thing it’s pointing to, which imposes overhead. In most applications, the extra overhead is well worth not having to use pointers directly and all the errors that come from mucking them up, but video games generally want as much performance as possible.

        *You could also have direct pointers and find all of them and update them every time. This is only a good idea if it’s referenced vastly more often than it’s changed.

    • mhoff12358 says:

      From what game programming I’ve poked at, there seem to be a lot of “everything you know if wrong” style trip ups that can really hurt performance.
      A good deal of game logic is iterating over a bunch of things and doing more or less the same thing to them. Apply your physics calculation to every physics object, send every drawable object to the graphics card…

      But these objects all need to react slightly differently, maybe you’ll make them all classes that inherit from some super class and use good oop. Oh, wait, that means when you store a bunch in a vector they’re all pointers to different parts of the heap so you have cache issues. You fix it so they’re all in one buffer despite having different memory footprints to fix this, but now you’ve still got a vtable lookup for the method you override for every single object which is a waste.

      There’s lots of traps due to the unique game requirements that make standard solutions behave unexpectedly badly, making it hard to look from the outside and say “why not do this?”

      • Abnaxis says:

        Yeah, that’s kind of where my first question was coming from. I guess a better way to put it would have been “Where’s the trap in using dependency injection?”

        • mhoff12358 says:

          Yep. I wrote the nicest cleanest code of my life a few months back, and am dreading the day when I’ll have to optimize it all out…

        • guy says:

          The very best performance generally comes from customizing code to the internal implementations of any other code it uses. If the textures are reliably stored in a certain order and of known size, it’s faster to get to the fourth texture with a jump to three textures worth of space after the location of the first texture than to use almost any other method. Even a direct pointer from each polygon to the associated texture is barely faster under ideal conditions and takes up more memory.

          That’s a fairly extreme example because usually the game only loads the textures it actually needs to save on RAM, so you can’t reliably do that, but you can reliably know that the next n bytes after the start of a texture contain the entire texture and nothing but the texture, and just grabbing those bytes is faster than searching for a delimiter. Dependency injection would make that difficult to exploit.

        • Xeorm says:

          Dependency injection is used plenty in games programming, but doesn’t really solve the issue.

          Think of it this way. When I initialize my program, I’ll initialize a whole bunch of stuff, including making some objects using dependency injection.

          When the user changes the graphical settings, the cascade of new initializations you’d need to do will affect a large amount of other processes. As a programmer, I can set things up so that all those initializations go off without a hitch and don’t cause any problems or any loss in gamestate.

          Or, I can be lazy, never worry about all that complication (And that is a ton of complication) and only require the user to go through the already working initial initialization process. It might be a big deal if users constantly are requiring restarts, but they’ll require one maybe a few times per install. It’s not worth the hassle.

  2. silver Harloe says:

    Sounds like a job for Captain Pub-Sub Pattern. It’s not just for networks anymore!

    “Never use simple pointers! … Those solutions might help mitigate the problem that your code is now ten times as complex, but none of them as as easy, as safe, as clear, and as future-proof as simply wiping the slate clean with a restart.”

    Is that always the case, though? I thought the job of Design Patterns was to regularlize certain known needs and by naming and regularity they become clearer than raw code. By following good templates, they might be future-proofed easier than raw code. If you have a library of Pattern implementations, you might make it easier than keeping track of all your mallocs and remembering to free them only at the right times (remember the multithread example? Instead of having the race condition at the top, you have the “wait, am I really done with this?” problem at the end. No one thread can know if it’s safe to release a resource)

    While full-on Publisher-Subscriber is obviously nutso and probably too slow for graphics, a simpler indirection might be just the trick. Just how much of a difference is there between “pointer to texture” and “pointer to pointer to texture”? It LOOKS half as fast, but all the real time is going to be spent in the “do something with texture” that follows. And is that really 10x more complicated? Are you sure it isn’t only 2x more complicated? Maybe less?

    Also, I could be way off, but I think rules only really create a cognitive burden when they have exceptions. If you always use the indirect-pointers in your project, no one is going to be confused by them after the initial training (and there will *always* be initial training. *No one* has code that is so amazingly like what’s in books that everyone can “get it” without some time to poke around under the hood).

    • There’s no time for pubsub. There’s no time for “just” another layer of indirection, which still doesn’t solve the multithreading issue, and will tend to trash your CPU cache lines, too.

      Basically, there’s no time for anything clever to solve this problem that isn’t totally free at runtime. Games in general aren’t even fast enough to run themselves as they are, which is why we don’t get 60fps solidly on consoles already.

      Plus, don’t forget, whatever clever solutions you or future commenters come up with still fall down on the fact that there is also no time to implement any of these clever solutions, as games right now also don’t have enough time to even be finished before they ship, let alone implement huge solutions to what are effectively non-problems.

      • default_ex says:

        Pubsub is a very effective solution to multi-threading issues. After seeing particular demonstration of it by Intel I dug deep into it and even constructed a half finished engine around the concept. I found a lot of the pitfalls of multi-threading just aren’t an issue when you are treating the pubsub pattern as the core idea instead of a band-aid to fix existing problems. The overhead actually turned out to be very minimal in comparison to alternatives I explored which certainly were numerous though not extensive.

        However when your talking multi-threading even the most solid of algorithms will be junk if you don’t understand the pitfalls and why they occur. I don’t doubt a lot of what made pubsub so successful of a solution for me was that I had already struggled with a lot of the problems multi-threading creates.

        It doesn’t solve the problem in the article though, just abstracts it away under yet another layer as you pointed out. Maybe makes it easier to manage in the long run but again you must know what your up against and that really apply in any situation: threaded or not.

    • Abnaxis says:

      My understanding is, that the time it takes for the CPU to go to memory, copy the contents to the cache, and read the contents is a significant performance drawback–i.e. “cache misses”. If you structure your indirect pointers so you aren’t having to go digging back into RAM to find where the pointer really is every time you access it, then you’re OK, but that complicates your code. Likewise, you can only use indirect pointers on stuff that’s going to be bottle-necked anyway like textures, but again it complicates the code…

      • guy says:

        That is also a risk, though the extent of the impact will depend on the specific CPU and a degree of blind luck (exactly what programmers always love to hear). The cache is divided into some number of segments of some size that map to physical memory in some manner. Ideally, the chunk of memory that contains the indirect pointers, the chunk of pointers that are pointed to the actual location, and the chunk of memory that contains the textures will all be loaded into the cache and accessed there. In practice, you’ll likely have a cache miss each at the start, some number of cache misses because you can’t fit all your textures into a single segment of the cache, and some sundry other cache misses. If you are terribly unlucky, the textures and pointers will map to the same point in the cache in such a way that they can’t both be in the cache simultaneously and you’ll have a miss every operation. Cache designs try to avoid letting that happen, but it’s a tradeoff between reducing cache misses and making the chip run faster by making it easier to locate an entry in the cache. And it’s the CPU designer who decides.

    • Wide And Nerdy says:

      So is pub sub essentially what i was babbling about in my above comment?

      EDIT: Looks like its kind of like what I was getting at. More use of categories instead of direct aliases?

      • silver Harloe says:

        I think you were talking about indirect pointers: nothing ever asks for X, they ask for X’s manager. Then every reference to X is made by Manager->X instead of just X. If X changes, everyone automatically gets the changed X without having to change their pointer (since their pointer is to X’s manager) (sadly, this pattern goes by many names, so is harder to talk about than others – I think C++ “smart pointers” are using this pattern, but I’m not really a C++ person).

        Publisher-Subscriber is more like a system of change notification. In it’s simplest form, anything that asks for a X would do so by asking the Publisher for X. The Publisher keeps a list of everyone who has asked about X, and if anything changes X, the Publisher goes through the list and tells each one “X has changed, yo,” through an agreed-upon interface (referred to as the Subscriber interface). The Subcriber will then change its pointer to X when it has the time to do so. Every reference to X is still made via X, so there’s no time wasted in deep loops.

        Both simple indirection and Pub-Sub have problems (and more code than I just discussed for things like read-locks and write-locks for multi-threaded apps), but are really old patterns with known characteristics that a good project manager can make rational decisions about (as opposed to “let’s just come up with something and hope” – you don’t know what the characteristics or trade-offs will be).

        But I come from business and web app environments, and the things I’m familiar with are always too slow for game development (in business and web development, we usually require profiling before calling something too slow, because humans – even very experienced humans – are terrrrrrrrrrrible at guessing bottle-necks, but game developers have their own rules there, too)

        Then again: “why not JUST this?” is almost always a question with a thousand depressing answers. If ‘this’ is simple enough, it HAS been considered.

        • Atle says:

          Also business applications have a very different life span than games. In a business application you need to code for a long life with many future changes. A game is much more publish and forget.

        • Veylon says:

          Pub-sub is I think what I’ve used in what little game programming I’ve done. There’s a class that holds all the game data and every other class that needs a piece of game data links back to that class. There’s only ever one copy and all the classes use a static pointer to reference it. Initializing all those static pointers to point to the game data class happens in it’s constructor.

          • silver Harloe says:

            That’s called a Singleton. It’s OO’s answer to global variables (and shares many of the same warts as global variables, but at least they’re all documented in one spot or something?) (Don’t get me wrong, I use singletons in my code, too – and I don’t really know how to make a useful cache system without one. Just some people would happily sneer down their nose at me for the practice)

    • Zak McKracken says:

      I do not understand the intricacies of Pub-Sub Patterns (well, not even the general stuff) but this very much sounds like a system which needs to be implemented in order to reduce (but not cancel out) the cost of giving parts of the code ability to update their data when needed.

      => And there’s another thing which somebody has to figure out, implement, after having long arguments with some hard-to-convince people who are very good in the olden ways but not too happy to switch horses.

    • guy says:

      The CPU side of the texture operation is pointer to texture to sending the texture to the graphics card without performing any operations on it. Adding an extra layer of indirection to that, times every polygon in the scene, sounds like a bad idea.

      • guy says:

        Well, to be clear, each texture probably only gets sent to the GPU once no matter how many polygons it’s on. But the GPU is going to need to match up polygons to textures, which means either the GPU will need to deal with an extra layer of indirection on each polygon or the CPU will need to format the polygons to remove the indirection.

    • Blake says:

      ” Just how much of a difference is there between “pointer to texture” and “pointer to pointer to texture”?”

      In most cases that will double the cost of that operation, but it’s worth remembering that accessing memory is one of the most expensive things you do.
      CPUs have gotten much faster over time, but memory not so much.
      I think we’re currently in the realm of a couple of hundred clock cycles per cache miss, which often means the most expensive part of a function is the memory access not the actual work you’re doing there.

      Sometimes this can be worth the cost, but patterns like that tend to become entrenched if you use them too much and then when it comes time to optimise you find that everything is just a little bit too slow and there’s no easy way to speed things up.
      Better to avoid things that you know will slow everything down at run time and just force people to restart if they change things at load time.

    • guy says:

      By the way, locking doesn’t necessarily make your race conditions go away. It stops you from having another thread possibly change the resource between line 2 and line 4 in the example, but the change may happen either before or after the thread runs. This may be actually meaningless (if you’re running producer-consumer it really doesn’t matter which consumer goes first) almost meaningless (if you’re doing graphics it’s quite likely that the difference will be imperceptible and vanish in a single frame) or critically important (if you have a game with a unit that heals if it survives an attack it’s critically important that checking if an attack killed it happens before the healing). To properly eliminate it, you need some kind of cross lock where the thread you want to run second blocks until the thread you want to run first is done; thread B waits on a semaphore initialized to zero that thread A signals after finishing. Of course, that implementation only works if thread A executes, so you can’t do it that easily if you only want to run thread A when you have something to write.

  3. AileTheAlien says:

    “that’s why game development sucks”
    I think it’s more of game-engine development that sucks, rather than game-development as a whole. Although, if the engine you have to work with is crap, your game-making will suffer too. :)

  4. Daemian Lucifer says:

    Isnt that third solution what most games that let you tweak everything in game adopt?Thats why after tweaking the options you can notice some stuttering for a few seconds until everything reshuffles.

    • guy says:

      Yeah, option 3 is the only one of those that’s really practical. Option 1 adds a potentially lengthy extra step to just about every operation, and Option 2 is more modest in terms of overhead but still not something you really want to be doing. Option 3 gives a massive performance hit while you’re in the options menu and can afford it.

  5. Joe Informatico says:

    Before we chalk this up to programmer “laziness”, let me point out that back in 2008, developer John Carmack stood in front of NASA engineers and said that graphics programming was “far more complicated” than aerospace engineering.

    This is one of those statements that sounds insane until you realize we put men on the moon with computers barely capable of playing Spacewar.

    • Kian says:

      The thing about game development is that it combines basically everything a computer can do into a single application with tight timing requirements.

      Let’s start with the obvious, the graphics. Most applications just tell the OS “Draw me a window, add these controls at these places, etc”, which is why regular applications share a look and feel in each system. A game cuts out the middle man, and goes directly to the graphics hardware. It doesn’t ask for things to be drawn, it has to know how to draw things itself. Some games use independent frameworks like QT or the like, but others create UI frameworks of their own.

      As performance starts to matter more and more, games also take on more responsibilities from the OS. For instance, asking the OS for memory can be expensive if you do a bunch of small allocations, so a game will create an arena, essentially asking for a single huge block of memory for it’s entire run and then administering the memory itself based on it’s own needs.

      Then say your game has any kind of networking. While they won’t re-implement TCP/IP, they will likely be using their own protocols on top of that stack.

      Does the game have microtransactions? Now it’s also a banking application, with all the security concerns involved.

      And you need to prevent hacking, if your online, and implement some draconian form of DRM where the game becomes hostile to the computer itself to appease the publishing overlords.

      And remember to do all this in tiny time slices.

      And we haven’t even gotten to gameplay yet.

  6. Orillion says:

    I hate it when games ask me to restart to see the changes because it should never get to that point. If your game is anywhere near the bleeding edge of graphics (or really, even if not) you should always have an external program (like MEConfig for Mass Effect, or the launcher present in all of the Elder Scrolls games since Morrowind). I know what my computer can handle. I know what effects I always turn off (because, whether my computer can handle them or not, they look unappealing to me). Let me do that so that I don’t have to wait an extra two-three minutes pointlessly.

    And always, ALWAYS let me choose to run the game in a window BEFORE letting it go to full-screen.

    • Daemian Lucifer says:

      You may know about your computer,but not everyone does.Especially if they have just bought a new configuration.

      Also,I prefer my games going full screen before choosing the windowed mode,so even that is not a unique preference.

      • mhoff12358 says:

        From a “things being user friendly” standpoint going fullscreen is nice and what most people will want. However from a “things are going horribly wrong” standpoint its much nicer if a game starts windowed. Its easier to tell if the resolution is wrong, its easier to tell if the game has hung and a bit nicer to close it when it does… Some stuff like that.

        Clearly the best compromise is to just start all your games via a command line so you can set all this with flags.

    • Xeorm says:

      On the other hand, I tend to hate games that do this. I don’t know how well your game handles, and now you’ve got this secondary program in the way between me and my game.

      I can’t know how the game will run until I play it, and I can’t do that until I’m in-game. It’s an extra step for me that I don’t make use of.

  7. Dragmire says:

    Man, pointers suck!

    And by suck, I mean I had a very hard time keeping track of them leading to many an unfortunate situation…

  8. Eric says:

    “And that’s why game development sucks and only a fool would try to make a game in this day and age.”

    We do it because we love. :(

  9. lethal_guitar says:

    “It creates folk knowledge that you “just have to know” in order to work on this game.”

    There’s a very simple measure against this: Code reviews. In the company I work in, everybody’s code, and this includes the most experienced senior rockstar programmers, has to be looked at by another developer before it can be merged back into the main branch. This can be done in person if you’re a small team, or remotely with a variety of tools. The point is not only to increase code quality, but also to share knowledge: Even a new hire might know a nice trick or something others can learn when looking at her code.

    In the example you gave, another team member would have discussed the new developer’s code before integrating it, and told her about the special requirements. She would probably also join in on other people’s code review sessions during her first days, and learn a lot of this “folk knowledge” that way.

    But I guess this practice is not so common in the game industry? Of course, it takes time away that could be spent programming – but I believe that it’s well worth it in the long run, because you save so much time you’d otherwise spend on hunting down bugs/understanding other people’s code etc.

  10. Holy shit, anyone seen how much IO Interactive is screwing up the Hitman release ?

    If you buy the game you only get half the game/story/plot, then you buy a upgrade almost half a year later for the remaining half.
    Or you pre-order and pay once, but you’ll still have to wait for the second half of the game.

    This smells of a blown budget (and deadlines), where they cut the game in two and are selling the first half to pay for the second half.

    Which is a huge shame as traveling the world doing jobs and making them look like accidents seems to go back to the core of what the hitman games are (in my opinion).

    I’m assuming that later in 2016 there will be a deluxe edition or something with both half sold as a single game release.

    What the hell is IO Interactive doing with this weird release? This is classic Ubisoft level stupidity.
    I had to go to Wikipedia and double check if suddenly IO Interactive had become a subsidiary of Ubisoft, but no, it’s Square Enix.

    Shamus could you do a follow up to your previous piece on this whole mess? (or let Rutskarn rant about it if he wants)
    Maybe it would make for good podcast material as well.

    • I’d also like to point out that after launch day, if they do let you buy the full game you are only really buying the first half of the game and pre-ordering the second half of the game. Which is seriously messed up.

    • This game is also going to get pirated to hell and back because a lot of people will wait until the “full game” is available, but at that point the full game will be available “for free” on pirate sites or similar.
      Why would you as a game company make people intentionally wait to buy your game?

    • This is my suggestion to fix this mess:
      Square Enix takes a hit on their bank account to fund the second half of the game, then delay the release date to July and release the full game as one piece.

  11. Restarting the game is a luxury problem IMO.

    It is annoying if the user has to quit the game then restart it.

    Some games will restart the game automatically and I’ll assume most won’t have much issues with that, though it can be jarring/annoying.

    A few games do not need restarting they just reload the world/level instead. (I’m guessing they “flush” everything and re-initialize the renderer.)

    But here is a “interesting” thought experiment:
    If a game showed a “loading” screen while in reality it is restarting in the background, would people be a annoyed as when the game has to restart?
    My guess is that no they would not.

    I think I’ve seen the odd game that actually let you change everything with no restarting or reloading of any kind (they stream in new textures I guess?).
    I can’t recall with games though sadly, I do recall seeing the textures get crispy/blurry depending on the texture quality setting (and I can’t recall how GTA V handles texture setting changes).

    A good way to handle configuration of a game on the PC (if the game do not allow instant results) is to provide a slick little game launcher:

    The launcher could have a few buttons/choices “Start, Update, Repair, Config” where Start would start the game, Update would check for (and download) a update, Repair would validate (checksum or hash) the game files and report or to to fix any corrupted files, Config would let you well configure the graphics/audio settings for the game.

    This way once you click Start you will be launched (almost) directly into the game, continue/load/new choices should ideally be shown. Though one could provide a config option so that the game continues automatically when started, one click on Start and your in the game (no logos or any other junk).

    The question is if the Config should be automatically set to a sensible default upon installation or if the Config window should be opened upon first run forcing the user to set the config (with settings preset to a sensible default so clicking Save is all they’d really need to do if they do not want to change anything).

    Such a launcher with a config window could even have a tiny preview if on where to get really fancy (to show how much an effect say SMAA or FXAA has on getting rid off jaggies or texture blurring), and such a config would not need to be game specific so it could be reused for multiple games using the same/a compatible game engine (and if no such universal config tool does not exist yet you heard the idea here first folks). Heck such a “Launcher” could potentially be game and engine agnostic.

  12. TMC_Sherpa says:

    My question is how often does the average player change their video options? Once or twice? I’m not going to say there aren’t gamers out there running fraps and going “OK, 16 AA, particles on high instead of ultra, grass on low, the game still looks good and I have 2 more FPS Woot!” but how much time is a team going to devote to that problem rather than, presumably, fixing something else.

    • guy says:

      Not usually very much, though that’s also something of a circular thing. I expect that if people could change their graphics settings without having to restart the game, lots of people would put them high and kick it down a notch or two in busy sections when the framerate starts to slip. And if you could do that with no lag in a single button press, everyone would do it.

      • JakeyKakey says:

        Framerate doesn’t usually drop that rarely and that consistently to warrant it though. It’s a pain in the ass restarting over and over again when you tweak the settings initially to have a good middle ground, but afterwards it really is a case of who cares.

        Maybe if you could jump pre-defined high-low on the fly via a keybinding, but even then it’s an enormous amount of hassle for a feature people won’t really use.

  13. default_ex says:

    One thing that occurred to me while reading the comments is that we don’t really experience this problem in C#. Though we do have another issue arise if we reload entire chunks of the game while it’s running. Perhaps a bit of inspection into how the typical reloading flow of a game written in C# works out would yield some interesting tricks that can be replicated in other languages.

    The issue that arises in C# is the GC kicking in, typically a few frames or even seconds after the reloading has occurred. It can be forced to happen at the end of the reloading but that introduces some problems which otherwise would never arise. I just accept it as the hit and even considered putting in a warning that it will happen. The GC collection issue isn’t too bad though, just a dip in framerate when the collection occurs then all is good (assuming there’s no blaring reallocation bad design patterns elsewhere).

    • guy says:

      As far as I’m aware, C# is much like Java in most respects, and what’s relevant here is that it doesn’t use direct pointers much if at all, so it doesn’t matter if everything gets relocated in memory because all the references update to point to the new location. This comes with a performance hit from the following of references, but if you’re not making a top-end AAA game you can afford it.

Leave a Reply

Comments are moderated and may not be posted immediately. Required fields are marked *

*
*

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun.

You can enclose spoilers in <strike> tags like so:
<strike>Darth Vader is Luke's father!</strike>

You can make things italics like this:
Can you imagine having Darth Vader as your <i>father</i>?

You can make things bold like this:
I'm <b>very</b> glad Darth Vader isn't my father.

You can make links like this:
I'm reading about <a href="http://en.wikipedia.org/wiki/Darth_Vader">Darth Vader</a> on Wikipedia!

You can quote someone like this:
Darth Vader said <blockquote>Luke, I am your father.</blockquote>