Archive for the 'Technology' category

Rob Zone Arcade

Feb 09 2013 Published by under Technology

Ahh, the Rob Zone Arcade. A year ago I had no idea I would embark upon a project such as this. Let me chronicle for you the journey of the Rob Zone Arcade.

Raspberry Pi

When the Raspberry Pi was announced way back when, it seemed kinda neat to me. A $35 computer, the size of a credit card. At the time, I didn’t really have any ideas for how I would use one, so I never really thought to order one. I do all of my development on a Gentoo Linux machine at home and didn’t need to putz around with a web server at all. So I passed, and waited and waited.

pi

Last fall, however, I came up with a few ideas for a Raspberry Pi. The biggest and best idea I came up with, however, was an arcade cabinet. I found a blog post some guy wrote up about an arcade cabinet he put together. He had an old computer and decided to build it into an arcade cabinet, using emulators. I know he used the MAME emulator to achieve what he wanted. Basically, he went online and found an old wooden cabinet where the guts didn’t work anymore. The game itself was busted and so was the monitor. He tore all the guts out and installed the computer and a power strip inside. He carved out the viewport and mounted a monitor. He took an X-Arcade stick and popped it in, then made custom graphics for the cabinet. He did it pretty damn cheaply too. I think it cost him maybe $200 total. I thought this sounded like a phenomenal use for my Raspberry Pi. So… I began.

It took a good two months for my Pi to arrive. When it did, I was immensely excited. I got home and immediately went to get Gentoo Linux installed on it. Unfortunately, I discovered a flaw in my plan. I assumed that the Pi would allow me to hook up an external USB thumb stick to boot from to then install the operating system. See, the Pi loads its OS from an SD card, which is atypical – most computers load from a hard drive or solid-state drive. This was different. I soon discovered that the Pi can only load its operating system from the SD card. Not from a thumb drive.

sd cards

So I had to wait to install until I got an SD card reader/writer for my Linux machine. I had to get the operating system installed using that machine, then put the card in the Pi to run it. So I did this. I installed Gentoo Linux on the Pi using a guide I found on how to do so. Turned on the Pi… Nothing. It didn’t load. I got frustrated, so I tried the whole process again. Again, nothing. I did a bit of searching online and found an alternate guide that didn’t involve my compiling the Pi’s kernel from scratch. It was similar to most of what I’d done. So I got a different SD card and tried this process. I didn’t use the same card because I thought it was possible that the card I was using was incompatible with the Pi.

It worked! Huzzah. At this point I had a Gentoo installation of the Pi running! I slowly started getting more and more software on to the Pi. Unfortunately, since I was running Gentoo, it would take longer because Gentoo compiles everything from source. I got the Stella emulator running too. It’s an Atari 2600 emulator. I got it running with a gigantic set of ROMs, including my all-time favorite, River Raid. They ran pretty well! I was happy. I had strange issues here and there with sound and some controls, but it was ok.

pi full

Because the compiling of Gentoo packages was taking so long, I ended up getting Stella and MAME installed on my main Windows PC for testing purposes. I figured I’d get ahead and make sure the ROMs I’m getting are going to work with the emulators. This is how I ended up finding some of the initial MAME ROMs I was going to use.

I ended up having to pull the plug on using Gentoo for the Pi. I couldn’t get an X server running on it properly. For those of you who don’t know what X is, it’s this – the graphical user environment, the GUI. Remember DOS? Command-line stuff? Yeah, the “Windows” environment was basically a GUI built on top of that. Well I would need a working X server in order to run some of the emulations properly. And I just couldn’t get it running correctly. I kept hitting my head against a wall in trying to do things that were outside the norm for a Pi. So I switched to an official Linux release for the Pi. And that basically solved those problems… But not the ones that came after.

The other problems started when I tried to get MAME running. MAME is the premier emulator for old arcade titles. You know, the actual machines in an arcade, not home video game systems. I got MAME installed and I was in the process of trying to get some ROMS to work… Then I started having issues. I would get ROMs on to a USB stick and plug it into the Pi, because this was infinitely faster than trying to load up a GUI on the Pi and download them locally. Every time I tried doing this, the performance on the USB stick would decline and eventually the system would stop recognizing it. I thought it was a problem with the stick itself. It wasn’t. I started having issues with the ethernet port crapping out too. It would work upon boot, but after a while it would just stop working. Restarting networking on the Pi wouldn’t solve the issue – I had to reboot, and that wasn’t always a failsafe either.

Needless to say, I was getting frustrated. I did some research online and found the awful truth – there were problems with USB power and Ethernet port power on the Raspberry Pis. How could I run a viable arcade cabinet on a machine that sometimes lost USB power? I was going to have a USB joystick plugged into this thing! So I punted on using the Pi as my arcade machine. It wouldn’t work. I had already spent a month trying in vain to get good emulation going on the Raspberry Pi, and I’d also invested money in the other things necessary to run an arcade cabinet – the joystick and the cabinet. I decided to move on and to get a PC running for the cabinet instead.

X-Arcade Joystick

I bought this while I was still dicking around with trying to get the Pi running. It is a nice piece of equipment. It can run off of an old serial port, which is what older joysticks typically ran off of. It could also run on a PS/2 keyboard port, or the modern USB port. The Pi only has USB out of these three options, so I would always plug it into that. When I started encountering the power issues on the Pi, I knew I had to move on because the joystick cut out a few times and required a reboot of the Pi to get working again.

joystick

I had it shipped to work, since it was a big box and I also had delivery issues during the month of December at my apartment. I opened up the box and some of my coworkers were immediately interested and jealous over it. I mean, it’s a dual joystick. I would have been jealous too! I hooked it up to my work computer to test it out and to get a feel for it. It actually sends keyboard commands to the computer, so by pressing buttons I was entering things into text fields like “1bcp” and CTRL and TAB. It was interesting. Unfortunately, the up direction on the player one joystick would stick. I’d get a string of 8s on the text input after moving the joystick up and letting it go back to its neutral position.

I was able to correct this at home. I hopped online and watched an instructional video on how to adjust the joystick. I popped the bottom of the unit off and found the trigger that hitting up on the joystick interacted with. I made it less sensitive, and that did the trick. A few more tests and the dual joysticks and all of the buttons worked as expected. Awesome.

Initially I wanted to remap the commands of the joystick itself. There are four settings groups that the joystick supports. The first one is not editable, but the other three are. I was going to make these changes, but to do so you had to plug in a PS/2 keyboard to the joystick. Something I did not have. Eventually I also realized that so far, all of the emulators I was running allowed remapping of the commands at the application itself. So there was no need to map the joystick to the emulator. I could do it the other way around.

With the joystick and Pi in place, the next thing I needed was obvious: the cabinet… But…

Low/Mid PC

I had just ordered the arcade cabinet a few days before I decided that I had to give up on the Pi. So I was already invested in a decent amount of money. This is why I decided to not force the Pi and to just get a low-to-mid-range PC running for the emulators. I figured going with Windows would allow me to run beefier things on the arcade than if I was using a 700MHZ Raspberry Pi. I hadn’t built a full PC in almost three years and I thought I could build a decent one for cheaper than I could buy. Off I went to Fry’s!

I already knew some of the things I would need. The cabinet was ordered and it supported up to a 22″ monitor, mounted. It also had four speaker slots, so I’d need a 4-speaker set. Other than that, the requirements for the machine were entirely my own decision. I decided to build it more on the medium side, rather than a barebones system. That gave me a little flexibility in the event I wanted to run more demanding games on it in the future. I shopped around Fry’s and had a hell of a time getting everything in a timely manner.

pc guts

First off, they didn’t have any stock of my first two choices for cases. I ended up going with my third choice, which thankfully had a power supply in it that was strong enough to handle the load I was going to put the machine under. It took me quite some time to find a speaker solution that would work for me. I bought the same brand, but in two sets. A 2-speaker solo set and a 2-speaker with subwoofer set. To make this happen I also got an audio Y splitter for the back of the computer. I got a decent motherboard, CPU and RAM set as well. I wanted to get an SSD for storage, but the price difference was massive, so I opted for a damn-cheap 500GB hard drive.

I got an ASUS 22″ monitor and a cheap (but still way more powerful than they used to be) NVIDIA graphics card, rather than letting the video run off of the motherboard. I got a a Blu-Ray reader, just in case I’d ever need the ability to read a BD-ROM. When I went to checkout, the process was interminable. The cashier had to ring everything up, then realized that the CPU I was buying only had one in stock and it was an open box. So they had to ring everything up all over again to give me the discount. And on top of that, they goofed the second time and had to issue me a small refund because the case I got was also an open box. I don’t typically buy open box, especially from Fry’s, and especially computer parts. But I know they test their open box CPUs, and I couldn’t imagine there being a problem with an open box computer case.

pc prep 2

Boy, was I wrong. The CPU had thermal compound awful close to the pins on the underside, so I took De-Solv-It to the CPU, rinsed and let it dry. Same with the CPU fan. I goofed and got some of the brushed compound on the RAM as well, so I had to give them the same treatment. While those were drying, I started putting the rest of the case together… And found the reason for the open box case. The hard drive bays were crooked. The top was welded in place in one spot too narrow, so you couldn’t actually get a hard drive in almost the entire vertical length of the bays. I managed to fit it in the bottommost bay. And then I had to move the optical drive down closer to it because the power cable split wasn’t far enough to stretch the entire height of the case.

Once the components dried, I plugged them on to the motherboard and started hooking cables internally. And then I realized I should have bought a power supply where I knew what connectors were available. This power supply had only one SATA connector, yet I had two SATA power devices. Additionally, it only had a 4-pin CPU power cable. The motherboard I had was an 8-pin. Seriously, who even builds 4-pin power supplies anymore? Get with modern times, people! I didn’t have any power converter cables for internal computer components, so I had to wait for two to be shipped to me. Turns out there are adapters to make an 8-pin CPU power connector. I also got a SATA splitter to power the optical and hard drives.

pc prep 1

Something else I didn’t realize I forgot was a Windows disc. I figured this wouldn’t be a problem. I could just download a base installer from Microsoft, right? Wrong. The only way you can purchase a base installer for Windows 8 is to buy it retail. Or through an MSDN subscription, which I did not have and was not going to get. You can get Windows 8 online if it’s an upgrade only. This is likely an effort to prevent piracy… Asshats. I spent a couple of hours trying to find a viable way to get a digital download, and punted. Since I had to wait on finishing putting the computer together, I decided to just order a Windows 8 disc and let it arrive with the parts I needed for the power supply.

So the two power supply parts arrived and so did Windows 8. Huzzah, everything works! My cleaning of the components worked and they were appropriate dried out, a mere two days after cleaning. The Windows 8 install went pretty quickly, and I moved fast to setup preferences and to get the Stella and MAME emulators on board. I encountered a hitch when I realized that the new PC was syncing settings with my existing Windows 8 gaming rig / main machine. Got that fixed. Got the emulators setup with the ROMs in place and did some quick testing with the joystick. All seemed well! I used Teenage Mutant Ninja Turtles 1 & 2 for testing, and it went very well. I tested making sure the two speaker sets would work correctly, and did keymaps configurations for Stella. I was going to do the same for MAME, but for some reason it didn’t seem to want to remember the keymappings. I figured that was probably intended behavior and moved on.

Xtension Arcade Cabinet

My original plan for the Rob Zone Arcade (just like using the Pi was in my original plan) was to get an old existing arcade cabinet from Craigslist or eBay. I figured I could find one where the monitor and game didn’t work and pull those out. Put in a new monitor and computer and joystick, much in the same manner that the other guy did in his blog. I did some initial shopping around, but then realized that I might not be able to pull that off. I don’t have any woodworking skills, let alone any place to be able to actually do some woodworking. I ended up stumbling across a cabinet manufacturer that actually built cabinets to work with the joystick I got.

base 1base 3

base 2top

I said what! Yeah. As soon as I saw that, it was all over. Assembly required, of course, but it was perfect for what I needed and could handle. I quickly ordered the cabinet. This happened before I went to Fry’s to get the PC parts, so I knew exactly what I’d need. The cabinet has overhead speaker slots, as well as slots on either side about midway up. The monitor cabinet supports up to a 22″ monitor with all of the appropriate mounting materials, so I just needed the monitor. The cabinet was backordered for almost three weeks before it finally got sent, and then it got stuck in a snowstorm in Missouri, further delaying its arrival time at my apartment.

I took the delays and transit time to make sure I had everything in place that I was going to need. I figured I’d need an extension audio cable and extension power cable for the top speakers, since I didn’t think those two cables would reach all the way down. As it turns out, I didn’t need the power extension and the audio extension was way heavier duty than I’d intended, as well as ridiculously longer than I needed it to be. I also didn’t have a networking solution in place. My bedroom has no wired network in it. I could have gotten a wireless card for the PC, but I knew I’d eventually want to plug in wired network devices in there, such as a Roku player or whatnot in order to play Netflix in the bedroom. So I opted to buy a wireless bridge that would connect to my existing wireless network and provide four wired ports. It came in, I tested it with my printer, and it worked flawlessly. Just a simple button press on both the router and the bridge (I got a compatible bridge) and I didn’t have to manually configure a thing. I also ordered a power squid because there were a couple of power transformers among the various power connectors. I should have paid attention to just how many power connectors I’d need though…

full 1full 2

full 4full 3

The cabinet arrived and I put it together! As is typical for me, I made sure to injure myself as I did so. The instructions weren’t as good as I was hoping they would be, but I got it figured out pretty well. Some of the sections were tricky because of the way they designed the pegs, but it all fit together. The hardest part was getting the light and speakers into the top marquee section. The light was supposed to be drilled in, but I didn’t have any screws that would work for mounting. I ended up using some of my 3M hanging strips, and they worked well (but not after I had to carefully peel them off and put them back on again because the light was too low and interfered with other parts of the cabinet). The hardest part were the upper speakers. I needed them on either side of the marquee, but to put the upper section together you had to lay it on its side. I couldn’t ensure that the right speaker would stay on the right side, if I had to lay it on the left before attaching the side panel. I ended up using more 3M strips to adhere the speakers to the insides of the panels, making sure to measure in so that I could just fit the right side panel on. It worked, first time. Boy was I happy.

I had another issue in mounting the monitor. There were rubber pieces on the back of the monitor where the VESA mount points were, but I wasn’t paying enough attention to why they were there. I thought they were in place to ensure a snug fit with the screws. No, they were there as decoration and needed to be pulled off before mounting, to expose the mount holes. Ten minutes I spent trying to figure out what was wrong. Oy. Blonde moment.

zoom 1zoom 2

So I got it all hooked together! Got the cabinet into the bedroom and put all of the parts and everything inside of it. I ended up putting the wireless bridge inside of the cabinet, because nothing else in the bedroom needs to be wired. When I get more wired components, I’ll take it out of the cabinet and pop it into a different power strip. Because the wireless bridge was in the cabinet, I required six power spots and only had five available. Temporarily I didn’t plug in the upper speakers. Turned it on, and voila! Working arcade cabinet!

I ordered a short 3-part power strip to be able to plug in all of the devices in the cabinet. When I split the wireless bridge out, I’ll take out the extra strip with it so I can get some things plugged in, like the TV and whatever other devices end up going in the bedroom. Took a couple of days to arrive, as always, and I ended up fixing some wires that were up against some internal fans in the PC.

Wrap

I ended up figuring out one final problem when I was doing some final testing of the upper speakers. I had gotten a few more MAME ROMs in the meantime and found they worked on my main rig but not the arcade machine. It wasn’t saving keymaps either. After doing some research, I discovered that I had a strange permissions issue. So I fixed the MAME directory’s file permissions to be accessible by all, and that fixed it. Suddenly I am running all of the ROMs on the machine just fine and it’s saving keymaps. It is awesome.

rom ki

rom tmntrom tmnt2

Basically, I have all of the Atari 2600 games made. And as far as MAME ROMs (remember, these are legitimate arcade titles) I am running:

  • Batman (Meh)
  • Killer Instinct (YESYESYESILOVEDTHISASAKID)
  • NBA Jam Tournament Edition (YESYESYESILOVEDTHISASAKID)
  • Street Fighter II: Championship Edition (I mean, if I didn’t have it, that would be fail)
  • The Simpsons (4-player… haven’t messed with it much yet)
  • Soul Calibur (I haven’t messed with this much yet either, but I loved this on the Dreamcast)
  • Tetris (bootlegged from Japan, but it’s TETRIS!)
  • Teenage Mutant Ninja Turtles (YESYESYESILOVEDTHISASAKID)
  • Teenage Mutant Ninja Turtles 2: Turtles in Time (Another excellent game)

I will gradually add on to the MAME collection, and possibly bring in new controllers like light guns, flight sticks, driving wheels and more where possible and supported.

As far as the Pi goes, I’ll probably generate a new SD card for it and see if I can get Netflix and Hulu running properly on it. If I can do that, then I’ll hook it up in the bedroom. A lot of people have been making Raspberry Pis into legitimate video streaming devices.

No responses yet

PHP, MySQL, Dates & Timezones

Nov 20 2012 Published by under Technology

I’ve recently had the displeasure of working with timezones on my main project at work. I work on an internal administrative system for Buffalo Studios. It has all sorts of functionality, such as content editing tools, customer service tools, reports, graphs and more. Its sole purpose is to make the lives of our internal customers easier, as well as to provide some functionality that doesn’t belong in our game environments.

When my project (let’s call it Admin) initially started, the servers it was running on were all in the America/Los_Angeles time zone. Everything from Apache to MySQL, all in America/Los_Angeles. A few databases Admin connected to were in one other time zone – UTC. When Admin was first built, it was built using the initial version of our internal PHP Framework. This framework had no knowledge of timezones and the like, since it was designed for our games, which are all run on UTC and don’t have to worry much about timezones.

With this in mind, Admin had a small utility to convert UTC dates over to America/Los_Angeles. Any date coming out of these alternate databases were stored in UTC, so a quick PHP conversion for display and I was good. Until recently.

The most recent Daylight Savings Time switch this fall caused some date & time problems for us. Not all of our servers were on UTC, and the fact that the same hour happened twice in a row caused some problems for some of our automated scripts. The decision was made to switch Admin’s servers on over to UTC at our earliest convenience. I didn’t think this would be a big problem, but it sure turned out to be.

The first thing I needed to do was to switch my local MySQL database to UTC for testing purposes. We were going to leave the app itself in America/Los_Angeles, because that’s the timezone that the vast majority of Buffalo operates in. So the system would be UTC and the app would display dates in America/Los_Angeles. That meant that all dates coming out of Admin’s database, after the switch to UTC, needed to have the timezone conversion done to them.

At first, I made this change within PHP itself. The funtionality that allowed me to easily say “this date is UTC, convert it” was extended to all dates coming out of the Admin database. Unfortunately, this posed a problem on our QA environment. QA Admin was still running in America/Los_Angeles, because it wouldn’t be converted to UTC until after our upcoming code release. So dates were borked in the meantime with the app assuming that the source data was in UTC.

Normally I would have just switched the QA server to UTC, but that’s not possible for us yet. QA Admin resides on the same machine as Dev Admin… As well as Production Admin’s MySQL database. So I couldn’t make that switch because it would adversely impact the Production database (this is being remedied early next week – Production Admin’s database will be split to its own dedicated set of servers!). So I figured the dates would just be temporarily borked during testing.

But testing couldn’t be performed properly because there were new scheduler features in some of Admin’s functionality. Being able to delay certain actions until later, for example. So how could the QA department properly test this date-centric functionality? Additionally, what if we needed to make timezone switches again?

I was willing to write these problems off, until I got one more request that made me re-evaluate how Admin was handling dates. The head of our IT department requested the ability for users to be able to set their timezone. We have some users around the world, so it makes sense for them to be able to view dates in their timezone. Thus… I had to rework the way that Admin handled dates.

The first step was for the app to automatically set the default timezone upon load. This was easy:

ini_set('date.timezone', 'America/Los_Angeles');

The next step was to have the user’s timezone preference set as the default as early as possible. This was accomplished in much the same way. We’d select the user’s timezone out of the database and then run the same PHP function above with that result.

One thing I wanted to use was the ability to tell MySQL what my connection’s timezone was. MySQL has the ability to set the system and connection timezone. If you set your connection timezone to something other than the system timezone, then dates that are selected from MySQL are automatically adjusted to your connection’s timezone. This was accomplished by doing the following, in PDO after the connection was established:

$statement = $pdo->prepare('SET time_zone=?');
$statement->execute(array(
    date_default_timezone_get()
));
$statement->closeCursor();

I’m using date_default_timezone_get() because the database connection could be made at any time, after a possible timezone switch. The thing is, though, is that the database connection to get the user’s timezone has already been established. Once I’ve retrieved that timezone, I basically need to set the timezone for any active database sessions:

foreach (self::$databases as $database)
{
    $statement = $database->prepare('SET time_zone=?');
    $statement->execute(array(
        $timezone
    ));
    $statement->closeCursor();
}

The next problem I ran into: not all of our databases are MySQL. Not all of them support setting the timezone. Thus, I still had to backup on converting the dates out of databases to the app’s timezone. Can’t win them all, right? But I had to rework the way the timezone conversion ran. We had a convenience function that did timezone conversion and formatting for output, all-in-one:

static public function dateTimeFormat($timestamp, $isUtc = true, $format = self::DEFAULT_DATETIME_FORMAT)
{
    if ($timestamp instanceof DateTime)
    {
        $dateTime = $timestamp;
    }
    else
    {
        $dateTime = new DateTime;
 
        if (is_scalar($timestamp))
        {
            if (!preg_match('#^[0-9]+$#', $timestamp))
            {
                $timestamp = strtotime($timestamp);
            }
 
            $dateTime->setTimestamp($timestamp);
        }
    }
 
    if ($isUtc)
    {
        $localTimezone = new DateTimeZone('America/Los_Angeles');
        $dateInterval = DateInterval::createFromDateString($localTimezone->getOffset($dateTime) . ' seconds');
 
        $dateTime->add($dateInterval);
    }
 
    return $dateTime->format($format);
}

The problem here is that it assumed America/Los_Angeles for the target timezone… And only allowed conversion from UTC. Well, we now needed to support all target timezones. This function was used a lot in Admin, so it took me a long time to make the conversion over to the following functions:

static public function dateTimeFormat($timestamp, $format = self::DEFAULT_DATETIME_FORMAT)
{
    if ($timestamp instanceof DateTime)
    {
        $dateTime = $timestamp;
    }
    else
    {
        $dateTime = new DateTime((preg_match('#^[0-9]+$#', $timestamp) ? '@' : null) . $timestamp);
    }
 
    return $dateTime->format($format);
}
 
static public function convertFromTimezone($timestamp, $fromTimezone)
{
    if ($timestamp instanceof DateTime)
    {
        $dateTime = $timestamp;
    }
    else
    {
        $dateTime = new DateTime((preg_match('#^[0-9]+$#', $timestamp) ? '@' : null) . $timestamp, new DateTimeZone($fromTimezone));
    }
 
    $dateTime->setTimezone(new DateTimeZone(date_default_timezone_get()));
 
    return $dateTime;
}
 
static public function convertToTimezone($timestamp, $toTimezone)
{
    if ($timestamp instanceof DateTime)
    {
        $dateTime = $timestamp;
    }
    else
    {
        $dateTime = new DateTime((preg_match('#^[0-9]+$#', $timestamp) ? '@' : null) . $timestamp);
    }
 
    $dateTime->setTimezone(new DateTimeZone($toTimezone));
 
    return $dateTime;
}

With these functions, I could properly take any date out of a non-timezone-supported database and convert to the app’s timezone. Additionally, if I needed to insert to these databases, I could convert to their timezone on the way in, as well. The only problem is that any of those databases could just change their timezones in the future, and it would take a bit of time to convert all of the code over if that happened. My next step on that problem, that I have yet to do, is to define constants associated with those databases so that I can reference the constant and only change it once if I ever have to. Or, I could build a way to make that conversion in our modeling systems.

One last problem I dealt with once I started using these functions – DateTime()’s constructor does indeed accept a Unix timestamp. Unfortunately, I had problems with it staying in the proper timezone. I didn’t read 100% of the DateTime() documentation on PHP.net, and thus missed a point where using a Unix timestamp to instantiate a DateTime() always results in the DateTime() setting itself to the UTC timezone. Something else to keep in mind.

So that’s it, right? No, wrong again. MySQL only does conversions on TIMESTAMP columns. DATE, TIME and DATETIME are not supported. And wouldn’t you know it, one of our games’ legacy tables all use DATETIME. So I couldn’t use automatic conversion for those anyway. All that work I put in on these three new functions would be fruitful for having to continue manually converting some dates even out of a MySQL database.

Before you get your hopes up that my odyssey wrapped up there… Don’t. I’m using Gentoo Linux for my local development machine, and everything had been handled for me when I installed MySQL. But Admin is running on Ubuntu servers, and for some reason the default Ubuntu configuration of MySQL does not include automatic installation of timezone support in MySQL. After some research online, I found that I had to manually populate MySQL’s timezone data, like so:

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

Before I did this, I got errors when attempting to set MySQL’s timezone in the connection:

SQLSTATE[HY000]: General error: 1298 Unknown or incorrect time zone: ‘America/Los_Angeles’

After importing from zoneinfo, I was able to set the timezone on the connection. Yet another headache. But, thankfully, once that was done, I was set! I’d handled everything I needed to, so far, to make this conversion work. And these changes all now work on our Dev/QA servers because it doesn’t matter now what timezone MySQL is in for Admin. It automatically converts the dates on the way out. Since it’s a database I have 100% control over, I was able to make sure all dates were defined as TIMESTAMPS. Actually, the Admin database is the only one with the connection timezone set. Our other MySQL databases are outside my control and they do not have the timezones installed. So I have to manually convert anyway, in PHP.

Something to note, though, is that Admin isn’t fully using DateTime() in the way that I want it to be. It would take a lot of effort to make the full conversion, and that’s time I just don’t have. I had to take an intermediary route instead, splicing the style it used to have with a kind of bridge. If I had to do it over again, I’d do things properly from the get-go.

So here are my recommendations for building a PHP+MySQL app that needs to support timezones. In fact, I’d recommend doing this anyway. It’s good practice, especially if your app will be dealing with dates at all.

  1. Use DateTime() whenever you’re dealing with dates. Don’t use time(). Don’t use date(). Just say no to Unix timestamps in PHP if you can help it.
  2. Make sure MySQL’s timezones are installed and always set the connection timezone.
  3. Always set PHP’s default timezone at the app level, then allow user’s to select their own timezone – this should set both PHP’s timezone and the MySQL connection’s timezone.
  4. If you have to manually convert timezones in PHP, associate the source of the data (i.e. a database) with its known timezone. For example, if you have a named database, something like this: const DBNAME = ‘America/New_York’;
  5. Always use TIMESTAMPs in MySQL. You’ll probably want a DEFAULT value, which would be ’0000-00-00 00:00:00′.

No responses yet

I Am Not A Rock Star [Updated Once]

Aug 22 2012 Published by under Technology, Work

The last 10 months have been pretty busy for me as far as job searches go. Last year Meteor Games started its decline towards bankruptcy, which it filed for earlier this year (so far as I know). The big layoff happened in mid-November, leaving me and a few others as part of a skeleton crew to wrap things up for the remainder of 2011. I started my job search during this End of Days scenario and ended up interviewing at a lot of places, before starting at Buffalo Studios to begin the new year.

Unfortunately, my job search did not end there. Things were not all as they seemed at Buffalo for me, at least early on. I was dissatisfied with some aspects of my job at the time and rather than try to stick things out, I ended up resuming my job search. To be honest, I probably shouldn’t have jumped ship so quickly, but I did. I ended up at a company called Needly. Due to circumstances entirely beyond my control, I ended up getting hired in for a job that I didn’t exactly interview for. An unintentional bait-and-switch resulted in my extreme dissatisfaction. Again my job search resumed, and through an interesting chain of events, I ended up back at Buffalo.

I’m very happy at Buffalo now. The problems I had at the beginning of the year are not present. I work on internal tools and systems. Basically, I’m a support guy for much of the organization. Need realtime graphs built? You can probably come to me. Need tools to edit player data? Me. Need a custom web board to surface customer service issues? I’m your man, Stan.

So during the last 10 months, I think you can say I’m pretty in-tune with the current state-of-affairs within the LAMP stack tech market in west LA. I’ve had a bunch of interviews and some code challenges. I’ve seen countless job requirements floating about. I’ve had an insane number of recruiters constantly getting in touch with me about possible opportunities – and all of that started a few months after I started at Meteor, so that’s been pretty constant. The companies I’ve interviewed at have been extremely varied in terms of what kinds of software they work on, their business practices, their culture and more. I’ve come a long way and with all of this experience, here I am to tell you one simple sentence that will require a lot of explanation.

I am not a rock star.

Many, many job requirements I came across use marketing-style terms such as “rock star” and “change the world.” Obviously you know what “change the world” means, but in terms of software engineers, a “rock star” is basically what you’d imagine them to me – someone who kicks ass, takes names and blows the competition away. Ideally you’d love to have tons of rock stars all over your engineering organization, right? Well, of course you want quality engineers. Aside from them, you’ll also need a good product, good product management, good executives, good financial backing, etc. But good engineers, yes.

Typically these marketing terms are coupled in with job reqs that have all sorts of interesting benefits and perks. I came across one that said the company offered three catered meals per day. Per day, folks! Shit, you’d almost never have to go grocery shopping for your home, save for weekends, right? Other perks are things like stock options, foosball tables and more.

I interviewed at one place before joining Buffalo the first time that had some incredible talent in the building. These guys knew their shit. Actually, I came across a few different places that had some high intelligence in-house. I felt humbled by one of them – Gravity. Man, those guys have sick skills and knowledge. More power to them. Anyway, this one place I interviewed at in late 2011 had this mentality of really enjoying what they work on. Everybody is excited to be there. To revolutionize the industry they were in. To change the world. Dedicated to their craft. Getting the job done.

This was all told to me, of course. I wouldn’t have been able to make this kind of characterization of their engineers (and other professionals) during the time I was there. I got so much marketing speak out of these guys it made my head spin. I had to actually ask numerous questions, some that I’m not comfortable asking in a job interview setting, just to get pertinent details as to what their environment and culture were like.

Basically, this place worked their engineers to the bone. I know someone who is friends with one of the leads at this place. He told me they’re pulling 60- to 70-hour weeks regularly to get shit done. They’re staying late on weekdays and coming in at least one day on almost every weekend. And their product hasn’t even gone to market yet. This was not an environment I wanted to be in.

See, places that use terminology like “rock star” and “change the world” are trying to sell you a job. In my experience, these places are looking for guys that have some talent, of course, but talent that they can burn out in no time flat. I understand that west LA is a startup scene. Long hours may have to be put in. But that’s not the kind of stuff I’m interested in. And potential employers can’t put “May work 50-60 hours per week” on their job reqs – they’ll never hire anybody. So they market the shit out of these things to get people in the door.

These places are trying to market a job to me, and I don’t like it. I am really good at what I do, don’t get me wrong. But I’m not a “rock star” because I want to work a human work week. I like putting in 40 hours and having the remainder of my week to myself to do what I please. Run OMGN. Hang out with friends. Play some games. Watch some TV and movies. I don’t want to spend my life working for someone else’s product. Even if I’ve got a bit of a stake in it, because chances are you’ll never make big bucks at a startup if you’re not a founder. The chances of making it big are too low.

Do I want to change the world? Sure. But I don’t want to sacrifice my life to do it. I want to live my life. Why change the world if I can’t enjoy the change I’ve created? Seriously, I’d rather have no catered meals at work at all and work 40 hours than have all of my food paid for because I’m spending 12 hours per day at the office.

I’m pretty close to being a 501 developer. Go read that link. In general, I think the idea of a 501 developer is one that doesn’t care about their craft or output. This is not the case with me. I take great pride in my work. If I push a bug out to production, I take it personally, especially since right now I have nobody on my projects to code review me. I’ve got a decent amount of autonomy at Buffalo and I like that, but it can lead to pitfalls in my output occasionally. Working with others is a good thing. Just the same, don’t mistake my pride in my work for a willingness to work forever.

A job is a business transaction. You’re paying me $X for Y hours per week. I am selling you my productivity. If I do not perform, you can fire me, just like you may replace a car that turned out to be a lemon. It’s a business transaction, to me. So why would I just up an offer to give you more and more of my precious time for the same amount of money? By staying late each day, my effective hourly rate drops because I’m salaried. Seriously, nobody has infinite time on this planet. Why would I give so much of it up when I could be making my quality of life better by spending time with those that mean the most to me?

This isn’t to say that exceptions can’t be made. If that critical system takes a shit, you’ve gotta get up and deal with it, lest nobody have a job when the morning comes. That’s understandable. Emergencies happen. What is not understandable, to me, is an expectation of working more than 40 hours per week. Adjust your product schedules if that’s the case. Don’t burn out your employees. Have a human working environment. Besides, studies made back when the 40-hour work week became standard show that 40 hours is an optimal number for human productivity. Anything more and you start getting more mistakes and diminishing returns.

I will always see terms like “rock star” and “amped up” for what they are – marketing terms to try to get brogrammers in the door. Some of us have lives, you know. Some of us have significant others and kids. Families. Family is far, far more important than putting in that extra 10 hours because you didn’t give enough time to create THE NEXT BIG THING THAT WILL OVERTAKE FACEBOOK.

[UPDATE]

A former boss/coworker of mine shared an article with me and a bunch of other software engineers we used to work with. I couldn’t find it, but he recently re-shared it. This is an excellent read about tech start-ups, and was part of the reason I even thought about blogging in the first place:

Michael O. Church: Don’t waste your time in crappy startup jobs

No responses yet