Not Dead

i was just confused as to why you walk out of a car wreck and your biggest concern is missing my fake birthday

Last Monday the top item on my to-do list was to give my friend Rob a call for his fake birthday. Then I got distracted.

I’d borrowed a car for a weekend trip to Madison and was returning on Monday, March 19. I was in the right lane of I-90 when a pickup in the left tried to lane-change into me in his haste to cut around the guy ahead of him. When I braked to avoid a collision, I spun out on the wet pavement and ground backwards to a halt along the crash barrier in the median. The back bumper disintegrated, the side of the car was scraped deeply enough to tear off a door handle, the front bumper was hanging half off.

With luck, and many thanks to automotive and highway engineers, I was uninjured. (The pickup drove off, of course.) The rest of my day was taken up with a police report, insurance report, damage estimates, and an early bedtime. All the usual fallout of a car crash.

The next morning I was trading email with Rob and I told him the whole story of the crash, ending with:

Oh, which is all a long, elaborate excuse for saying I’m sorry I missed your birthday yesterday, Rob. Happy belated!
… thank you?
Wasn’t it March 19 what you moved it to like 20 years ago because you were sick of having a birthday up against Christmas? I thought it was 3/19 and I’m sure it was some lead singer’s birthday…
guitar player. it was Pete Townshend from The Who

you got the date right. i was just confused as to why you walk out of a car wreck and your biggest concern is missing my fake birthday

I’ve been chewing on this question, but the answer is easy: I’m really happy with where I am and what I’m doing with my life. The crash hasn’t made me think “Oh no, I’m wasting my life! I need to quit my job and work on NearbyGamers full-time! Or quit NearbyGamers and work 90-hour weeks! Or join a nunnery! Or win a triathlon!”

I wanted to get right back to what I was doing. I’ve thought deliberately about what kind of life I want, and I’m living it. And I can’t think of a better way to celebrate being alive than to enjoy a fond old joke with a friend.

Posted in Life at 2012-03-27 18:48 | 2 comments | Tags: , ,

Timing

Luke, who writes backwards like DaVinci did some more game design with help from #bbg (on irc.freenode.net – anyone’s welcome to drop by to talk browser game development, it’s a great place). Reading his note photo, it looks like he’s breaking cards down into Settings, Characters, and Monsters. There’s not a lot more info, just that he’s spending his hours planning out his game.

Speaking of hours, I missed responding to something in his previous update:

Eventually, I’m going to create web interfaces for a lot of this stuff, but for now I’ll have to do any settings and etc. by hand in the database. By the way, the interface work isn’t strictly game-related and can be handled outside of So Play We All hours.

After the first week we said hours had to be budgeted towards code, but not marketing and blogging. It’s vague here, Jim, what are you referring to working on? If “interface” means HTML frontend, that’s code that’s gotta get counted, Luke and I both did a bunch of template work on budget.

Anyways, this week Jim’s got some nice top-to-bottom functionality done in his rendering engine. It felt a bit like my update about finishing off code from last week. He’s rendering a basic page:

We do not have DisplayRegions yet, so I am just some simple text. However, this page is now valid XHTML and not simple plain-text!

Congrats on the milestone, Jim.

Posted in Games at 2011-08-12 22:47 | 1 comment | Tags: , , ,

Breakdowns

When Jim asked me how many hours I could put to So Play We All this week, I said “Negative three”. That turned out to be pretty accurate, as I managed to drop on the floor all but the three most important things for my week. Unfortunately, Oaqn didn’t make that top three so I sent $20 each to Jim and Luke. So, let’s look at what I funded this week.

Luke had writer’s block, so there’s not a lot to say there. I’m a bit puzzled that he doesn’t say “coder’s blocK” because the hours are budgeted towards that, but I can see how it’d be easy to open a code editor and then stare at it.

I’ve chatted with Luke a bit about his game design and thought it was pretty solid, similar to stuff I’d seen on Three Hundred Mechanics . This really sounds like he’s trying to see the entire design up-front and getting overwhelmed by it. His big questions are all certainly important ones, but maybe it’s worth figuring out if there’s a way to take smaller bites.

Jim’s got his first progress that doesn’t sound to me like he’s reinventing a wheel. The template for a page is broken down into DisplayRegions, each of which has a Controller (“Component”) responsible for loading the right data.

It’s an interesting PHP-styled take on MVC. The top-level code that handles each request isn’t a controller action, it’s basically a template split into code/settings (“DisplayEngine”) and markup (“PageTemplate”). The template then lists what controllers and actions should be invoked to handle the request, which is a not how I’ve ever seen any web MVC work before. It feels pretty stereotypical of PHP to have a template running the show, and I wonder how much logic is going to leak into them as a result. A common pattern is that a section of a page with links to register and sign in — or, if there’s a user logged-in, to edit account settings and log out. Jim, in your system, where does that if (logged_in()) { [settings/logout template] } else { [register/login template] } live?

Posted in Games at 2011-08-06 05:20 | 2 comments | Tags: , , ,

Keeping Jim Busy

Oops, got totally distracted by flying back to Chicago and forgot to write my So Play We All response post on time, so there’s $10 each to Luke and Jim. Late but not lost, here’s that response. (Luke didn’t post an update this week, so I’m only responding to Jim.)

This week, Jim had a brief but significant update, writing:

Well, after so many weeks of being seriously far behind, I’ll finally be making the progress towards being able to render a complete HTML page.

He’s written his Page, Session, and Form classes to the point that he’s only held back by not being able to template pages from displaying real pages. I’m a little surprised he got votes in this week’s poll without anything to demo, but it’s nice to hear things are coming together for him.

Actually, maybe I should be worried that he’s going to start displaying a game sometime soon. So let me mention a great Rails feature you should spend time reimplementing, Jim. The pending release of Rails 3.1 includes HTTP streaming, basically the ability to send parts of the page while still working on generating the page.

This is how PHP’s page-as-script model works out-of-the-box, but it often leads to bugs when state changes during the page rendering. I’ve seen a lot of browser based games with a bug where a page says you have 100 minerals in the header and then, lower in the page, say that you only have 50 because loading this page performed an action that spent 50 minerals. Having an explicit stage that builds and renders a page usually prevents these bugs at the cost of being able to send enough information for the client to get working at downloading page assets while the server is still performing work. Continuing to support that may cost Jim enough time in gold-plating to keep me comfortably ahead.

(But just in case it doesn’t the 3.1 announcement also mentions an asset pipeline that compiles and compresses CSS and JS for faster pageloads. Have fun, Jim.)

Posted in Games at 2011-07-18 23:58 | 1 comment | Tags: ,

Rewriting My Competitors

It’s really clear that the polls So Play We All are measuring progress. When we have a quiet week, there’s a lot fewer votes. This week, there were 4, evenly split between Luke and I. The SPWA site doesn’t have code to handle ties so it highligted me as winning, which I guess means the bugfix is not my problem. :)

Luke laid down code for cards. I know I’m helping the enemy, but I’ve got to tweak it. His code is:

 
class CardController < ApplicationController
  def play
    play_sym = "play_#{@card}".intern # PH: this should be .to_sym
    self.send(play_sym)
    render :action => play_sym and return
  end
 
  def pocket
    pocket_sym = "pocket_#{@card}".intern
    self.send(pocket_sym)
  end # PH: no explicit render here? Feels like a paste error
 
  protected
 
  # plays
  def play_roland
    # Play the game to see what happens when you play the Roland card!
  end
 
  def play_water
    # Play the game to see what happens when you play the Water card!
  end
 
  # pockets
  def pocket_roland
    # Play the game to see what happens when you pocket the Roland card!
  end
 
  def pocket_water
    # Play the game to see what happens when you pocket the Water card!
  end
 
end
I’d write this code as:
 
class CardController < ApplicationController
  # I'm guessing from usage above @card is just the name for a card as a string
  # and that it's loaded from the url by a filter, note that I use it differently.
  before_filter :load_card
  after_filter :default_render_card
  
  def play
    @card.play
  end
 
  def pocket
    @card.pocket
  end
 
  protected
 
  def load_card
    @name = params[:card]
    @card = "card/#{@name}".camelize.constantize
  end
 
  def default_render_card
    render :template => "cards/#{request.action}/#{@name}" unless performed?
  end
end
 
# add in config/application.rb:
module Oaqn
  class Application < Rails::Application
    config.autoload_paths += %W(#{config.root}/app/cards)
  end
end
 
# and then create app/cards/roland.rb:
module Card
  module Roland
    def pocket
      # code for pocketing
    end
 
    def play
      # code for playing
    end
  end
end

So now the cards each get a source file to themselves, templates have their own per-action dirs (better swapped to per-card dirs, if there are more actions), there’s less duplicated code, and it’s far easier to test these smaller pieces. The only thing missing from this example is the fact that Luke may have to pass some game state into the methods. As long as there’s not too much it’s probably worth being explicit about.

2011-07-09: Luke actually used this code and found it didn’t work as written. I found an explanation; either add ‘app’ to autoload_paths instead of ‘app/cards’, or drop the Card wrapper.

Meanwhile, in the past, Jim wrote some PHP, and I’m not touching that language.

No, in seriousness, Jim talked about why he has some identifiers surrounded by __ (which I’d called python poisoning). I haven’t dug into his code (again, PHP), but it looks like it might be an InBandSignal to reuse Events as framework steps.

And then he talks about session fixation attacks, which are have been protected against out-of-the-box on PHP with the session.use_only_cookies setting for a while. I was a bit confused, I’m pretty sure he’s actually describing session capture attacks. Oh, and there was some other stuff about writing code to store sessions in the database. If you’re curious, Jim, here’s the code for a Rails app to do that, which appears commented-out in the stock config file for your editing convenience:

 
  Oaqn::Application.config.session_store :active_record_store

It includes support out of the box for keeping sessions in cookies (encrypted, of course), your SQL database via ActiveRecord, or Memcached. I’m curious, how much of your budget did you spend storing sessions?

Two Turnarounds

I was really impressed by Luke in week five of So Play We All. He built a playtestable game fast and, more importantly, he learned from it. He’s decided to completely rework his gameplay. Player interaction wasn’t what he wanted and he realized it would be a huge amount of work to write. It’s not easy to decide you’ve spent time building the wrong thing, and that maturity impressed me.

And, you know, I’m a huge fan of card games, so it’s nice to see another one in development.

As great as that is, Jim got my vote in this week’s poll.

In a post titled Deity Development he responds to some criticism and then links to the documentation for the abstract work I was hassling him about doing the last few weeks. I’m glad to tangibly see his progress, and it looks like he’s got a solid core built now.

Posted in Games at 2011-07-01 10:49 | 1 comment | Tags: , ,

Recreating My Firefox Profile

With the release of Firefox 5 a few days ago, I thought it was time to recreate my Firefox profile. You may not know what it is because you only have one: it’s the set of your add-ons, bookmarks, history, and every other kind of customization you can do to Firefox.

As a web developer, I have a half-dozen for testing reasons, but one that I use for all of my personal browsing and most of my work. Very infrequently, I’ve noticed that it sometimes would have errors on web pages that other Firefox profiles didn’t. After some thinking, I realized that I’ve been copying the same Firefox profile nearly ten years, copying it between computers as I upgrade. And all the while I’ve been tinkering with it, poking around in its config files, testing extensions, changing options in about:config.

I wanted a fairly mindless activity today, so I recreated my profile from scratch, re-installing all my extensions and configuring everything just the way I like it. It took a few hours, and my notes ended up surprisingly long.

The few times I’ve thought about switching to Chrome I’ve looked for one or two of these add-ons and seen that there’s no equivalent. Now that I have these notes I can check comprehensively the next time I get the urge.

The notes will mostly be of interest to web developers. My browser is pretty heavily customized with tools, privacy protections, and productivity tweaks (mostly to make it feel like vim and allow me to pull things offline easily). It’s an intimidating list to look at, but it’s ten years of small changes every few weeks all at once.

Add-Ons

  • AdBlock Plus http://adblockplus.org/en/
    • add EasyList (button in tab on startup)
    • ‘Options’ menu, uncheck ‘Show tabs on Flash and Java’
  • Better Privacy
    • select any LSOs you want to keep
  • Cookie Monster
    • uncheck “Automatically Reload…”
  • Download Statusbar
    • General
      • check ‘Download speed’
      • uncheck ‘Keep a download history
      • check ‘Clear finished downloads when the browser closes’
      • ‘Automatically clear these filetypes’: *
      • after 90 seconds
    • Appearance – choose ‘Custom Style’
      • File Name Size: 9
      • Height: 13
      • check ‘Main Downloads Button’
      • check ‘Clear Finished Button’
      • check ‘Enable Speed Colors’
  • FacebookBlocker
  • Flashblock
    • check ‘Block Silverlight as well’
    • add any whitelist sites
  • Greasemonkey
  • LeechBlock
    • block tvtropes.com
    • General – check all
  • Pentadactyl

    ~/.pentadactylrc

    "1.0b4.3 (created: 2011/01/05 17:55:12)
    
    loadplugins '\.(js|penta)$'
    set guioptions=BrsC
    set runtimepath=/home/harkins/.pentadactyl
    set urlseparator=,,s
    
    " vim: set ft=pentadactyl:
    
  • NoSquint
    • Zooming tab, uncheck ‘Show current zoom levels’
    • Set ‘Default full page zoom level’ to 100%
    • Exceptions tab, add .github.com, .tumblr.com, .blogspot.com, .posterous.com
  • Pixlr Grabber
    • uncheck ‘To edit images’ and ‘To edit backgrounds’
    • select ‘Always save to desktop’
  • Readability https://www.readability.com/addons
  • RefControl
    • click ‘Edit’ button, choose ‘Block’ and check ’3rd Party requests only’
    • outside of settings, right click button at bottom of window, remove icon
  • Sauce Launcher https://addons.mozilla.org/en-us/firefox/addon/sauce-launcher/
  • ScrapBook
    • Show up to: 10
  • SQLite Manager
    • select ‘in a new tab’
    • uncheck ‘Always confirm’
    • uncheck everything in Prompts tab
  • Tamper Data
  • Tree Style Tab
    • Appearance
      • Skin ‘Sidebar’
      • Tree Twisties: choose ‘None’
    • Menu
      • uncheck all but ‘Reload this Tree’ and ‘Close this Tree’
    • New Tabs
      • uncheck ‘Always ask’
      • select ‘Open in new tabs’
    • Tree
      • uncheck ‘When a tab gets focus’
      • check ‘Double-click on a tab’
    • Advanced
      • uncheck ‘Enable Animation Effects’
      • uncheck ‘Show tree contents’
  • UnPlug
    • Integration – uncheck all but tools menu
    • Downloads – ‘Preferred download method’: Save as
  • User Agent Switcher
  • Web Developer
    • General
      • Check to hide the context menu, confirmation, and informational
    • Validation
      • select CSS 3

Incompatible

These aren’t yet compatible with Firefox 5, so they didn’t get into my notes.

GreaseMonkey Scripts

Sorry for the lack of titles, but this was annoying enough to compile already.

51281 62706 7705 23555 53547 60314 38516 31804 56690 100746 104489 38985 45032 75263 77801 94112 30646 23175 28374 29279 29682 29681 29829 29828 95298 29666 49366 74340 76300 45032

Toolbars

  • right click on the toolbar, uncheck Web Development toolbar
  • right click again, choose ‘Customize’, choose ‘Use Small Icons’ and remove:
    • read it later
    • search box
    • zoom buttons
    • home button
    • bookmarks button
    • FireBug button
    • drag GreaseMonkey button to status bar

Cookies

click on CookieMonster at bottom of window, click View Cookies, show exceptions.
‘Allow’ sites you regularly visit
‘Block’ google properties

Bookmarks menu -> Show all Bookmarks

‘Import and Backup’ -> Back up to json in old profile, Import ‘Choose File’ in new
Same with ScrapBook – open sidebar, Tools, Import / Export, select all…

Edit -> Preferences

  • General
    • ‘When Firefox starts’: Show my windows and tabs
    • ‘Home Page’: about:blank
  • Tabs
    • check everything but ‘When I open a link in a new tab’
  • Applications
    • search for VLC, Windows, and QuickTime, change items to ‘Always Ask’
  • Privacy
    • check ‘Tell web sites I do not want to be tracked’
    • select ‘Firefox will’: Use custom settings for history
    • select ‘Keep until’: I close Firefox
    • select ‘When using the location bar, suggest’: History
  • Security
    • uncheck ‘Remember passwords for sites’
  • Advanced -> Update
    • uncheck ‘Search Engines’

about:config

  • browser.autofocus false
  • browser.dom.window.dom.enabled true (new)
  • browser.history_expire_days 30
  • browser.tabs.animate false
  • browser.tabs.closeButtons 2
  • browser.tabs.loadBookmarksInBackground true
  • browser.tabs.loadDivertedInBackground true
  • browser.tabs.selectOwnerOnClose false
  • browser.zoom.full false
  • browser.jsannoyances.disabled true (new)
  • downbar.display.clearButton false
  • downbar.display.mainButton false
  • downbar.display.percent true
  • downbar.function.useAnimation false
  • network.http.pipelining true
  • network.http.pipelining.maxrequests 8
  • network.prefetch-next false

~/.mozilla/firefox/[profile]/chrome

userChrome.css

 
    @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
    /* don't bold active tab title */
    /* no longer works, argh */
    tab[selected="true"] { font-weight: normal !important; }
 
    /* stop TreeStyleTab's Sidebar theme from changing its color when in/active */
    .tabbrowser-strip[treestyletab-style="sidebar"][treestyletab-mode="vertical"] {
      background-color: #ccc !important;
    }

userContent.css

 
    /* indicate nofollow links with a dotted blue underline */
    a[rel~=nofollow] { border-bottom: 1px dotted blue !important; }

Got any neat suggestions I’ve missed?

Posted in Code at 2011-06-25 03:54 | No comments | Tags: , ,

Small Steps

In Week 5 of So Play We All, things were pretty quiet. I bugfixed and laid groundwork. Luke… uh… did something. I read his post and it sounds like he added some helpers but otherwise mostly just rewrote his story. It’s more enjoyable now (seriously, play it), but it doesn’t really feel structurally any different. There’s no added mechanics that I can see. I’m curious where he’s going, though.

Meanwhile, Jim is apparently suffering from Python poisoning, because he’s naming events __LIKE_THIS__. He’s swirling into madness:

Once Version 1 is stable, I’ll compile a list of “official” Events that developers can utilize in their own projects.

No, I didn’t make that up. Not only is he thinking about a framework for multiple games, he’s thinking about a published framework for multiple games. Not, you know, his game. I see why Luke earlier used the phrase architecture astronauts. Jim, you are a great many abstractions away from writing a game, and I think the air is getting thin.

More encouragingly, Jim’s been writing about some of the deities in his game world: Dani, Rhegar, Nuri, Shisane, and Kesok. I understand the setting is largely based on long-gone-by D&D campaigns. It’s great to see some player-facing information.

Posted in Games at 2011-06-23 08:50 | 4 comments | Tags: ,

Craftsmanship Tour: New York Times

In May, while visiting New York City, I dropped by the New York Times to code with Derek Willis and, impromptu, Dan Berko. I worked with both at the Washington Post (and saw many other familiar names on doors, online journalism is a small town).

Derek’s got a great career arc. He climbed up the ranks of journalism, covered Congress, and got involved in data-heavy projects. “Computer assisted reporting” is one of those terms that nobody quite loves but nobody’s successfully replaced (though it seems “database journalism” is gaining ground) and refers to collecting and analyzing data in databases. Derek got as interested in the “computers” as the “reporting” and has deliberately pushed his skills and career into software development. (*cough* sounds like a good topic for a quiet blog, eh, Derek? *cough). I look at his GitHub profile today and he’s been busily merging in contributions to his open source projects like his USA Today Census gem.

We started out the day looking around the FEC scraping code. In the States, the Federal Election Commission gives out lots of data from candidates filing required disclosure statements. We tidied up the database a little and then turned to the project for the day, which has just been publicly announced:

Today we’re announcing the addition of paper campaign filings from Senate candidates and two party committees to our Campaign Finance API, which previously had only provided details of electronically filed reports. Now users can request and view the filings of any committee registered with the Federal Election Commission. Unlike House and presidential candidates, current and would-be senators file their campaign reports first with the Secretary of the Senate, who then forwards them to the F.E.C. That agency then scans in the images from the paper filings and makes them available for viewing (an example). While an effort to require electronic filing for Senate candidates hasn’t gotten much traction this year, we have at least made the API’s set of filings more complete. New in the Campaign Finance API: Paper Filings

The scraper was previously ignoring the paper-only reports, but we updated it to recognize and categorize them. The categorization was a huge bit of nostalgia for me: take the noisy and sometimes inconsistent provided categories and map them onto a standard set of database categories (form_type, in the screenshot in the announcement).

When we ran the scraper, it would complain and halt each time it reached an unknown category. We’d add that to a mapping table and restart from that point, but it was frustrating to have to keep an eye on it. So we set the scraper to ignore records that it didn’t have a mapping for and warn about the problem. We set the scraper to run (and hit the amazing Shake Shack for burgers) and came back to find a list of missing mappings. After adding that, we ran the scraper again to fill in the missing entries.

This worked because the scraper only added entries it didn’t already have recorded. The term for this is idempotency, and it’s useful from the level of individual functions up to large, fairly complex programs like web scrapers. Every program fails, having an idempotent approach to the problem means you don’t have to keep careful track of many types of failure because you can fix things and re-run your program without worrying about duplicate records or updating things twice.

Derek had to run off to catch a train, so I dropped in on Dan Berko. He was on one of the Post’s several other “web innovation” teams while I was there, so we helped each other with code occasionally but didn’t spend a lot of time coding together.

The New York Times has large and well-maintained internal tools for reporters and editors. The reporters have a CMS for writing stories and the editors have a budgeting system for planning what goes where in the paper. We improved communcation between these two a bit, so the budgeting tool could refer to a story in the CMS and pull metadata from there instead of requiring an editor to re-input it.

The UI was simple: if the editor links a story, several fields should be grayed out and a checkbox should indicate the link. If the editor unchecks the box, the link is broken and the fields become editable again. This started out with two code paths – one for linking a story, one for unlinking – and making sure on pageload that the UI was in the proper state. We’d barely started writing that when we saw it could be implemented even simpler:

 
disable_if_linked_to_cms: function() {
  var checked = $('asset_cms_id').checked;
  ['asset_home_status_id', 'headline', etc.].each(function(id) {
      $(id).disabled = checked;
  });
},
document.observe('dom:loaded', function(){
  Event.observe('asset_cms_id', 'click', Budget.disable_if_linked_to_cms);
  Budget.disable_if_linked_to_cms();
});

When the checkbox is checked, all the form fields are disabled. When it’s unchecked, they’re not. The code runs on pageload and anytime the checkbox is toggled. I really liked this bit of code: we started out writing the simplest thing that came to mind, but soon we realized it could be reduced. The resulting code probably elicits a “So what, it’s not doing much?” reaction, which is far better than the previous “Now, let’s see, what’s this doing?” we would’ve had at first. The sign of the best code is that you immediately understand it, not that you have to stretch yourself to follow its solution.

Posted in Code at 2011-06-22 18:07 | No comments | Tags: , , ,

Now Featuring Monsters

The So Play We All theme this week was “core game objects” and the time budget was 3 hours. I did did well for myself, time to review the others’ work — both of which included monsters.

Luke did well this week as he started to build out his combat system, including party members who (unless he’s hacked it in, but it doesn’t look that way) respond to locations and enemies. It’s a start at gameplay, though your choices are pretty limited so far. I like the idea in the blog post about having party members you can configure but not directly control, it reminds me of Ogre Battle.

Also, he’s started the storyline, including “the fact that the bear can’t seem to find you is important”. When you play, the bear enemy appears to be completely incapable of attacking you. Just for wild-ass guessing’s sake, I’m going to guess the player starts as some kind of ghost. We’ll see how I did when the storyline takes shape.

Jim… continued to work on the controllers for his web framework, as he did last week. I felt like this:

> Application creates CommandRouter and TemplateDisplay instances

I’m very happy for it.

> Application retrieves Events from the CommandRouter for the current Post data (usually none)

So, it’s like how PHP populates $_GET and $_POST for you before invoking a script, but redundant.

> Application retrieves Events from the CommandRouter for the current URI

Events are sounding awfully general purpose. Wasn’t this a game? I feel faint.

> Application loops through the current events (events can be added while processing other events) and calls the CommandRouter->ProcessEvent() method for each one

It’s a generic message queueing system. The world is going dim…

> CommandRouter creates any necessary controller and sub-display instance for the event and passes all data to any module event handlers registered for the current event

It is pitch black. You are likely to be eaten by a grue.

> Created controllers determine models to use which add their data to the relevant Display objects (which are further applied to the TemplateDisplay instance)

No, really, a grue. It eats developers who don’t finish games.

> Application renders the TemplateDisplay

The grue dies of boredom.

Jim mentioned he liked the Mortal Kombat drawing last week. I guess he didn’t click on it. It’s a link to a great article, which includes:

3. DON’T ROLL YOUR OWN TECH IF YOU DON’T HAVE TO

There are pros and cons to writing your own engine. But ask yourself, do you really have to? Is what you want to do impossible to do with what’s already out there or would you be reinventing the wheel? Of course, if you write your own engine you can make it just perfect the way you like it. But be honest, how often do you ever get past the engine to the game itself? Do you find yourself making game engines more often than you do games?

Bring the thunder, Jim.

Posted in Code at 2011-06-18 11:00 | 5 comments | Tags: , , , ,
  • Twitter: pushcx

  • More tweets below and @pushcx