Saturday, February 22, 2014

Seeking Questions (and DOM/HTML5 Game Layout)

I had been pondering some architecture issues after a day of refactoring and cleanup on an HTML5 game I’m building at work. Some common data/UI integration problems were bugging me, mostly just for the feeling of good separation, and I was about to post to r/gamedev:

I'm looking for advice on some minor architect issues in some HTML5 gamedev work I've been up to. My background is as a web developer professionally and a very trivial game developer as a hobby, and I"m only recently combining those. However, for lots of reasons related to the positioning of this game as *part* of a larger web project at work, it isn't a traditional <canvas> HTML5 game, but being done with a combination of DOM and concern-separated logic.

I'm having trouble figuring out how where to draw the lines between the bits that implement my UI and the bigs that run logic behind it, and how to keep them in sync efficiently. There are patterns for this, but I don't feel like my usual approaches make sense in a game context, so I'm looking for any advice you've got.

This is a card game, though the situation and question would apply to other types of games, as well. Right now, I have a new refactoring that gives me two parts: a card logic component, which shuffles the deck, draws cards, manages a discard pile, play states, etc; and, all the animations and transitions of the card sprites that I display.

BAM. Right there the answer smacked me in the face. And at that moment my first thought was how interesting it is for the act of writing out a problem to trigger the solution in your head, and this isn’t a new idea in the world of even for myself. It is, however, something I want to cultivate, both in myself and others.

Write more and often, about your projects.

I try to keep a development journal and used to do a better job of it. I’m going to look at setting up some kind of prompt to keep myself reminded through the day and maybe that will help. But, on to the solution here.

If I were responding to this post, rather than writing it, maybe this is what I would say:

Separation is great, but at some point these different parts just have to talk to each other. At least, something has to connect them. You’re going to be redundant if you model all the card state twice, both in your logic and your UI, so keep one of them dumb. That’s probably going to be the UI.

Those visuals need to respond to the state changes in the logic, rather than trying to mirror them.

That logic going on, tracking your cards moving between the deck and the hand and discard pile and whatever other states you have needs to allow some reponse to that state changing. When the logic draws a hand from the deck, the visuals need to know which three cards to slide across the screen into your hand. When you play a card, the player needs to see that happen.

Just fire a simple event when the state of a card changes in the logic, and let the DOM update accordingly.

Sunday, February 16, 2014

Javascript Module Loaders Considered Harmful

Introduction


I’m coming to an opinion of Javascript module loaders that is profoundly negative and I’d like to express why I think they are, generally, a bad idea. However, I do think they have a place, which I’ll get to at the end.

Now, I understand I might be in the minority here. Between the competing specifications of CommonJS and AMD modules, loader systems like RequireJS or the (honestly really awesome) Google Module Server, and the huge cultural influence of Node on the Javascript world, you’d be hard pressed to argue against Javascript modules these days. Scripts are old hat, too stupid, too inflexible. Everyone knows that and no one would make an argument in their favor, right?

I’m going to step out on a limb and say “Javascript Module Loaders Considered Harmful” and I know the baggage involved with declaring something “Considered Harmful”. I mean every ounce of context that phrase carries with it, and I hope I can persuade you.

Harm #1: Confused Debuggers


Module loaders often make debugging difficult in a number of obvious and subtle ways.

Compression, transpiling, and other pre-processing in the pipelines that typically support module loaders (which are not always necessary, but are in use in tandem consistently) rewrite scripts from the input module to the source that actually gets parsed by the browser. There is a frequent mismatch when debugging in the browser between your actual source and the code you see in the debugger. Source Maps are helping this, but support for them in both browsers and tool chains is still underwhelming.

Often times, even when the source is unchanged or the source maps work properly, the simple nature of the dynamic tags used by module loaders causes issue. Debuggers might not recognize the same script between page loads, without an inline <script> node, causing breakpoints to be lost, for example.

It is very hard to justify module loaders on their benefit when they can make debugging your code, the very thing they aim to help you organize and simplify, so much more difficult.

Harm #2: Module Load Order


Perhaps the single most common and frustrating thing to deal with in module loaders is the order of load or script execution. Compared to the expected load order of a series of <script> tags in your page, understanding when each module will be executed can be an exercise in frustration quickly.

Execution order from module loaders is usually a factor of the race to which modules are downloaded first and the inter-module dependencies defined which will keep actual execution of a downloaded script pending until its dependencies have all been loaded.

There is obvious merit here and helping us to define and understand dependencies, and to provide clear references between them in the form of things like require() calls, is certainly admirable.

However, the fact is that the vast majority of our projects don’t have such complicated intra-module dependencies to really justify this.

Harm #3: Workflow Complication


Simply put, using a module loader instead of simple scripts is simply harder to work with.

There are well known difficulties integrating other libraries that don’t use the same module system. That there are multiple such systems makes this worse. Library authors are forced to provide extra wrappers for all the different loaders or pick a side when their users have or care not to.

When you bring in new developers to a project or when a developer finds a library she wants to use which has decided to distribute itself as a module in a specific system, like RequireJS, there is an added barrier to use with little apparent benefit to a developer who just expected another <script> tag to their existing project. Is it worth integrating someone else’s preferred loader to use their simple library? I fear this may lead to fragmentation of our already disperse ecosystem.

Conclusion


The harms are not justified compared to the benefit when the majority of web applications utilize such a small and constant set of Javascript.

There is a case for module loaders, which can only really be made when the costs are outweighed by the benefits, and this is only really verified when the costs of not using a module loader are greater than the costs when you do use a module loader. Costs of not using a module loader are incurred when you have a large enough body of code that loading all of it at the start of your app is detrimental to performance, user experience, or both.

Saturday, February 15, 2014

How To Record Video-cast GIF Animations

I'm playing with some game dev fun on the side, and as part of motivating myself I hope to have something to post to /r/GameDev's Screenshot Saturday event every weekend. This quickly got me wanting to show off something other than a still image, so I went looking for how people produce the animated screenshot GIFs I see developers posting of their games all over. Here's what I found:

Step 1: CamStudio

This open source screencast recorder is very simple, very light, free, and does a good job of recording a basic AVI screencast of a portion of your screen. You can set it to record just the part of your screen where your game is running, so you don't need to worry with post-processing crop. I tried a few other tools before this, and all of them had more up-front configuration and none of them really worked well. Either they only recorded black, or they had awful framerates, or they made my whole system crawl.

Just get CamStudio.

Step 2: VirtualDub

Maybe there is another more straight forward tool, but the first I tried (OpenAviToGif) just crashed after the first frame. VirtualDub seems to be for some other features that, frankly, I didn't even pay attention to. But, it has a simple export feature that can convert your CamStudio recorded AVI into a GIF very easily.

Download VirtualDub from their Sourceforge page.

Step 3: Post to /r/GameDev

Just do it, every Saturday. Tons of fun!

and as an extra, here's my first:


Tuesday, February 11, 2014

How To Select a Browser Storage Option

We’re in a position that, for many projects, we must include some sort of browser storage. Unfortunately, we aren’t yet at the point where the best approach is entirely obvious. Between localStorage, WebSQL, and IndexedDB developers are left with a complicated pool of options and difficult to compare pros and cons.


localStorage

The simplest and widest supported option is localStorage. If you can solve your needs with it, you should. localStorage keeps simply key->value pairs of strings in the browser, even when your website is closed. There is no real structure to the information you store, making it good for simple cases like user preferences or caching of necessarily small things.

Use localStorage when
  • You need to store less than 2.5 MB, which varies a bit between browsers
  • You can deal with the storage failing, which can happen in private modes or when hitting storage limits. Some failures are silent
  • You can identify your stored data by easily known keys, and don’t need to query over it
  • You need support across all major browsers today

Don’t Use localStorage when
  • You need to store much larger amounts of information, or large binary files like images or music
  • You need to store some unknown amount of user created content, and search for it later
  • You need access to perform very well, with very frequent access

WebSQL

The WebSQL spec was introduced with a lot of excitement, because it was such a wonderfully simple solution. Not only was it SQL we already knew, but it was explicitly SQLite, one of the most well known and widely used SQL engines, when you need smaller and embedded databases in an application. WebSQL’s simple approach to transplant such a well known engine into our web browsers meant very little to learn to take advantage of this new API.
Unfortunately, the future of WebSQL is suspect. For many reasons, many of which crowds of developers disagree with, standards bodies will not support WebSQL. But, it is still implemented in a number of browsers, especially mobile browsers. Based on browser support, it is a great option, standard or not.

Do Use WebSQL when
  • You need support for pre-Android 4.4 mobile browsers or PhoneGap projects
  • You can live without Firefox support. Maybe you’re app is mobile/phonegap only or a Chrome App.
  • You’re porting something as directly as possible from an existing SQL-using application and schema. Maybe you’ll port this over to IndexedDB later.

Do Not Use WebSQL when
  • You care Firefox and IE support (I sure hope so)
  • You want to reduce long term support as WebSQL is deprecated and removed in the future
  • Your data is not well suited for relational storage

IndexedDB

Moving forward, while localStorage will continue to have its use in small and specific data sets, IndexedDB is king of the hill in the browser storage game. There isn’t much of a debate, because WebSQL is no longer supported and IndexedDB is implemented in recent versions of all major browsers, with the exception of both Desktop and Mobile Safari.

Compared to the key/value and table based storage provided by our other two options, IndexedDB “feels more webby” for better or worse. Serialized javascript objects are dumped directly into storage, rather than being constrained to key/value strings or a pre-defined table schema. “Here, keep a copy of this object, I’ll ask for it later,” you tell the browser.

Do Use IndexedDB When
  • IE 9 and under are not needed. (Safari can be satisfied with a polyfill)
  • Your data only has to leave in the browser, and doesn’t need to match a server-side schema.
  • You have an existing backend solution that has an IndexedDB layer, like CouchDB and PouchDB.
  • You are ready to use the newest and coolest that is also well supported and established.

Do Not Use IndexedDB When

  • Your data is very simple and easily mapped to keys (use localStorage)
  • Your data is coming from a SQL server and you essentially need to mirror it on the client (maybe use WebSQL)
  • You can use a higher-level or more featureful abstraction on top of the specific storage layer (like PouchDB)

Saturday, February 01, 2014

Interest in a Feature Postmortem Blog

I'm looking to gauge interest in the community for building a feature postmortem blog. I tweeted the idea yesterday and immediately had some people who seemed to like the idea as much as I do.

The goal would be writing in the context of a project about a specific feature you built, what you needed to refactor to make room for it, and what how your previous decisions had helped or made difficult the new work you were doing. How was the work able to be broken down? Did you account for future changes you know you'll make? What work did you intentionally leave for tomorrow or the next developer?

At the heart of this idea is the thought process in my head when I sit down and work on something specific, and wanting to share that process with others and to get the same back to them. I would love to curate a reader submitted collection of these stories.

Is there an interest? Please tell me if you'd like to read this and especially if you'd like to contribute!

The Narratives Around Visual Programming

Re-posted from www.ironfroggy.com

We need to train new developers, and we need to make programming approachable by more people, if only to get their attention before they dive deeper. I'm not speaking anything new hear, but I think there are some gaps in many of the common narratives.

Narrative 1: We need to teach kids and more adults to program


I agree! We need to get the attention of adults who might be interested in a career change, and we need to capture the imagination of children who can grow up and build the future software ecosystems we'll use in our retirements.

But there is a gap in this narrative, between the learning to code and the actually being an active experienced developer.

At least in many of these cases, education is given in some more approachable fashion, but it isn't given in a way that a clear path exists from start to finish. We hook them, and then we rely on a common trait of developers to get them through the harder bits. I'm going to use Python and games as an example, because it is a common one. The Young Coders class is amazing, but I have a big problem with it: we are setting these children up for major frustration and major disappointment. We teach them to code in a wonderful language, on a great environment that fosters creativity and experimentation. We give them a comfortable start that pulls them in, hooks them, and sets them on a path to self driven education beyond all the course material.

They're going to leave these classes, already sold on everything they learned, and realize they can't send these games to their friends easier. They want to brag, and we won't let them. We've made it harder on them. "Just go install Python, and PyGame, oh and PyOpenGL because i used that, too. Then unzip my game and it should run!" they're going to tell their friends, who will look at them strangely.

We can't start developers on a path with these kinds of walls.

Either we need to break down those walls (make distributing Python projects with binary dependencies easier!) or we need to start them down a different path (like web-based coding).


Narrative 2: UNIX vs IDE Culture


The war is old and the battles have been fought over all sorts of territory, from compiler performance to language preferences to testing methodologies. But, what is the distinction between these two mindsets is really only beginning?

I have been firmly in the UNIX school for a long time, but i'm not stranger to IDE culture, either. I started my programming education with a stack of books from the library and seven Borland C++ floppies from my cousin (software piracy for the 90s), before upgrading to an actually purchased copy of Visual Studio 6.0, for I still have all my installation media.

The narrative in this divide is between a developer who gets his hands dirty and developers who let's the machine do the gritty parts for them. The UNIX developer says the IDE devotee doesn't actually understand what goes on "under the hood". The IDE developer says the UNIX devotee wastes their time doing things manually and using under-powered tools. But, both of these groups see themselves as developers, and the others as "devotees", tied hopelessly to their weird tools against all practical arguments.

If you ask a Python developer what a kid should use when getting started, they aren't going to start talking about Git, VIM, or writing setup.py files. They'll mention IDLE, where a student can naturally shift from playing in the REPL to saving a script to run against later. Where a natural progression will exist from those first steps to writing a little game they save and run again when a friend is near. But we don't look at IDLE as a "real" tool. For the most part, we only look at it as a toy. No Python developer I know looks at IDLE as a serious development tool that anyone should continue using past the learning stage.

And this is basically how many of them look at IDEs and IDE culture, as well. "Grow up and learn the command line options for the tools your GUI has been hiding from you!" they'll say. And there is an idea of power in this, that the IDE devotee is missing out on a deep well of powerful tools and options at their finger tips. We'll make this claim, and then go back to our garbage-collected, run-time compiled, dynamically-typed language.


Narrative 3: Visual Programming is a Silly Toy


While seen usually as a novelty, there are actually a huge number of visual programming options around. The thing is, they exist with a very two sided attitude from traditional developers. On the whole, they are seen positively within specific contexts of learning and education, but completely disregarded when suggested for "serious work". You can see this mirrors the narrative from UNIX developers towards IDE developers, and yet this attitude is common in both camps.

Effectively there are no "real developers" who consider visual programming viable for what they would call "real programming".

But who are the real developers and who gets to make that distinction? What is real programming and how do we identify "toy programming"? These aren't clear, and they serve largely so "other" approaches we don't like, often for fairly emotional reasons more than clear and practical ones.

It is true, there are obvious and often stark differences between a stable, mature C codebase and a project file in Scratch. Clearly, these are two very different things. But, we don't need to extrapolate from this that all text-coded programming is inherently better than any graphical-coded programming. We need to recognize a cross over, and when we do we'll enable that intersection to grow.

Good IDEs and good toolsets are important, and visual programming may be an extension of that. If this is the case, we may continue to prefer our own style but we are being dishonest if we don't label it as another camp in the same woods.


Conclusion: Abstractions like visual programming are poised to seize new ground


Look around you and you're going to see the writing on the wall. You're going to see how much more powerful Scratch 2 is, how intuitive the NoFlow project looks to make software crafting, and how games like 

LittleBigPlanet have created whole communities of people who are building software and don't even realize it.

Our walls are arbitrary. We look down on choices of text editor, on the choice between text editor and IDE. The very fact that we define a difference as if Emacs and Eclipse are so much different speaks volumes for our ability to segment ourselves needlessly. We've done the same with visual programming tools, and I think to their detriment, restraining the passion of developers who would improve them, and cutting off what could be a powerful avenue for whole new classes of developers to join our ranks.

I don't think we've learned to create software, but we've been prototyping the concept. There are fantastic possibilities when we look at the tools we hold sacred in our craft as ephemeral as the things we produce with them.
I write here about programming, how to program better, things I think are neat and are related to programming. I might write other things at my personal website.

I am happily employed by the excellent Caktus Group, located in beautiful and friendly Carrboro, NC, where I work with Python, Django, and Javascript.

Blog Archive