Second best Final Fantasy game now on PS3

Final Fantasy 7 cover art

Final Fantasy 7 cover art

This popped up in my RSS reader just now. Many people would get into a heated argument with me over what the best Final Fantasy game is, so I’ll just claim seven to be the second-best Final Fantasy game. Any fan of RPGs should play through this at least once, if only to understand why any self-aware game character would fear FMV sequences.

Final Fantasy VII On PlayStation Store Today

Just about every Final Fantasy game has had environmentalist life-force hippie connotations, but I think this one does it best with the whole Mako reactor business. Almost as well as Koyaanisqatsi. I can’t wait to go home and play it!

And this time I won’t leave Yuffie behind.

Converting between Date and Datetime in SAS

In SAS, fields are either character of varying length, or numeric. No exceptions. Temporal values such as Date and Date/Time are stored as either the number of days or seconds since 1960 January 1st.

In order to convert from Date/Time to Date, and from Date to Date/Time, you could divide or multiply respectively by 86400 (the number of seconds in a day).

data _null_;
  d='29FEB1984'd;
  put d date.;
  dt=d*24*60*60;
  put dt datetime.;
  d=dt/24/60/60;
  put d date.;
run;

But unless someone deals with dates every day, it might not be obvious to them by reading this code what those magic numbers are doing.

Another method would be to use put() and input() using functions to go back and fourth.

data _null_;
  d='29FEB1984'd;
  put d date.;
  dt=input(put( d  ,date7.) || ':00:00:00', datetime.);
  put dt datetime.;
  d =input(substr(put(dt,datetime.),1,7),date7.);
  put d date.;
run;

But I don’t consider this any better. It’s wordy. Functions are nested within functions. And you still have a magic number for the call to substr. Also, since it isn’t uncommon for SAS datasets to get into the billions of rows, this probably isn’t the fastest way to do it.

SAS has built-in functions called dhms() (mnemonic: date,hour,minute,second) and datepart() that should make things a lot easier.

data _null_;
  d='29FEB1984'd;
  put d date.;
  dt=dhms(d,0,0,0);
  put dt datetime.;
  d =datepart(dt);
  put d date.;
run;

Static Java List Instantiation

I’ve been out of the loop on straight Java programming for a while, so this is probably obvious to a lot of people, and has been for a long time. But on the off chance that I’m not the only other idiot out there, I’ll post this.

The old way of instantiating a List in Java was like this:

List strings = Arrays.asList(new String[]{"foo","bar"});

In Java 5, templates were introduced, so I had to change to doing this:

List<String> strings = Arrays.asList(new String[]{"foo","bar"});

It just occurred to me that with variable-length methods, I can simply call asList like this:

List<String> strings = Arrays.asList("foo","bar");

Barcamp 2009 Registration is open!

Raleigh BarCamp registration is open. Register here, and do so soon to stake your seat! I couldn’t make it to last year’s, but look forward to this year’s.

A BarCamp is an unconference where people interested in a wide range of technologies come together to teach and learn. … Rather than having scheduled speakers, everyone pitches sessions the morning of the BarCamp. Those sessions are put on a schedule, and lots of little groups form for intense group learning. Everyone is expected to teach, to talk, to participate. Yeah, its different from a regular conference - but it works!

The idea of an unconference came together when people realized the best times they were having at conferences were the times between sessions - where people with like interests could meet ad hoc. The goal of BarCamp is to facilitate this type of interaction for an entire day. We supply the food, the space, the wireless, the projectors - you show up to teach and learn.

BarCampRDU 2009

Reverse the Bits in a Byte in 3 operations

This is among many brilliant hacks from this page.

b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;

The multiply operation creates five separate copies of the 8-bit byte pattern to fan-out into a 64-bit value. The AND operation selects the bits that are in the correct (reversed) positions, relative to each 10-bit groups of bits. The multiply and the AND operations copy the bits from the original byte so they each appear in only one of the 10-bit sets. The reversed positions of the bits from the original byte coincide with their relative positions within any 10-bit set. The last step, which involves modulus division by 2^10 - 1, has the effect of merging together each set of 10 bits (from positions 0-9, 10-19, 20-29, …) in the 64-bit value. They do not overlap, so the addition steps underlying the modulus division behave like or operations.

The genius here, I think, is the modulus division to compress eight specific bits from a 64-bit number down into an 8-bit byte.

World of Goo, 75% off this weekend!

World of Goo

This weekend only, World of Goo is 75% off on Steam. This is down from an already low $19.95 to a mere FIVE DOLLARS. This is your chance to join the morally elite who pay for the things they consume. Strange concept, I know.

World of Goo is one of an increasingly few games to be released without any DRM. It’s an indie game developed by two renegade EA developers. It’s also available on Linux as well as Windows and the Wii! It was released in 2008 with almost universal acclaim scoring a 94% on Metacritic.

For all the nerd-rage on the internet about how much we don’t need DRM, EA sucks, the that games should made for Linux; the fact that this game had a nearly 90% piracy rate suggests that gamers are just hypocrite whiners.

Help reverse this trend. Support indie games. Buy this. It’s five dollars. You will probably spend more on lunch today.

Redirecting with mod_rewrite without breaking OpenID

On philihp.com, I redirect the root address philihp.com to philihp.com/blog. I do this with mod_rewrite, since it’s much faster to do an HTTP Location header based redirect than to use an HTML meta tag redirect. I encountered a problem with this, though.

I want to be able to authenticate with the identifier “philihp.com”. Not “openid.philihp.com”, not “philihp.com/openid”, just simply “philihp.com”, and I have it all setup using phpMyID to host locally, which is good. But rather than put all the server machinery for authenticating at my root level, I like to have it at “philihp.com/openid” (or elsewhere), and out of the way. OpenID has facility for doing this, since it’s almost always done; when a browser visits philihp.com, in the HEAD tags of the HTML, there’s the following:

<link rel="openid.server" href="http://philihp.com/openid/" />
<link rel="openid.delegate" href="http://philihp.com/" />

Where the openid.server specifies where the machinery is for taking care of the authentication, and the openid.delegate specifies what the claimed identifier is. What happens when you go to somewhere like twitterfeed.com, when you try to authenticate there the server itself goes to the URL you give it, looks at the HEAD tags of the HTML it sees there, and forwards the end user to the openid.server specified. The problem I had is that when the server goes to philihp.com, it’s being redirected from mod_rewrite to blog/ because of this thing. This is bad, because it causes my claimed identifier to be “philihp.com/blog/” instead of just “philihp.com”.

I wasn’t the first person to have this problem, though. Haris bin Ali and Will Norris found a solution with PHP that checks the HTTP headers and redirects based on them. Below these have been adapted to RewriteCond rules, which would get evaluated before PHP or any other platform your site runs on (so long as it’s still Apache).

RewriteCond %{HTTP_USER_AGENT} !openid [NC]
RewriteCond %{HTTP_USER_AGENT} !^$
RewriteCond %{HTTP_ACCEPT} !application/xrds+xml [NC]
RewriteRule ^$ /blog/ [R,L]

These say “Redirect empty requests (requests for root) to /blog/, unless the User-Agent header has “openid” in it, or is blank, or the Accept header contains “application/xrds+xml”"; which are all going to be characteristic of a request coming from an OpenID consumer, and not from a normal browser.

The Martini Shot

In film making and photography, the Martini shot is the last shot of the day. According to Dave Knox, it is named so because “the next shot is out of a glass”1.

The second to last shot of the day is the Abby Singer shot. As an assistant director, near the end of a day of shooting, Abby Singer would say “this and one more” so the crew could begin to tear down parts of the set.

Named after Elian Gonzales’ aunt, the Marislasis shot is the third to last, the Maya Angelou shot is the fourth to last shot, and the Lou Nidus shot is the shot before lunch.

Relentless Boarding Parties

Aaron Dixon - Saul
Paul Houlbrooke - Apollo
Sean George - Tyrol*
Chris Rabeler - Baltar
Phil Busby - Roslin
Ken Mather - Boomer*

To shake things up this game, and keep people from picking characters they’ve been before, everyone picked the character for the person to their right going clockwise. Paul made Aaron be Saul first, then it went down in the order above. Phil picked Chris to be Baltar because he’s such a horrible horrible human anyway. Ken picked Phil to be Roslin so Chris wouldn’t be president. Aaron picked Ken to be Boomer so he could be admiral.

Apollo draws Missing G4 Explosives as the first crisis to put Boomer in jail as she starts in the armory. Tyrol puts in 1, pass, pass, Boomer says she’ll take care of it and puts in 3 cards. It fails, and there’s a blue 5 point skill card in it, so Boomer goes to jail, but she accuses Tyrol of sabotaging the check. It’s pretty suspicious though, so Roslin and Saul both think Boomer’s a cylon. Food Shortage advances jump track. Roslin cherry picks Water Sabotage to advance the jump track, then a Survey Team, Forced Water Mining, and Rescue the fleet all advance the jump track for a quick first jump. Saul takes us 3 distance for 2 fuel. Good Saul.

Tyrol draws Declare Martial Law, and the presidency goes to Saul. Then a Raiding Party, but the jump track is at 0, so we just get some friends. Scouting For Water pushes the jump track up, then Low Supplies, then Besieged giving us a base star and friends on the board. Apollo draws Network Computers, and it passes, but Tyrol is all like “oops, blind devotion (his once per game) says it failed”, so instead of advancing jump twice, it goes back once and gives us a boarding party. Tyrol’s turn is next too, and he reveals sending Baltar to sickbay so he draws only 1 skillcard next turn. Crap. He leaves and goes to the Armory, rolls, and hits a lucky 7 removing the boarding party. Baltar draws Analyze Enemy Fighter advancing the jump track, but activating raiders to blow up 3 ships to kill 3 pop. Then a Jump Control Failure pushes jump back one, and population is now in red which is good for making sure the sympathizer sides with humans, but it really is the worst thing to be in red because it inhibits sprinting through jumping early. Boomer draws Elections loom to advance the jump track, but three heavy raiders are about to board.

Cylon-Boomer uses 2xLaunch Scouts instead of 2xMax Firepower to kill the heavy raiders.

Boomer and the Heavy Raiders

Saul’s turn, Boomer says she has two max firepowers to fire on them, probably killing or at least getting rid of two of three, so he executive orders her for two actions. But instead, she scouts twice for bad crises and high-fives Cylon-Tyrol. Technically it was better than execing Apollo, because if Apollo were a cylon, he’d get 3 actions in a row; but we had all forgotten about suspecting Boomer was a cylon from the beginning. She decides to stay a “human” so she can still bomb crises and use her once-per-game. So crises suck for a while, Cylon-Tyrol hits us with his supercrisis, Fleet Mobilization, which fails from already low cards, and advances the heavy raiders further. Baltar manages to shoot at a boarding party killing it, but draws the Guilt by Collusion crisis which fails from a bad skill check. Roslin cherry picks a jump counter with Water Shortage.

We jump past 4 distance, and the sympathizer is neutralized going to the already cylon Tyrol. Heavy raiders urgently need to be killed, as they’re at 2/4 (we lose at 4/4). Saul moves to the President’s Office, and says he has an Authorization of Brutal Force, so the plan is he execs Roslin to use her once-per-game and hopefully draw the other Brutal Force, Apollo execs Saul to use the president’s office, so in total there are 6 quorum draws, and Baltar’s turn to adapt, and maybe Roslin’s turn to do something. And since Boomer didn’t reveal, unless someone’s crisis activates heavy raiders, Saul and Apollo will get turns.

Saul ready to be exec'ed

Saul ready to be exec'ed

So Roslin is exec’ed, but doesn’t draw it. Saul is exec’ed, uses the office to draw one, doesn’t get it, uses his Brutal Force in hand as the second part of the office, then as his second action uses the office to draw, doesn’t get it, so he draws another as the second part and doesn’t get it. Cylon-Tyrol’s turn uses Cylon Fleet to push the boarding party further, they’re right on the edge now. Baltar’s turn, he execs Apollo to use the armory twice, but we’re all out of Strategic Planning cards so we have two 25% chances of hitting (a little less than a 50/50 chance). He misses both times with a 2 then a 3, so the Strat Planning wouldn’t have helped anyway. He draws Boarding parties, immediately activating heavy raiders, and the humans lose.

Before the second jump, humans could have jumped early to bring pop down to 3 at half-time and save the ship from boarding parties, but having 3 pop is really rough. I guess having two cylons actively sabotaging stuff before half-time is really devastating for the humans.

Beep!

Make my computer beep. Go here: http://shatner.philihp.com/beep/