Pixel City Redux #5: Debugging Bugs Me

By Shamus Posted Tuesday May 8, 2018

Filed under: Programming 96 comments

In programming, sometimes things go very wrong and you have no idea why. Bugs happen all the time, and a lot of this jobOr hobby. Whatever. involves tracking down and fixing your mistakes. On any sufficiently mature project you’ll probably spend more time testing and debugging new features than you spend writing them.

So it goes something like this:

You’re busy playing the game you’re developing when suddenly you crash to desktop. Looking a bit closer, it seems like you got a division by zero error. It seems the variable named “distance_to” was somehow set to zero. The odd thing is,that variable is used for calculating the distance to the closest quest marker, and you know for a fact you weren’t anywhere near one.

So clearly this bug isn’t your fault. Obviously your code is fine. This is probably a bug in the compiler. Or maybe the operating system. Maybe even the processor itself. To sort this out, you’re going to need to send an irate email to the guilty.

But before you fire off that salvo of email abuse, you figure you’ll have a quick look at your code, just on the off chance that this is somehow your fault.

It’s true that you can “solve” this problem by having the program check for a value of zero before doing any division with this variable. That would certainly stop the crash, but it wouldn’t fix the bug. According to how things are supposed to work, it should be impossible for this variable to be zero. Stopping the crash won’t address the fact that something is going wrong.

The problem looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Weather.Update ();
Quests.Update ();
MagicSpells.Update ();
Towns.Update ();
Damsels.Update ();
Peasants.Update ();
Player.Update ();
Music.Update ();
SoundFX.Update ();
Crafting.Update ();
Monsters.Update ();
Network.Update ();
Gui.Update ();
Particles.Update ();
Render.Update ();

The only place in the code that messes with the variable distance_to is there on line 2, where the game looks at the player’s active quests, checks for progress, updates quest triggers, notifies them of quest completion, and that sort of thing. But the crash happens on line 13, when the interface tries to divide another variable by distance_to, which has somehow been set to zero.

Keep in mind that the idea of a “line” of code can be pretty misleading, particularly when we’re looking at the program at such a high level. Each line in the above code could call other code that calls other code that calls other code. Picture a Matryoshka doll, except each doll contains five dolls which each contain five dolls, and so on. By the time you’re three levels deep you’ve got 53 = 125 dolls scattered all over the place. And this structure is a lot more than three levels deep.

Since these 15 lines of code comprise your core game loop, they will probably invoke a non-trivial percent of your entire codebase. These 15 lines could easily represent tens or even hundreds of thousands of lines of code.

That would make for a slow search if you were going to examine the whole thing a single line at a time. Calling this a “needle in a haystack” wouldn’t be hyperbole. The problem would be about that difficult.

Luckily, you’ve got a debugger.

Unluckily, you’re using Monodevelop to debug Unity code.

Welcome to Monodevelop

Right now you’ve got two programs running: Unity and Monodevelop. The idea is that Monodevelop will attach itself to Unity. It will watch what happens. It can show you where the program is and what all the variables are at any given moment. It can pause program execution so you can poke around and check what’s going on.

So all you need to do is fire the game up, and step through those 15 lines of code. After each step you can check the value of distance_to, and hopefully you can track down what part of the code is setting it to zero.

For reasons that will become clear later, I wasn’t able to get proper screenshots of Monodevelop in action. The following image was swiped from the Unity manual:

Stolen from the Unity manual pages. At least I found SOMETHING useful there.
Stolen from the Unity manual pages. At least I found SOMETHING useful there.

That little window in the lower left is where the action happens. When you pause the program to look under the hood, that’s where it will show your variables.

So you hit F5 to begin debugging. This should attach Monodevelop to Unity so you can begin.

Except instead of jumping right into the action, Monodevelop pops up a dialog box asking you what process to attach to. You have two options: “Unity” or “Unity”. Which one is the right process? I’ll give you a hint: There’s no way to tell and it changes every time you restart the program.

You can select one or the other. Everything seems fine. Then you alt-tab over to Unity and Monodevelop beeps at you: “Couldn’t attach to process”. Note that it won’t tell you that you got it wrong until you alt-tab away.

And then five minutes later you run into the same problem because your head is full of code and you don’t have the patience or mental bandwidth to memorize this rando coin flip for this particular game session.

Whatever. Eventually you get the process attached. The program runs until it reaches the breakpoint you set on Quests.Update (); You look down to the watch window to see the state of the variables and it’s blank.

I don’t know why, but sometimes Monodevelop just… can’t. It has moods. Just close down this session and restart the debugger. Then alt-tab back to Unity and then GO BACK TO STUPID MONODEVELOP BECAUSE YOU PICKED THE WRONG PROCESS AGAIN.

Okay. All done. Now execution is sitting on Quests.Update(); and your variables are showing up in the watch window.

Again, I don’t have screenshots, but it will look something like this:

+GameManager
  +CraftingJobs
  +Damsels
  +Gui
  LastAutosave
  +MagicSpells
  +Monsters
  +Music
  +Network
  +Particles
  Paused
  +Peasants
  +Player
  PlayTime
  +Quests
  +SoundFX
  +Timer
  +Towns
  +WeatherSystem
  WindowedMode

You’ve got a big old list of variables, organized into a tree. Each of the items with a + in front of it is a collapsed branch.

The variable you want is under the +Player group. Somewhere in there is the variable distance_to, and you need to watch that variable to find the one part of code that’s somehow setting it to zero.

So let’s take a look and make sure it’s not already zero. You click on the +Player variable to open up that branch. Only, instead of showing you all the variables in +Player, it has this level of meta-information about the variable itself, or C#, or whatever. I’ve never really figured out what they’re for, but they’re not relevant to your code. But underneath those variables is another branch. if you open THAT up, then you’ll see it’s got two more branches, one for “Static Members” and one for “Non-Public” members. Without getting into what these mean, let’s just say these are additional data about your variables. It’s not necessarily wrong to list them this way, but there are other ways to do this that wouldn’t bury your information under a bunch of layers of nesting like this.

The problem here is that the list is a bit fiddly. When you open a big branch, the vertical scroll shifts and you lose your place. So as you dig down through the structure you:

  1. Open a branch, which causes everything to shift.
  2. Find your way back to where you were before the shift.
  3. Scroll down through the now-open list and find the container for the thing you want.
  4. Click to open it, which sends you back to #1.

And Carmack help you if you need to look inside an array of values. Once you find the array, you open it up to see the values are stored in a list inside of that one, and then each and every value in the list is inside of its own branch. Like I said above, I don’t have screenshots of this but I’ve created this mock-up, which should give you a rough idea of what it’s like:

I actually made this in Visual Studio by adding a bunch of layers of nesting to a perfectly straightforward structure.
I actually made this in Visual Studio by adding a bunch of layers of nesting to a perfectly straightforward structure.

Despite the endless nesting and scrolling, you persevere. After twenty seconds of window-scrolling and branch-clicking, you finally arrive at distance_to. You discover the value is set to something reasonable. Say 147.5. Whatever. That’s fine. It’s not zero.

So now you just need to advance “one” line of code, let Quests.Update () do its thing, and see if the value of distance_to changes. You hit F10 to advance one line…

And then the variable window is completely reset. The view jumps all the way to the top and all the branches slam closed.

Once you’re done cursing and you’ve calmed down a bit, you grab your pickaxe and begin digging down through the layers of hassle and obfuscation again to reach distance_to. Once that ordeal is over, you see that it hasn’t changed a bit. It’s still 147.5. So you advance one more line of code, the window resets again, you throw your computer out the window and live out the rest of your days as a crazed hermit in the mountains.

Or you use Microsoft Visual Studio.

VS seems to know what process to attach itself to and doesn’t ask me to guess a coin flip between “Unity” and “Unity”. It doesn’t lose track of the variables. The watch window looks like this:

Oh yeah. That's nice.
Oh yeah. That's nice.

There aren’t tons of extra layers of needless nesting and the structure basically reflects the structure of your code. And most importantly, the whole thing doesn’t reset the window every time you step through the code. Instead, the window stays still, and the program even highlights variables in red when their values change.

So you smack the step key 8 times and you see that distance_to gets reset to zero someplace where you don’t expect. Congratulations, you found the problem in less than half a minute, rather than fighting through several minutes of wrestling with Monodevelop’s sadistic variable-hiding. This is a staggering boost to your productivity. (Or penalty, if you’re somehow trapped on MonoDevelop.)

It turns out that distance_to was getting set to zero during… Crafting.Update ()? Apparently in the potion-crafting code you accidentally typed “distance_to” when you meant “distill_tonic”, and thus stored the value in the wrong variable. (This typo / bug was probably cause by autocomplete.)

You complete idiot.

The autocomplete in VS is a bit too eager for my taste. I DO want it to pop up suggestions, but I DON’T want it to “autocorrect” what I typed after I hit the spacebar. I’ve poked around in the options and haven’t found a way to turn it off, but the options screen is a vast labyrinth and I probably just need to keep looking.

A year ago, the connection between Visual Studio and Unity was a bit wonky and I couldn’t get the debugger to work. Thanks so much to the folks in the comments of this series who let me know that the whole thing is completely turnkey now. Your comments probably saved this project. I don’t think I could have endured much more of the MonoDevelop debug tools / torture device.

This is why I don’t have screenshots of the Monodevelop debugging circus. I switched the entire system over to Visual Studio and I’m afraid I’ll break something if I switch it back again. (Monodevelop can no longer read my project files after the switch, and I’m scared the problem might work both ways if I switched back to get screenshots.)

As nice as it is to have good tools, I should warn you that this project is actually winding down. I’m going to keep playing around with Unity (and keep writing about it here) but I’m going to abandon the procgen city stuff soon.

I’ll talk more about this in the next couple of weeks.

 

Footnotes:

[1] Or hobby. Whatever.



From The Archives:
 

96 thoughts on “Pixel City Redux #5: Debugging Bugs Me

  1. DaMage says:

    Monodevelop can no longer read my project files after the switch, and I’m scared the problem might work both ways if I switched back to get screenshots.

    Monodevelop loved to inform me that it couldn’t read certain files, that I had previously created using Monodevelop.

    That IDE (if you can call it that), is one of the worst I have ever used and I am so glad that VS just works with unity now.

    1. Asdasd says:

      more IED than IDE then?

      1. Jennifer Snow says:

        Hurl yourself on that unexploded grenade?

        1. TheJungerLudendorff says:

          It certainly encourages people to fall on their swords.

  2. Daemian Lucifer says:

    You have two options: “Unity” or “Unity”. Which one is the right process? I’ll give you a hint: There’s no way to tell and it changes every time you restart the program.

    Huh.Yeah,Ive seen that.

    You look down to the watch window to see the state of the variables and it’s blank.

    I don’t know why, but sometimes Monodevelop just… can’t. It has moods.

    Hmm,interesting.Not that unusual.

    When you open a big branch, the vertical scroll shifts and you lose your place.

    But….But….whyyyy?I dont think Ive ever seen a branch window working like that.

    And then the variable window is completely reset. The view jumps all the way to the top and all the branches slam closed.

    This isnt searching for a needle in a haystack,this is searching for a hay in a needle stack.

    1. Dev Null says:

      Used needle stack.

      1. Decius says:

        Used needle heap.

        It’s super effective?

  3. Radagast says:

    And all that is for one of the easiest errors to find! Imagine what a more subtle bug would be like..

  4. Daemian Lucifer says:

    but I’m going to abandon the procgen city stuff soon.

    And switch to procgen grass terrain?

    Oh-oh,I know!Procgen star system generator!Since you were so frustrated by no man sky,why not tackle parts of that?That could be interesting.

    1. Nick Powell says:

      Procedural Ranty Blog Post Generator! A program that automatically downloads and attempts to use random bits of software from the internet and writes 2000 words every time they stop working

  5. Decius says:

    Am I just not thinking like a programmer when I think “distance_to is being set to zero somewhere that it shouldn’t be. So I should search through every place that sets distance_to and make sure that it isn’t setting it to zero. Why is the string ‘distance_to’ even in the potion code?”

    1. Daemian Lucifer says:

      It shouldnt be there.But,there are parts of the code that are public,and thus can be changed by any part of the code.So when you mistype it somewhere it will be compiled as if thats what you meant to.And because visual studio has a weird autocomplete feature that picks the first option as soon as you press the space bar,this type of error happens often.So when Shamus wrote “dis”,he saw “distill_tonic” in the offered options and thought he picked that one,when the visual studio picked “distance_to” instead.

      1. KarmaTheAlligator says:

        OK, but I’m sure Decius meant that a search for “distance_to” would have had at least one result in the potion part, probably highlighting where the problem is, since it’s not meant to be there. Or does the search not work that way?

        1. EwgB says:

          I’d say all of you are correct.
          That problem should be way easier to find than stepping through with a debugger. And you don’t even have to rely on a full text search. Visual Studio allows you to search for references to a specific variable, type etc. (though I don’t know if that works as well in the Unity context), so that you only get references to a specific variable, not other variables that are just named the same.
          But also having globally writable variables like that is a big code stink (no offense, Shamus). And since this is C#, you could at least encapsulate the value in a property and put a breakpoint in the setter, so that you don’t have to go hunting around through all your codebase.

          1. Daemian Lucifer says:

            That is true in this case.But the problem couldve just as well been that the “distance_to” was messed up somewhere where it should be.For example the problem couldve been somewhere where the variable should be multiplied by 10,but instead the typo multiplied it by 0.Or something completely different.

            1. Decius says:

              And looking through everywhere it gets set would notice that, too.

          2. Shamus says:

            “no offense, Shamus”

            I thought it was obvious that this was a simplified example for illustration purposes. And yet everyone is taking it at face value. Did I not make the code absurd enough?

            1. Matt Downie says:

              All code is absurd, except to the person who wrote it.

              1. Tom says:

                I must be an aberration, then. I regard all code I have ever written as a hopelessly naive and amateurish mess, no matter how much I polish and refine it, and instinctively assume all code written by anyone else will be better and more sophisticated, doing properly and elegantly what I’m probably writing at a level of absurdity perhaps just barely one notch above Bogosort.

                To paraphrase a certain sci-fi novel, whenever I attempt to write code, I can’t shake the feeling that I’m hammering nails with a microscope.

                1. Shpelley says:

                  I’ve been programming over a decade myself, and I have yet to feel like I do it right. Just started getting into game development with Unity recently myself and at least now I can be absolutely certain I’m doing everything wrong instead of just vaguely feel like it.

                  1. Olivier FAURE says:

                    After a few years of paying attention to my practices, trying to be aware of various levels of compensating, over-compensating, over-engineering, etc, I feel like I’ve stricken a pretty good balance where I could stand behind 95% I’m writing, decades from now.

                    So yeah, it’s possible!

            2. Daimbert says:

              The code looks like code that I’ve seen and probably even written a number of times. It’s simplified, but not really absurdly so …

            3. Wolf says:

              Not absurd enough and at the same time too long.
              Also since the example was not carried through all screenshots there seemed to be no reason to follow the code. So inattention hid the absurdity you wanted it to exhibit.
              The fact that absurd example code is usually super short so that the absurdity sticks out, probably clashed with your need to explain the annoying depth of the search tree here, and that muddled the message.

            4. DrCapsaicin says:

              It seemed clear to me: After all, there are no quest markers or players in your procedural city (and certainly no potions….so far?) so I assumed it was a figurative example. That being said, maybe a brief disclaimer at the top that points the fact out might be in order to avoid confusion.

            5. EwgB says:

              I wasn’t talking about a specific contrived example. I’ve read your code, Shamus (the Frontier project specifically), and it is full of globally accessible values. Which is obviously fine for a hobby project that you work on all on your own (though it does make debugging harder as seen in this case). It wouldn’t fly in any company environment with decent coding practices and code reviews, though.
              Again, I’m not trying to cause any offense, honestly (though I might be failing at that). I love all your programming articles and have the highest respect for all your work. I’ve been tinkering with the code you released from the Frontier project a while back, and it is pretty cool!
              All I wanted to say was, that encapsulation and information hiding is a very useful concept that was specifically invented to address those kinds of problems, and C# offers you a lot of instruments that make it way easier and much more convenient than in ye olden C/C++ days.

              1. Shamus says:

                “I’ve read your code, Shamus”

                Ah, I see. That’s fair then. I just didn’t want to be blamed for having a dynamic list of Damsel objects.

                It really is a lot easier to maintain encapsulation in C# / Unity. All of the inter-object communications are already established by the Unity gameObject framework. So when Thing1 need some info from Thing2, they can already find each other and make calls without me needing to build object libraries, search functions, and other non-game infrastructure. It’s nice being able to grab the .transform of something and immediately be able to know where it is, what way it’s facing, who owns it, and who it owns. (Having said that, transform itself breaks encapsulation because any object can modify the position of any other. But I’m okay with that. Sometimes complex behaviors require complex systems with complex interactions and you can’t always fix that with coding styles.)

                Also, I notice I need less cross-class information overall. I’m not even sure why at this point. Maybe I just haven’t tried to do anything really complex yet, but all my classes are pretty locked down.

                Having said all that: I hate the C# set / get system. That’s a lot of lines of code for what is essentially identical to making the variable public. Yes, you could add sanity checks or debugging stuff to them, but then why not just a function for that? And if it’s just for setting and getting then why do I need to clutter up 4 lines with all the curly braces and spacing? I’d much rather a system that allows me to tag a variable as public read but not public write, but without having to build a stupid empty function block to do so.

                (This was REALLY annoying in Monodevelop because I try to keep a trivial set/ get on one line, but if I fiddled with the line of code MD would explode it out to 4 lines: Open brace, set, close brace, blank line. It would turn six minor variables into half a page of pointless whitespace. Yuck.)

                1. Shamus says:

                  Hey genius, this, plus proofreading, might make for a half-decent section in an article.

                  1. Daemian Lucifer says:

                    Youve had a few of comments like that recently.Maybe collect them and have them as a “in case of emergency” post?

                  2. DaMage says:

                    Not to mention adding some semi-relevant pictures of GTA5.

                2. Onodera says:

                  The trivial case fits on one line, Shamus: public float HP {get;set;}

                  1. PeteTimesSix says:

                    Bonus points:

                    public float Hitpoints {get; private set;} = HealthSystem.DefaultHitpoints;

                    1. Shamus says:

                      Okay, I dig this.

                      From reading the docs, I was left with the wrong impression that if I wanted to make one private and the other public then I’d have to expand the whole thing out with curly braces and such.

                      Arg. I wish I’d known this sooner. This means I have quite a bit of code refactoring that I’m going to feel guilty about not doing.

                    2. Shpelley says:

                      One thing to note about this approach Shamus is that you can’t use [SerializeField] on a property (get/set) unlike a field so that it’ll show up in the Inspector. This isn’t a huge problem but can look ugly to you:

                      [SerializeField]
                      private MyThing _thing;

                      public MyThing thing {
                      get { return _thing; }
                      private set { _thing = value; }
                      }

                      Getters/Setters can really be useful though for effectively adding triggers/events on data change, though.

                  2. EwgB says:

                    That’s a plus one from me, was just about to write the same thing.

                    In the trivial case, you don’t even have the backing variable, so that you don’t accidentally access it instead of the property. Can’t make a mistake if the variable isn’t there! :-)

                    In addition, you can have read-only properties with only a getter (can only be set from a constructor). Those can be useful for external dependencies and settings that don’t change at runtime, or for virtual properties (e.g. you have a Person object with “normal” properties FirstName and LastName, and a virtual property FullName that concatenates the two).
                    And you can even have write only properties without a getter, though the use case for that is pretty limited as far as I can tell.

                    1. EwgB says:

                      Oh yeah, there’s another nice piece of syntactic sugar I totally forgot about. Since C# 6.0 read-only properties (those with only a getter) can be implemented using a lambda expression, further cutting down the clutter. The example with the full name from above would look like this:

                      public string FirstName { get; set; }
                      public string LastName { get; set; }
                      public string FullName => $”{FirstName} {LastName}”

                      Here I also used string interpolation (it’s the string with the $ sign), which is also a C# 6.0 feature that allows you to use variables (and actually any expression) inside a string instead of doing string concatenation. It’s basically a shorter (and more readable) version of string formatting, which would have looked like this in this case:

                      string.Format(“{0} {1}”, FirstName, LastName)

                      So basically, C# is awesome and everyone should use it! :-)

                  3. Liam says:

                    And you can just type prop and hit tab twice to generate the property code (or propg, or propfull, or many others)

                  4. Decius says:

                    That looks like the kind of thing that really should show up in the documentation example code somewhere near the beginning of where new people enter it.

                    1. 4th Dimension says:

                      Actually, now that I check it. It pretty much does: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties

                      Simple properties that require no custom accessor code can be implemented either as expression body definitions or as auto-implemented properties.

                      And the following examples do show how this can be done. They of course first show the traditional way of doing it, because these other ones aren’t end all be all.

                3. Erik says:

                  This was REALLY annoying in Monodevelop because I try to keep a trivial set/ get on one line, but if I fiddled with the line of code MD would explode it out to 4 lines: Open brace, set, close brace, blank line. It would turn six minor variables into half a page of pointless whitespace. Yuck.

                  And this is why there are wars over code style standards. :) It’s really unfortunate that the Monodevelop environment seems to enforce its preferred standard – hopefully there’s somewhere to change that. Or, y’know, just abandon MD for VS like you did. :-P

                  That’s one of the biggest disadvantages of working in the embedded space – my IDE choice is severely limited to start with, limited further by my processor choice, and now locked in with no options by the company’s initial choice and the need to support old projects even while we’re doing new ones.

                  1. Daimbert says:

                    The attempts to enforce coding standards is one of the reasons I avoid IDEs; if your company’s standards are different from the default, then it will try to readjust it for you and fail, making you have to redo it. You can teach most of them to do it the “right” way, but any time the environment blows up — and Eclipse used to do that regularly — it resets it and you have to remember to correct it again.

                    Or I can just do the spacing and the braces myself while typing, not getting interrupted and not having to remember to reset it if things go wrong.

                    I choose the latter [grin].

                    1. Mistwraithe says:

                      I agree, however IDEs tend to offer a lot more than the formatting. Code completion and drilldown (ie ctrl clicking on an identifier) is very useful.

                      My preference is to still use the IDE but turn off all the auto formatting and templates.

                    2. EwgB says:

                      Many modern IDEs allow you to save those coding standards inside the repository (see .editorconfig for example), so that you don’t have to manually set up your environment, and you can have different rules for different projects. I have for example rules for my personal projects that differ from the company rules (like opening braces on their own line vs. on the same line with the code).
                      In addition to that there are server-based solution like SonarQube that go beyond simple syntax checking into static code analysis territory with the configuration stored on a central server (on a per project basis) with your IDE connecting to the server, getting the newest config and running checks on your code with it. There you get things like too many parameters in functions and too high complexity.

                    3. Daimbert says:

                      Mistwraithe,

                      Code completion isn’t really a benefit for me because I find that it doing it while I’m typing breaks my concentration, so I’d rather it just kept quiet. The drilldown can be useful at times, but searching works, too, most of time … and, I’ve found, often helps me find things that I didn’t think of if I’ve started looking in the wrong place.

                      EwgB,

                      At work, I don’t control the repo, and so can’t put that there. At home, I don’t use repos because my projects are so small that it’s pointless.

                    4. Decius says:

                      Are formatting standards so basic to the code that the IDE can’t format code for display and editing the way the user wants to see it, depending on user-configurable settings?

                      It seems to me that the first offering that provided the ability to just *not have* formatting standards for the team, because everyone sees their own preferred layout, would gain a competitive advantage.
                      Or are newline characters and whitespace sacred for some reason, and the IDE displaying all the newlines and whitespace consistently is more important than coding?

                    5. Daimbert says:

                      Decius,

                      Because people use an IDE to submit the code to the repository, it would have to keep track of what the user sees vs what the code is actually like. Otherwise, if it just reformatted it to what they wanted to see and submitted that then the format would keep changing every time anyone made any change to the file (people who have their autoformat set differently often end up causing this ). These, then, would get tagged as changes to the file even though they really aren’t. Since people can add new code to existing files, if the IDE is going to separate that it would have to know what the “official” set of standards are so that it can format the base file appropriately.

                      So either the IDE enforces the agreed upon coding standards behind the scenes — which requires some kind of file to be available — or the coding standards of a file change every time someone with a different idea of how they should be, which was the problem coding standards were invented to solve in the first place. You can add a “Display Only” mode, but then the designer would still have to make all new code conform to the standard before submitting it, at which point it would just be easier for them to learn to tolerate the coding standard.

                    6. Decius says:

                      Daimbert:
                      If everyone is using the same IDE, all it needs is to be consistent.

                      If people are using different ones, then you need a diff function that disregards “changes” that the compiler disregards. (I’d offer up specific examples, but I’d probably either include something technically wrong and leave off the key example).

                      If the compiler doesn’t care about the amount of whitespace, why does the diff?

                4. Xeorm says:

                  Main reason I’ve heard for get/set like that is to allow for proper encapsulation while still treating the variable like a variable. Making it a function would defeat the purpose. I believe there are options for reducing the needed amount of boilerplate code to put in, but never looked at it much.

                  Not even strictly needed in your own code. C# supports public variables just as easily.

                5. Blake says:

                  “That’s a lot of lines of code for what is essentially identical to making the variable public. Yes, you could add sanity checks or debugging stuff to them, but then why not just a function for that?”
                  Because functions have different syntax at the call sites.

                  One use case I ran into was actually on a C++ project, turns out MSVC has properties as a non-standard extension.
                  My issue was that I had a public member, that could be written to in a number of places across different threads (there was good reasons for this I swear), and I needed to catch when it was set to a specific value. Data breakpoints weren’t an option as it wasn’t 100% reproducible and the memory addresses weren’t consistent.
                  I could have given the member get/set functions and then gone and changed a heap of files to match the new syntax, but just changing:
                  MyType m_foo;
                  to
                  __declspec( property( get=getFoo, put=setFoo ) ) MyType m_foo;
                  I was able to put the required debugging features into setFoo without changing any other files.

                  I’m not a big fan of just making everything a property to begin with, but the ability to make something into a property as needed without changing other things is a pretty big deal.
                  It’d also be nice if C++ had a ‘public_read’ access specifier which C# properties can do.

            6. Leonardo Herrera says:

              Shamus, do you have this in a public repo? I recommend you to put it on Github. People can look at it. It doesn’t matter if it doesn’t work yet. C’mon, you can do it.

        2. Default_ex says:

          The search is even better. Right click variable, hit find all references and it will list everywhere it’s used with a snippet preview and double click to go to it. MonoDevelop doesn’t always find all but most of the time it does. Vs is way more reliable in everyway.

        3. Richard says:

          No, Visual Studio’s native search is completely and utterly useless.

          It is utterly incapable of finding everywhere a variable is actually used.
          Instead of showing you where this particular “distance_to” is referenced, it will show you everywhere that the text string “distance_to” exists as a variable name.

          Often even in commented or ifdef’d out code.

          This is of course wonderful for those times you want to find where a member variable “x” is set.

          Out-of-the-box, Visual Studio is almost completely unusable as an IDE.
          It is however a very good debugger interface, it’s just the rest of it that’s worse than useless.

          Plug in a Whole Tomato and suddenly it’s a pretty good IDE, as long as you hide most of the native search tools…

          1. Duffy says:

            There’s a rational distinct between searching for text and looking for references in VS. The idea behind the basic search is you don’t know where the object is at all yet, and maybe not even it’s full name. Whereas searching for references you’ve found a specific version of the object already.

            When you have a specific version of an object you want already you can right click it and search for all of it’s references.

            1. Richard says:

              I know – it’s just that it doesn’t actually work, at least with C/C++ in VS 2015 and earlier.
              It seems like you either get no hits at all outside the current compilation unit (despite knowing for certain that it’s used), or you get everything everywhere.

              Intellisense is really pretty awful compared to other IDEs. It kind of feels like they made something for C89 two decades ago and didn’t touch it since. The DB creation takes a really long time too.

              I recently rediscovered this because I’m switching machines and the new one didn’t have Visual Assist installed yet.

              To be fair, I can’t say I’ve used VS 2017 much yet as our big projects aren’t ready for that transition.

          2. Blake says:

            VS2017 Find references is greatly improved over some earlier versions, but you are correct that Visual Assist does it way better.

      2. Decius says:

        I know what “can be changed by any part of the code” means for 6052 Assembler- you can write any value to any memory address, and many of them are valid instructions.

        But that typically requires intentionally doing so- if your IDE allows typing in one module to alter variable names in another module, what the actual fuck?

  6. KarmaTheAlligator says:

    I DO want to to pop up suggestions

    Probably meant to be “want it to”.

  7. Lee says:

    Regarding autocomplete, which in VS is called Intellisense, you might want to toggle the completion mode. As you’ve seen, the default is “complete what you think is right when I press space.” The other option is “complete what you think is right when I press tab,” which makes the process much more deliberate on the programmer’s part. In my version, you change modes with Ctrl-Alt-Space. I’m not sure if there’s a way to make it default to the tab version.

    1. default_ex says:

      It used to default to Tab to complete in VS2008 on back but for some reason VS2010 on forward decided Space to complete was a better idea. That was one of the many reasons why so many developers stuck to VS2008 and waited for VS2012 to upgrade. VS2012 was just so nice of an improvement that minor annoyances like that were worth fixing.

      It’s surprising just how much you can change in VS2012 on up through the settings pages. Easy to waste a whole day tweaking the IDE to behave exactly like you want it to.

  8. Adam says:

    That was certainly an interesting rant on some very interesting (read: incredibly stupid) design decisions on the part of Microsoft, making me extremely glad I’ve never had to use either of those applications… but at the same time, if the issue was “specific variable was being set to 0 unexpectedly”, why wasn’t your very first thought “let’s see whether anything is setting it to 0 where I didn’t mean to?” I would have just started by searching for the variable and seeing what came up. And if nothing obvious did come up, I’m guessing/assuming/freaking *hoping* that that other IDE, terrible as it is, *must* have some way of setting conditional breakpoints, that you could tell it to break on a line (the one with the variable being set), if and only if that variable was ever 0?

    1. Shamus says:

      To be clear: The distill_potion scenario above is completely fictional. I wanted a nice clean example that wouldn’t require tons for explanation for context and that could be followed by non-coders.

      Sure, you can search for a variable. But if you just search for it by string you might get a lot of other variables named “distance_to” that aren’t part of the player and aren’t relevant to your program.

      And in a complex program, some variables will get changed often. You can spend a LOT of time searching for everywhere a variable gets changed, jumping to each bit of code, and reading all of it to check the logic. In my experience that can (depending on the program) take a couple of minutes for each block of code you have to read. Meanwhile, you can find the offending code in just a few seconds if you have a good watch window.

      Of course, the watch window doesn’t help you find intermittent problems. Sometimes you gotta dig for the needle. But that’s never my first approach.

      1. default_ex says:

        .Net (and by extension Mono) does have some really fancy stuff for debugging but it further adds to the list of why debugging sucks even if it does help a lot. The System.Diagnostics namespace contains all of the functionality you need to take control of the debugger from your code base. Combined with the Reflections stuff, it becomes an incredibly powerful debugging tool. I have had bugs complex enough that I had to write code that would walk backwards in the stack to analyze it in the way I specifically needed it to and assert when the condition hit that I knew was causing mayhem. As cool as those features are, it’s a crazy meta thing where your writing code to diagnose and find bugs in code. Something about that always makes me feel dirty even when it’s proved itself to be very effective.

        1. Decius says:

          Many anthropology historians consider the use of tools that are specialized to make tools to be a watershed moment in primate development.

          Recursion is a powerful tool. Using recursion where useful is what makes technology.

      2. EwgB says:

        As I already mentioned in a comment above, Visual Studio and C# do offer some solutions for the problems you mention. You can search by reference instead of a simple text search (right click on a variable, “Find All References”), which takes care of name coincidences. And as for changes all over the code, I would use a property instead of a variable. For example:

        // Make variable private so no one from outside the class can write to it directly
        private float distance_to;
        // Make a public property with a getter and a setter
        public float DistanceTo {
        get {
        return distance_to;
        }
        set {
        // The variable “value” is declared implicitly
        distance_to = value;
        }
        }

        Then you can make sure that no one is accessing the variable directly (even the class itself in the best case). And then you can place a breakpoint on the line with the assignment without bothering who called it. If you are e.g. interested only in cases where the variable is set to 0, you can also make the breakpoint conditional, so that it only breaks on a particular input value (or any other condition you might imagine).

        Edit: Damn it, all my formatting is not rendered. Is there any way to make comments with code in them?

        1. Richard says:

          Visual Studio’s search is utterly useless in C/C++.
          It’s a naiive text search, nothing more.

          Are you saying that it actually works for C#?

          1. Matt Downie says:

            Find All References seems to work properly in a C# Unity project for me (and not so well on my last C++ project).

          2. EwgB says:

            Yeah, support for C# in general is miles ahead in Visual Studio as compared to C++. I honestly think this is as much a function of the language design as it is a property of the IDE. Remember that C in particular was created not only way before modern IDEs and the capabilities they offer (people used to develop it in a text editor, and many still do), but also before many advances in compiler construction. The way too powerful macro system make static code analysis of C/C++ particularly tricky, and it is used all over the place. I tried to read the code of V8, the JavaScript engine powering Chrome and Node.js among others (I thought about modding it for my diploma thesis). It was like reading some arcane texts meant to summon The Ancient One Whose Name Shall Not Be Spoken. I barely escaped alive and sane from all those macros that are defined by five other macros that each in turn are defined by other macros that are different depending on the architecture you are trying to compile this beast on.
            So to sum it up, IMHO C# rocks in terms of pure language design (ignoring things like OS support, available tooling, frameworks etc.), and Visual Studio offers great support for it. It really is the cleanest, nicest language for general application design I’ve worked with to this day.

            1. Richard says:

              It’s not the language, it’s Visual Studio specifically.

              There are many C/C++ IDEs where it works correctly:

              Qt Creator’s native code model works, everything based on clang works – and the Whole Tomato plugin for Visual Studio works!

              C++ and C# are more similar than you’d think. C is very different of course…

              I’m not keen on managed code because of performance and portability – there’s a C++ compiler for almost every platform you can think of, from the smallest to the very largest.

              Modern C++ (2011 onwards) is a lot more safe than it used to be. Footguns still abound of course.

  9. CrushU says:

    Whew, if you think this is bad, stay away from debugging XML trees inside Java. Easily one of the most frustrating things I’ve ever encountered, because each thing is a ‘Node’ and its toString() doesn’t specify what’s inside it so you have to open the variable and find its ‘value’ variable. And they’re structured as a one-way List, so if the node you’re looking for is near the bottom…

    It’s a special kind of thing where telling the code to print out a logging statement at a specific point is easier than debugging that same code.

    1. Daimbert says:

      Dumping logging messages is my preferred approach for debugging … mostly because I hate to work in IDEs but IDEs are often a pain to set-up when you just need to debug something (although in Java now I’ll load up Eclipse if I really need to debug something). The other advantage is that if the code gets hit a lot — for example, you’re debugging messages sent from some kind of server — dumping a log lets you search for the things you want to see without having to do “Hit … not the right one, continue … Hit, not the right one, continue … Hit, right one, need to see what happens later … continue, continue, continue …”

    2. Daemian Lucifer says:

      And they’re structured as a one-way List,

      Wait,what?What is this,the 80s?Screw that,even basic was not designed in such a silly manner.

    3. Paul Spooner says:

      You could probably overload toString() to get it to print a summary of the node. That’s something I took the time to do in my python NBT interface module, and it has paid off tremendously since then. If you don’t have the right tools, take the time to make the tools.

      1. tmtvl says:

        It sucks that reflection in Java (AKA metaprogramming) is so terrible, otherwise some things would be much easier to debug.

      2. CrushU says:

        That’s a good suggestion.
        Too bad it was a library class that had that structure, so overloading toString() would’ve meant changing every instance of either Document or Node to a new subclass that you wrote… (Hmm. I think Java lets you name things the same as other things, you just have to clarify whether you mean java.lang.xml.Node or my.sensible.Node, I think…)

  10. Sean says:

    I admit I’ll be a bit sad to see the procedural stuff finished, as I appreciate your often clever approaches to it. I discovered the blog through the last city project, so it has always had a place in my heart. :)

    1. DrCapsaicin says:

      Agreed. I used the screensaver version of Pixel City at work for years and was looking forward to an updated version (please please please!).

      That being said, Shamus always has interesting stuff to say and I enjoy his coding projects so even if this series moves away from the procgen city stuff, I’m sure it will go somewhere cool.

  11. GoStu says:

    I’m not a coder. I don’t program games, I just play them. I appreciate this series though, because it’s helping me see ‘under the hood’ (car analogy!) of development and bugfixing.

    I always get a hoot when people rant and rave about “how easy it should be to fix these bugs, if only [developer] wasn’t so incompetent”. Then I read something like this and see how hard it really is to do.

    All that said, Frontier Developments manages to come up with some truly mystifying bugs and I’m pretty sure their version control is for shit.

    Still, thanks for writing!

    1. Daemian Lucifer says:

      Its just another matryoshka doll.Players rage about the bugs left in by the dumb developers,and then developers rage about the bugs left in by the even dumber developers of the language they used to make the game,who in turn rage about the dumbest engineers who made such a limiting hardware for them to code on.

    2. Mephane says:

      I am a programmer and have also played their game Elite Dangerous extensively. From by observations their biggest problem is tunnel vision and over-compartmentalization. E.g. two different teams working on very similar stuff, each coming to their own and very different solution, without ever communicating and finding a reusable, shared implementation. Then the solutions are never reconciled with each other, and you end up with two features that look very similar on the surface but are absolutely incompatible to each other.

  12. C.J.Geringer says:

    So, since you specified you are abandoning CITY procgen, what is the chance we will see project frontier or project hex remade in unity?

  13. Robert Conley says:

    In poor debugging environments I try to use Unit testing as much as I can. For example I would put each of those update under a series of unit tests. The test would be organized as setup, execute code, compare. A bit tedious to do but nothing beats it for catching unintended side effects.

  14. Awwwe, sad to hear your abandoning the procedural city thing. I’ve been using Pixel City as a screensaver for years and was looking forward to an upgrade :/

  15. OldOak says:

    You complete idiot.

    Correction: You autocomplete idiot.

    That’s karma for you, Shamus :)

    You should’ve nicely asked in advance what tooling would the audience recommend/prefer, maybe put out a poll or the sorts, do some extra articles to temper down the religious aspects, and proceed with what the “mass effect” of the poll would’ve been.

    Regardless, your experience is quite a good testimony of the types and amounts of issues most of the game engines present to the new users.

  16. Jason says:

    It’s true that you can “solve” this problem by having the program check for a value of zero before doing any division with this variable. That would certainly stop the crash, but it wouldn’t fix the bug. According to how things are supposed to work, it should be impossible for this variable to be zero. Stopping the crash won’t address the fact that something is going wrong.

    This.
    It drives me crazy when I see code like the following:
    void DoSomethingReallyImportant(thingThatShouldNeverBeNull)
    {
    if thingThatShouldNeverBeNull == null
    return;

    // Code that does really important stuff with thingThatShouldNeverBeNull
    .
    }
    (Sorry for the terrible formatting)
    Yes, the code above will never throw a null reference exception, but you’re just ignoring the problem, rather than solving it. If that thing should never be null, maybe it would be better to throw that exception, rather than let the calling code think everything worked fine. Or throw a custom exception. Do something!

    1. Niriel says:

      Yeah, about Null in particular, the fact that Null is a valid value for pretty much any type is absurd. If I want to allow something to have no value then I want it to be explicit, not default and mandatory. That’s what option/maybe types are for.

      As to your specific example of silently failing, “if null return”, it’s all over the place in Unity. Render an model but you forgot to set the mesh? Draws nothing. Test a collision but one of the objects is null? Returns “No collision”. It’s horrible. I love my NullPointerException.

      1. PeteTimesSix says:

        You can make a case for both of those being sensible though: sometimes you just want an object with no model but with collisions (invisible walls) or vice versa (wall detailing) and it keeps your game objects more unified if you just set the value to null instead of removing the component, and in the general case its preferable to have a traffic cone in a game that someone forgot to assign a collision mesh to just not collide with things instead of crashing the game when the player comes near it.

        On the other hand, you could make the argument that its hard to miss a bug if it grinds the whole game to a halt every time it happens, so… *shrug*

      2. Decius says:

        There’s also something to be said for the ability to test incomplete code.

        If you haven’t gotten around to implementing all the thingthatshouldneverbenulls, there’s no reason you can’t get code that runs to test something that has been written.

  17. Jabberwok says:

    Maaaan, I was really looking forward to the new version of the city generator.

  18. Anon says:

    You shouldn’t even need to step through and manually watch the variable, you should be able to set a watchpoint (aka data breakpoint). You tell it to break automatically when variable distance_to is set to 0.

    No idea if MonoDevelop supports it, but the Visual Studio debugger really should. gdb can do it and people always tell me how the Visual Studio debugger is so much better than gdb.

    1. Phil says:

      Or (at least in VS, not sure about MonoD), you can add your own variable to the watch list.
      In the (fake) example, it’d be something like library[1].some_damn_thing.another_damn_thing.seriously_what_is_this_crap.where_is_my_data.pointless_container[3].value, and you may or may not have the help of autocomplete there, but should at least prevent you having to manually drill down after every change.
      Not as useful if scope changes during debugging would mean that “library” isn’t available in the same way, though.
      Even less useful if you’re using VS and don’t have to deal with the constant shifting.

      1. Droid says:

        Hey, Shamus, you see that thing in the post above? Apparently, words that are too long (even though they have dots and brackets in them) are just rendered in one line and then cut off at the edge of the text box instead of breaking them into a new line after the text fills the whole width of the textbox.

        Example from above:
        library[1].some_damn_thing.another_damn_thing.seriously_what_is_this_crap.where_is_my_data.pointless_container[3].value

        No idea how easy that is to fix, but I thought I’d point it out!

        1. Phil says:

          Hmm, I need to actually preview my posts, or at least double-check them after posting; didn’t even notice that, heh.

          Talk about edge cases…..

          Interestingly, if you highlight the text to copy/paste it (which I did by selecting that line and the one following), the text is actually there and copied.

    2. Richard says:

      Depends a lot on the variable scope and lifetime.

      If the variable is a global or a static then it’s easy.

      If it’s a member of an object with a limited lifetime then it can be really difficult to set the memory breakpoint.

      That said, Visual Studio’s debugging – and post-mortem debugging from minidumps – is really, really good. Much better than any other IDE I know of.

      Plus Edit-and-Continue (live patching of debug builds) is really cool. I think some other IDEs do that too but VS is the one I first found it in.

  19. StuHacking says:

    Changing engine then abandoning the project… You’re more like a professional developer than you give yourself credit for Shamus! ;-)

  20. MadTinkerer says:

    …job… Or hobby. Whatever.

    Hey, my jobbies are serious business!

  21. baud says:

    Ah the joys of debugging. The most extreme I’ve done was:

    -debugging in the browser (internet explorer) javascript code
    -switch to eclipse to debug the java applet called by javascript (this applet should be removed one day in the future. Perhaps once we switch to a java version that doesn’t support applets).
    -switch the visual studio to debug a dll called by the java call. In the end the bug was that the dll was switched from x86 to x64, but the values retreived from the registery were still stored as char (one byte) instead of w_char (two bytes). It did not crashed because of this, but we were getting non-sensical results.

    Since we’re doing web dev using tomcat, I’m doing a lot of remote debugging. The half day of work before finding the right incantationsstart arguments to be able to do it was worth it.

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun. Your email address will not be published. Required fields are marked*

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>

Leave a Reply

Your email address will not be published. Required fields are marked *