Lostcast episode 61...


  • Patron

    Just wanted to chime in on the discussion on the merits of Test-Driven Development;

    • The objection “my app is mainly graphical so TDD is very impractical” is very commonly heard when discussing whether or not to TDD, and something I frequently have to rebut in my university JavaScript class. As my wording probably revealed, I don’t think this excuse is valid. :) Here’s why; you don’t test what’s being drawn to the screen, but test that (a stub/mock of) the screen drawing function is being called with the correct arguments. Or in your example, that the correct animation change event was thrown or the pawn method called as expected. I’ve written a short article here. Although the main focus is how to test backbone objects, the latter section talks about testing DOM-affecting functions with the very same mindset as described above.
    • To continue my unpedagogical bashing - @geoffb’s question to @richtaur about how many bugs TDD could have avoided is also moot. Coding with TDD will not directly make you do fewer mistakes (although you might discover your mistakes sooner since your tests will fail, while a non-TDD:er wouldn’t know something was up before he actually fired up his app and did the test manually). However, coding with TDD will make you write more decoupled code, as you have to question your API as you define it since it is immediately used in a test. And more decoupled code means less error prone.
    • And of course, TDD will protect you from regression, as you’re not just testing the new functionality you add. Every test you ever wrote in the project is run, which means if your spiffy new feature shat in a remote corner somewhere, you’ll be immediately aware (unless this is an unforeseen edge case which had no test).

    Consider a parallel universe where @geoffb and @richtaur already knew TDD (and specifically how to TDD in JavaScript) before starting on AWL, and then developed the project using TDD. Would that codebase be more stable and better designed? My thinking is yes, definitely. No doubt in my mind. It matters not that it is a game. TDD would benefit the project. End of discussion, sit down and shut up.

    But learning TDD is not done in a heartbeat, and learning good TDD takes ages, and finally, learning good TDD in JavaScript takes longer still. Is investing all this time worth it? Say in another parallel universe where LDG chose to make this investment with the specific intent of making AWL a better code base. Is it worth it for this single project? I’m thinking maybe. Maybe not. I’m not sure. It would definitely benefit them over time, absolutely, but is the increased stability in a single project worth the significant upfront time payment to learn TDD? Perhaps not.

    Back to this universe - is is worth adding unit tests to AWL now, after the fact? Definitely not. You wouldn’t get any of the decoupling gains as the codebase is already designed. Also, writing tests take time, and the only viable way to be able to spend that time is to write the tests continuously, as you code. Which is what you should do anyway.

    But yep, in the long run, it is worth it. I might sound religious about this - I’m not. But of this I’m sure: learning TDD made me a better programmer all around.

    I’ll end with a book recommendation (which I might’ve mentioned before, apologies if that’s the case) - Test Driven JavaScript Development by Christian Johansen. It is from 2010, but still by far the best book on the subject (and I’ve read them all). 5 stars.


  • LDG

    @David interesting points :) I especially like being incentivized to write decoupled code.

    I can’t speak for @geoffb but I had to write test cases (for both frontend and backend code) during my time at Yahoo!. I found it to slow things down considerably but outside of that I bet it did produce less error-prone code. I can’t say if I “know” TDD because I’m not familiar with the particular term but I have worked for many months on projects that required all code be shipped with working tests. I look for value everywhere I work and I didn’t come away with any new habits from that experience.

    We write code really fast and a large amount of it regularly gets thrown out, or refactored, and tests would add extra overhead every step of the way. I could see the value of tests in a different world, if we were working on a large, continuously updated game like League of Legends or similar.


  • Patron

    I though it was worth commenting about code style, so, here we go:

    I don’t think code style isn’t that important, I think it isn’t important at all!

    I mean, if you spend time thinking about how to make your code consistent, or having hour long discussion about how to code something, you’re wasting your time!

    It’s way better to make some dirty “good enough for now” code in 10 minutes than spend half a hour thinking about how you should implement that.

    Of course, you’ll probably say that coding this way will introduce lots of obscure bugs and that one will probably have to rewrite all that dirty code, but that’s generally not the case.

    Optimizing code makes it harder to understand. Also, “good enough for now” is usually “good enough for shipping” in the indie game industry.

    One should note, however, that I don’t mean in any way that you should not care about making crappy code, I just mean that you should not overthink it.

    Making your code prettier, optimizing algorithms for obscure edge-cases, optimizing rendering code, all of that is generally a waste of time.

    I know you guys have way more experience as programmers than me, but I mean, have you watched Jonathan Blow’s “How to program indie games” lecture?


  • Patron

    Also, I think that at some point GUIs will be capable as regular code, but I don’t think they’ll be ever efficient or fast as regular code.


  • LDG

    Conversations about code are fun for us and often lead to great takeaways, so I never think of it as a waste of time. Code consistency/style leads to less error-prone code, just as TDD does. Whether it’s good for a dev and their specific project is entirely subjective.

    Additional layers on top of layers of execution can certainly lead to slower performance. Scripting languages are slower than compiled languages, and yeah usually GUIs tend to produce slower applications because of all the complicated overhead they often add. But there’s really no reason that manipulating shapes with a mouse should produce slower applications than manipulating symbols with a keyboard. I was thinking of stuff like this because of a comment on the podcast blog, which pointed to this video: http://vimeo.com/71278954 Fascinating stuff, really turns programming on its head. I believe that the whole idea of programming itself is a fundamentally flawed way for humans to interact with computers. We’re essentially typing a foreign language, far removed from the actual output.


  • Patron

    @richtaur said:

    Conversations about code are fun for us and often lead to great takeaways, so I never think of it as a waste of time.

    Well, they’re certainly fun, but the way you talked about your code discussions on the podcast makes it sound like they’re very inconclusive.

    Code consistency/style leads to less error-prone code, just as TDD does. Whether it’s good for a dev and their specific project is entirely subjective.

    I have to disagree.

    How many bugs has indentation avoided? How many bugs has placing a space between a function name and the braces avoided?

    It can certainly make your code look prettier and maybe easier to read, but making it less error-prone? I don’t think so…

    What if one has adopted a code style of using inheritance everywhere? I mean, EVERYWHERE, even where he’s not supposed to.

    Keeping a bad coding practice consistent leads to less error-prone code? Of course not!

    What I mean is K.I.S.S. Implement the simplest thing possible and simply not care about how it looks or how it performs.

    Additional layers on top of layers of execution can certainly lead to slower performance. Scripting languages are slower than compiled languages,

    By optimizing, I meant optimizing for performance.

    According to Jonathan, optimizing algorithms for faster execution generally makes your code more error-prone and harder to understand for only a marginal increase of speed.

    and yeah usually GUIs tend to produce slower applications because of all the complicated overhead they often add. But there’s really no reason that manipulating shapes with a mouse should produce slower applications than manipulating symbols with a keyboard.

    What I meant is that a GUI that is capable as code will probably take a long time to “compile” your program into code, not that the application will be slower.

    I was thinking of stuff like this because of a comment on the podcast blog, which pointed to this video: http://vimeo.com/71278954 Fascinating stuff, really turns programming on its head.

    Haha, very funny!

    Yeah, it’s possible to make a program that can interpret your goals and figure out how to do it, but to make it efficient, it would have to be very application specific, therefore, someone would need to write lots of these interpreters;

    I believe that the whole idea of programming itself is a fundamentally flawed way for humans to interact with computers. We’re essentially typing a foreign language, far removed from the actual output.

    I completely disagree.

    Coding is the more natural way to communicate with a computer, a way that’s easy to the computer to understand and is possible to us to understand.

    As you know, computers are terrible at interpreting human language, so, unless you put a human brain inside your computer, I think code will still be the best choice.

    There are languages like Scratch or Blocky and you can even program microcrontrolles with flowcharts, but it is still not natural human language and it’s way less eficient than typing things.

    If we can make computers which can really understand human language and can realize analyse human logic and understand it, we’ll have so many moral problems to solve that no one will have time to develop a way to use these computers to code.

    What I think we should be focusing is IDEs that can analyze your code while you’re typing it, figure out what you want to do and autocomplete what you’re typing.

    I don’t mean an IDE that can autocomplete variables names, I mean an IDE which can autocomplete hundred lines long functions.


  • Patron

    I don’t mean an IDE that can autocomplete variables names, I mean an IDE which can autocomplete hundred lines long functions.

    We are getting there. Purpose-built IDEs, such as Android Studio, Qt Creator, Xcode, etc, the auto-completion mechanisms, UI layout tools, templates, etc are powerful and can save a lot of time. General purpose IDEs still have a way to go. Some tools, such as Komodo Edit, have built-in syntax checking and warnings (like unused variables) for JavaScript. That’s probably about the best level of support you can hope for in general development.


  • LDG

    How many bugs has indentation avoided? How many bugs has placing a space between a function name and the braces avoided?

    I have first-hand experience that consistent code style leads to less error-prone code. If you doubt this, see Doug Crockford’s JSLint: http://www.jslint.com/

    Humans write errors. When we’re confused even about what format we’re reading and writing, we’re more likely to write errors. We trip ourselves up.

    What if one has adopted a code style of using inheritance everywhere? I mean, EVERYWHERE, even where he’s not supposed to.

    That’s not code style, that’s architecture.

    I believe that the whole idea of programming itself is a fundamentally flawed way for humans to interact with computers. We’re essentially typing a foreign language, far removed from the actual output.
    I completely disagree.

    I don’t think you watched all of the video ;) We don’t need better ways to write long receipt-style lists of commands on top of brittle, unguessable APIs. Humans communicate with words and gestures. There are obviously better ways than writing cryptic languages without any immediate knowledge of what’s happening in the program.

    @josue I hope you keep an open mind. You have lots of passion and some knowledge about programming in general, but very little real-world experience to color your views. I’ve worked with hundreds of developers over the years and the BEST were the ones who were open to ideas and wanted to learn something new every day.


  • LDG

    auto-completion mechanisms, UI layout tools, templates, built-in syntax checking and warnings

    Those are some nice features, but I see most of them as band-aids. When you take a step back, it can feel ridiculous to be typing a bunch of seemingly-nonsensical symbols to generate an image on the screen. Direct manipulation would be so much sweeter!


  • Patron

    @richtaur said:

    auto-completion mechanisms, UI layout tools, templates, built-in syntax checking and warnings

    Those are some nice features, but I see most of them as band-aids. When you take a step back, it can feel ridiculous to be typing a bunch of seemingly-nonsensical symbols to generate an image on the screen. Direct manipulation would be so much sweeter!

    I believe the non code-based manipulation you are referring to is sweet as long as it is optional. There is always that unanticipated edge-case a purely GUI-based tool can’t support. As long as I have the option to override the tool and edit the generated source directly, I am happy.


  • Patron

    @richtaur said:

    How many bugs has indentation avoided? How many bugs has placing a space between a function name and the braces avoided?

    I have first-hand experience that consistent code style leads to less error-prone code. If you doubt this, see Doug Crockford’s JSLint: http://www.jslint.com/

    I have tried to use JSlint before, but I found it to be annoying!

    It’s basically a Javascript Crockfordnator. I think most javascript programmers will find it easier to read Crockforded code, as it’s the “standard”, but I personally don’t like it. I prefer the K&R style.

    Humans write errors. When we’re confused even about what format we’re reading and writing, we’re more likely to write errors. We trip ourselves up.

    I have a conception which I don’t know if is true or not, but in my mind, the first implementation that comes to your mind is probably the simplest (or at least most obvious) one you’ll ever be able to think of, and if it’s the simplest possible, it will just work.

    If your implementation is the simplest possible, I think trying to beautify it removes it’s natural beauty.

    What if one has adopted a code style of using inheritance everywhere? I mean, EVERYWHERE, even where he’s not supposed to.

    That’s not code style, that’s architecture.

    So, what exactly you mean by code style?

    When I said code style, I was talking about everything from naming conventions, through formatting to architecture.

    All that depends on each one’s style, right?

    I believe that the whole idea of programming itself is a fundamentally flawed way for humans to interact with computers. We’re essentially typing a foreign language, far removed from the actual output.
    I completely disagree.

    I don’t think you watched all of the video ;) We don’t need better ways to write long receipt-style lists of commands on top of brittle, unguessable APIs. Humans communicate with words and gestures. There are obviously better ways than writing cryptic languages without any immediate knowledge of what’s happening in the program.

    Yeah, I don’t watched all of it, but I watched most of it (20 minutes or so).

    I know, if we could just communicate with computers and tell them what we want them to do, it would be way better than what we have now!

    But to make that work, computers would need to have a very high level of cognitive intelligence, the kind of AI that hasn’t seem much advance in the last 50 years…

    I belive that, someday, we’ll be able to connect synthetic brains to computers, but then we would have way more serious problems than how to develop software with that.

    So, what I’m saying is, yeah, that’s what we need, but no, I don’t think that’s possible.

    All the examples Bret showed were of very specific software developed for very specific applications. I belive it’s totally possible to make a game engine where you can script entities writing “human language”, but it would be, of course, very limited compared to “real” code.

    So, my suggestion is that we should focus on software that can recognize what you’re coding and help you to code it more efficiently.

    I think the closer we get to real human language, the slower and less flexible it will be, and the closer we get to machine language, the harder it will be to humans to understand it. That’s why I think we’re standing on the right spot right now.

    And we really need a more efficient way to input human language into a computer. I think keyboards are just better for “machine language”, and voice commands/gestures are not yet quite there…

    @josue I hope you keep an open mind. You have lots of passion and some knowledge about programming in general, but very little real-world experience to color your views. I’ve worked with hundreds of developers over the years and the BEST were the ones who were open to ideas and wanted to learn something new every day.

    Well, according to the examples Bret showed, maybe even experience might not color my view…

    I have to admit something… I simply LOVE criticizing other people!

    You know, it just feels soooo good to be right!

    Yeah, I know that’s a bad habit, and I know I should try to change it, but gosh, it’s hard!

    So, when you see me criticizing something, and you can’t be quite sure if I my criticism is genuine or if I’m just dicking around, assume the later.

    But seriously now, what do you mean by a “good” programmer? And why should I (or you) be interested in being a “good” programmer?

    I just want to get things done quickly, I don’t care if my code will look like a mess.

    Of course, organizing my code will certainly make my life as a software developer less miserable, but “software developer” is only one of the dozens of hats a indie game developer has to wear, right?

    Does being a “good” programmer makes you a “fast” programmer? If not, I think there isn’t much of a point in trying to be one, at least as an indie.

    If you’re and academic CS person, having a open mind is really important. If you’re working on a 200 person team, having a very consistent code style is vital. But working by myself, why should I care if I can get stuff done without all that?

    Also, isn’t all that purely subjective? I mean, coding is art. There isn’t a right way to make art, right? There are the techniques, but they don’t work for everybody.

    Thank you for being so patient guys! =P


  • Patron

    Oh, also, when I say that beautifying your code is probably a waste of time, I mean manually beautifying.

    Automating it would be the way to go, I think…


  • Patron

    Hey @richtaur @david @geoffb, I was reading my previous posts on this topic and noticed how my thoughts on code style seemed rather irrational…
    Let’s see if I can clarify what I think:

    Writing “good” (organizated, clever, well thought out) code:

    • Takes a lot of time and effort
    • Takes way less time to debug
    • Takes way less time to modify/add new features
    • Is generally very reusable

    Writing “bad” (inconsistent, badly organized) code:

    • You can just vomit code into your computer, so, it’s probably faster to write
    • Takes WAY more time do debug
    • Takes a lot of time to add new features
    • Reusability factor is almost 0%

    I think time constrains and project scale determines which approach is better for a certain project.

    I mean, if you’re writing code for a Ludum dare, it doesn’t matters how bad it looks.

    In the other side of the spectrum, if you’re programming stuff for a AAA game, you have to be very organized and consistent.

    I’m just talking out of my ass here, but more than 15k lines of code seems too much for me.

    I mean, I don’t know crap about AWL’s source code, but it seems to be a relatively simple game, from a technical point of view at least (except for the polishment stuff. I bet your particle system has more than 5k lines of code alone).

    Of course, making roboust and flexible systems as you did makes it damn easier to add new content, and makes it possible to use a great part of your code on future projects, but, is it worth it? What if you “hard coded” everything?

    I really don’t know, and I hope you guys can give me some advice…


  • LDG

    Typing code has never been a time bottleneck, so there isn’t much of an advantage to writing ugly code. As we learn more about making games, I’ve noticed that @geoffb and I both want conflicting things: we want to move faster, but we also want more flexibility and abstraction (which takes time). When we hard-code things we are able to move quickly, but sometimes we move so fast past it that we don’t take the time to see if the system we’ve built is really the one we wanted.

    A good example is AWL’s monster behavior script system. Right now you can only attach a single behavior to each entity because it was easy to do it that way. But now we’ve noticed that we’re writing lots of duplicate code for similar behaviors, so we’ll probably end up refactoring this bit.

    It’s a sliding scale that should probably be tweaked for each individual project. The do-it-quick then rewrite-later-if-needed approach isn’t too bad when you’re writing in JavaScript, but is probably way too expensive in other contexts like the AAA space.


  • Patron

    @richtaur said:

    Typing code has never been a time bottleneck, so there isn’t much of an advantage to writing ugly code.

    Yeah, I know, but I’m not talking only about typing.
    If typing code is that fast, shouldn’t it be faster to type a bunch of crappy code instead of spending time thinking about how to architect a system, and how to make it accept different types of input, and making it handle edge cases and all that stuff?

    As we learn more about making games, I’ve noticed that @geoffb and I both want conflicting things: we want to move faster, but we also want more flexibility and abstraction (which takes time). When we hard-code things we are able to move quickly, but sometimes we move so fast past it that we don’t take the time to see if the system we’ve built is really the one we wanted.

    Well, then you can just rewrite it.
    Sure, it will take some time, but you’ve already saved timing hardcoding things instead of making generalized system, right?

    A good example is AWL’s monster behavior script system. Right now you can only attach a single behavior to each entity because it was easy to do it that way. But now we’ve noticed that we’re writing lots of duplicate code for similar behaviors, so we’ll probably end up refactoring this bit.

    Yeah, when Geoff said entities in Djinn can only have one behaviour I was like: “So, why are you using entity/component then?”

    It’s a sliding scale that should probably be tweaked for each individual project. The do-it-quick then rewrite-later-if-needed approach isn’t too bad when you’re writing in JavaScript, but is probably way too expensive in other contexts like the AAA space.

    I think “the do-it-quick then rewrite-later-if-needed” is the best approach to all indies, not only HTML5 guys, because, according to Jonathan Blow, good enough for now is, on most cases, good enough for shipping.


Log in to reply