A Love Letter to Games

I’ve been a life-long gamer.

I began my gaming career as a child, when my parents acquired an Atari 2600 in the early 1980s. Shortly after their divorce, we acquired an Intellivision, which I now consider the single greatest console of all time. The Intellivision captivated my interest in gaming until the mid 1980s, when I was gifted an NES around winter of 1986. I instantly fell in love with Mario, Contra and Punch Out on a little 13″ color television that I had in my bedroom: I’d sit on the edge of my bed, mere inches away from the TV, fully absorbed in squishing goombas.

It was a great time to be 8.

Computer-based gaming caught my attention around 1987 when my mother purchased an Apple IIc. I was hooked on public domain games that she would bring home from school. For the first time, I wanted to know how these games were made, and so I began reading up on programming Applesoft BASIC. Later, a kids magazine (and I can no longer remember the name of the magazine) began publishing code snippets for Applesoft BASIC. This was programming gold, and I remember the frustration of transcribing line-by-line the code that let you inflate a balloon by repeatedly tapping the space bar. If only a single character was incorrect, it wouldn’t work. A valuable lesson, for sure.

I moved to PC gaming in the late 1980s. I became hooked on Sierra adventure games in 1989 (and I still posses boxed copies of the Colonel’s Bequest and Conquest of Camelot). 1992 rolled around and I became obsessed on Wolfenstein 3D, followed shortly thereafter by Doom in 1993. I have fond recollections of downloading Doom from a BBS and subsequently sending it to my friend over ZMODEM on a 300 baud connection.

It took all night.

Meanwhile, I had picked up a fully-licensed copy of Borland C++ and began the slow, agonizing process of self-learning the low-level details of the hardware and software. At the time, I had no idea what I was doing.

Between 1991 and possibly 1995, I had access to a shell-based internet connection provided by Nova Southeastern University. I ended up writing graphical “games” in no time, following tutorials I found online on something called the “world wide web” over an application called Lynx. This stuff was awesome! And few of my friends understood.

I wanted to make games like Doom.

Sometime around 1995, during a high school programming class, I wrote my first complete computer game in Pascal. It was a Space Invaders-style ASCII-based shooter, complete with powerups. The code was terrible. I wish I still had it.

PC games held my attention for over a decade. I didn’t return to console gaming until 2005 or so, when I purchased a (possibly used) Xbox. Then the Wii, then the Xbox 360.

By the mid-2000s, I was deep into a programming career. I had cut my teeth professionally on PHP, Visual Basic, and C#. Somehow, I ended up becoming an applications developer, not a game developer. But that’s okay, it’s what I wanted, really: Stories from the trenches of game development were always unpleasant, with tough deadlines and missed releases and late night and weekends and stress. It would have been fun, I think.

Looking back at what I’ve accomplished in my life so far, it’s really the classics that helped nudged my career and shape by interests. Luminaries like Shigeru Miyamoto, Roberta Williams, Christy Marx, John Carmack and Will Wright became my heroes.

Indeed, my software career began in the early 1980s, with those first awkward button mashes on the Atari 2600, followed by a fascination with gamepad inserts on the Intellivision, followed by the simple elegance of Super Mario Bros.

Pitfall, Astrosmash, BurgerTime, Lock ‘N Chase, and Armor Battle all paved the way for my lifelong fascination with computing. Without Punch Out, the Legend of Zelda, Super Mario Bros. or Contra, I doubt my interests in PC games would have blossomed.

Without Quest for Glory or Space Quest, Conquest of Camelot or the Colonels Bequest, I may never have had an interest in Wolfenstein 3D or Doom. I would not have had the desire to learn the low-level details of the machine. I would not have picked up Borland C++.

These weren’t just games.

They were gateways.

<3

Wherein I learn that some developers don’t know how to play well with others and get upset about it.

First, apologies to Stephen Hawking and Dan Rosenberg for the title.

Second, some back story…

Years ago, I was responsible for a web-based application that consumed a small XML payload, performed some calculations and spit out a small XML answer.

The application consumed and produced very precise coefficients, such as 0.000000000000007.

As the application matured and time progressed, we eventually had to split the calculation model from the validation model in order to handle change-management procedures. Additionally, we were slowly aligning our core platform with a future-state vision, little-by-little moving chucks of code from Platform A to Platform B.

In order to prevent a platform war and to Maintain Focus, I’m going to simply state that I developed on Platform A, while another team within my organization developed on Platform B.

To validate code changes in Dev, we’d run tens of thousands of rows of test data through both the validation model and the calculation model.

Test data was always constant.

Production data was variable.

Uh oh.

Continue reading »

Tagged with:
 

Here I go, changing the interface. Again.

I continue to refactor wordptr.libpwd.

The following methods have been added to or changed in the wp_configuration_t interface:

  • Name Changed: get_daemon_on_start_method
  • Name Changed: set_daemon_on_start_method
  • Signature Changed: populate_from_file
  • Added: set_config_file_path
  • Added: set_lock_file_path
  1. typedef struct wp_configuration {
  2.   wp_status_t (*populate_from_file)(struct wp_configuration *self, const char *file_path);
  3.   void (*set_config_file_path)(const struct wp_configuration *self, const char *value);
  4.   void (*set_lock_file_path)(const struct wp_configuration *self, const char *value);
  5.  wp_daemon_on_start_method_fn (*get_daemon_on_start_method)(const struct wp_configuration *self);
  6.   void (*set_daemon_on_start_method)(const struct wp_configuration *self, wp_daemon_on_start_method_fn fn);
  7.  /* additional methods left out */
  8. } wp_configuration_t, *wp_configuration_pt;

I made a decision to (re)name all events following an “on” semantic, such as “on_event.” For example, see the method name change for “get_daemon_on_start_method.”

Additionally, I’m still cleaning up the cruft left over from converting the project from the original stand-alone Linux daemon tutorial. There’s a lot of worthless code in the library at the moment, but it’s being stripped out.

Finally, I’m beginning to add documentation.

Have fun.

Tagged with:
 

It’s (slowly) getting somewhere.

I updated the libwpd configuration settings in wordptr.libwpd to support a client override of the default daemon loop. This method gets injected into the daemon start method on reconfiguration.

There’s a little more work to do in this space, but here’s a brief outline:

First, the following typedef was added for the hook signature:

  1.   /* start method hook signature */
  2.   typedef void (*wp_daemon_start_method_fn)(const struct wp_daemonizer *);
  3.  
  4.   /* Example in client code */
  5.   void daemon_start(const wp_daemonizer_t *self);

The wp_daemon_start_method_fn typedef is utilized by the internal configuration class with the following getters and setters:

  1.   wp_daemon_start_method_fn (*get_daemon_start_method)(const struct wp_configuration *self);
  2.   void (*set_daemon_start_method)(const struct wp_configuration *self, wp_daemon_start_method_fn fn);

Finally, the hook is installed within the client reconfiguration method like so:

  1.   static void reconfigure_daemon(const struct wp_daemonizer *daemon, const wp_configuration_pt config) {
  2.     config->set_daemon_start_method(config, &daemon_start);
  3.   }

If the hook is not installed, the daemon creates its own loop: It sits in a perpetual wait state, listening for signals. By overriding the main loop with your own daemon_start method, you can alter the default run loop.

The current default run loop looks something like this (see the latest commit on GitHub for wp_daemonizer.c, method wp_daemonizer_start):

  1. static wp_status_t wp_daemonizer_start(const wp_daemonizer_t *self) {
  2.   assert(self); /* make compiler happy */
  3.   sigset_t mask, oldmask;  
  4.   wp_daemon_start_method_fn start_fn = self->data->config->get_daemon_start_method(self->data->config);
  5.  
  6.  
  7.   if(start_fn != NULL) {
  8.     start_fn(self);
  9.   } else {
  10.     sigemptyset(&mask);
  11.     sigaddset(&mask, SIGUSR1);
  12.     sigprocmask(SIG_BLOCK, &mask, &oldmask);
  13.  
  14.     while(true) {
  15.       sigsuspend(&oldmask);
  16.     }
  17.     sigprocmask(SIG_UNBLOCK, &mask, NULL);
  18.   }
  19.  
  20.   return WP_SUCCESS;
  21. }

Note that in the override case, the sigsuspend method is never called. Consider a similar pattern in your own main loop or you’ll eat CPU cycles.

Have fun.

Tagged with:
 

These things are neat/useful.

I’ve used a lot of different tools over the years. As I’ve aged, some tools have remained staples of my development toolbox. Others have fallen by the wayside, never to be executed again.

Here’s a list of tools I use throughout the day/week/month. This will be a living post of sorts: My toolbox changes all the time and I’ll do my best to keep this list as current as possible.

Be forewarned, however: I’m a developer of esoteric taste!

Continue reading »

Tagged with: