Sunday, December 26, 2021

My Game of the Year Awards: 2021

Dating back to my days as a kid, one of my favorite hobbies is computer and console gaming. Following the Gamers With Jobs rules -- only games that I played for the first time in 2021 are eligible to make the list -- here are my top 10 favorite new-to-me games of 2021 (along with the platform on which I played each game), in descending order:

1. Metroid Dread (Nintendo Switch)

After nearly 20 years, we finally got a new 2D Metroid sequel. And it does so many things right! Gameplay that deeply respects prior games in the series, yet smartly blazes new territory. Beautiful and finely-detailed graphics. Good map/level design. Tough but fair boss battles. It's probably impossible for the greatness of Super Metroid (SNES) to ever be matched again, but Dread is an excellent modern take on the formula.

2. Bravely Default 2 (Nintendo Switch)

Bravely Default 2 takes the raw materials of JRPGs going all the way back to the first Final Fantasy games, iterates and folds them back on themselves many times, and ends up with this pretty nice piece of gaming origami. The most important thing I look for in a JRPG is combat that is fun, well-balanced, and (ideally) rewards smarts/creativity on the part of the player, and Bravely Default 2 delivers.

3. Final Fantasy Pixel Remaster (iPhone)

Speaking of the first Final Fantasy games: It was a treat this year having in my pocket this update to the very first Final Fantasy featuring a wonderful soundtrack, sharp graphics, and modernized and rebalanced gameplay -- while still remaining faithful to the original. I don't often blog about individual games, but I did do a compare-and-contrast between Final Fantasy Pixel Remaster and the NES original.

4. Monster Train (Windows)

With my primary computer these days being a Mac, I don't do a lot of gaming on Windows, but I made an exception for Monster Train. It's a fun and smart iteration on the Slay the Spire deck-builder-battler genre. (I was initially put off somewhat by the protagonists being the forces of Hell, but it's fine; in Monster Train, the angels are a bunch of jerks, and your team is fighting for self-preservation.)

5. Xenoblade Chronicles (Nintendo Switch)

I'm still midway through this expansive classic, and it might end up higher on a hypothetical 2021-2022 combined list, but for now, here we are! I had originally passed on this game, but the combination of my teenage son recommending it to me as having "single-player MMO" combat, plus wanting to learn more about Shulk from Smash Ultimate convinced me to give Xenoblade Chronicles a fair shake, and I'm glad I did. And I really like the soundtrack!

6. Etrian Odyssey 5 (Nintendo 3DS)

I dusted off my 3DS again during a period where the aforementioned teenage son was monopolizing the household Switch, and discovered that he'd purchased a digital copy of Etrian Odyssey 5 (2017) at some point. I'm only midway through, but the tough combat and old-school DIY mapping using the 3DS's stylus are just as engaging as I remember from earlier series entries.

7. New Pokemon Snap (Nintendo Switch)

I had low expectations for New Pokemon Snap, but they were wildly exceeded when I had a couple of weeks to give it a try on a check-out from my local library. I think the thing I like most is the fact that when you manage to get a great photograph, it's 100% due to your own timing and skill -- not due in part to some huge passive buff from a piece of equipped gear, or a lucky roll on some behind-the-scenes RNG. I'm planning to purchase a copy of New Pokemon Snap for myself when it goes on sale.

8. Steamworld Quest (iPhone)

This deck-builder-battler that's not a roguelike, but is instead a party-based RPG, played really well on the iPhone platform, even though it was originally designed for larger screens. The unique battle system kept me engaged all the way through to the end of the game.

9. Roguebook (Mac)

Another fun riff on the deck-builder-battler-roguelike genre, adding a map exploration mechanic that ends up working a bit like FTL, where you need to do all you can in a given area to power yourself up, before taking on the area boss and advancing. A few remaining rough edges in both minor UI bugs and gameplay balance issues don't hold Roguebook back from being fun to play.

10. Sorcery! 4-game series (Mac)

Also available on iPhone, this isn't just a remaster of the original 1980s gamebook series, but a full remake, taking advantage of the digital platform. A combat system that incorporates a bit of skill, and isn't simply dice-rolling -- and smartly, gives the player the option to immediately replay battles that didn't go so well -- adds to the fun.

Honorable mention

Best new DLC: Fighters Pass 2 for Super Smash Bros Ultimate (Switch). I find it crazy how well this mashup of 82 or so distinct playable characters from dozens of different series actually works in practice. My favorite gaming experience of 2021, eclipsing any of the new games mentioned above, is playing 2v2 local-vs-online matches with the teenage son. (The characters I mainly play are Samus and Ludwig von Koopa!)

Friday, December 10, 2021

Kotlin: My first impressions, via days 1-3 of Advent of Code 2021

While working on Ruby solutions to this year's Advent of Code programming challenges, my attention was caught by one of the sponsored messages running in the site's sidebar, from JetBrains:

Get ready to jingle with Advent of Code in Kotlin! Have fun, learn new things, and win prizes. Believe in magic with Kotlin. Happy holidays! https://jb.gg/AoC

That link redirected to a post on the JetBrains / Kotlin blog inviting developers to try out the Kotlin language via the Advent of Code (AoC) problems, and providing a nice Kotlin AoC GitHub template as a starting point.

I'd never worked with Kotlin before, but I have used AoC to try out new programming languages before. Serendipitously, I had some time available today, and so I decided to give it a go!

In the time I had, I wound up solving the first 3 days of AoC 2021 in Kotlin.  Here's a quick write-up of my very first impressions of Kotlin!

What I liked!

Good out of the box support in the IntelliJ IDE (which I downloaded for the first time today), including suggestions for more idiomatic Kotlin syntax. (Which makes sense, as JetBrains provides both the IntelliJ IDE and the Kotlin language itself!)  I was saved from some instances of typical "trying to write language X as if it were language Y" newbie mistakes by warnings/suggestions in the IDE.

IntelliJ displays, inline in loop declarations, whether the lower and upper bounds are inclusive of exclusive. This made it easy for me to understand whether, in a Kotlin until loop over an array, I needed to use myArray.length or myArray.length - 1 as the upper bound of the loop. (The former!)

I found the data class syntax to be a nice succinct and readable way for a method to return some related values. In a method in one of my Ruby AoC solutions where I was returning two values just wrapped together in an array, it was easy in the Kotlin equivalent to declare a one-liner data class, and then have my method return an instance of that class, to make what was being returned much more obvious to readers.

If ... else in Kotlin is an expression, not a statement. While looking up an equivalent for the typical ? : ternary expression syntax, I actually enjoyed discovering that ? : is actually not supported in Kotlin, and an inline if ... else should be used instead.

Support for ".."-syntax ranges like in Ruby (e.g. (5..15) to represent the set of integers 5 through 15, inclusive) was fun to see in a C-like language.

The variable-declaration keywords val and var, similar to let and const in JavaScript ES6, to respectively declare immutable and immutable variables.

The ability to pass a function "pointer" as a parameter to a function -- something both the Ruby and Kotlin variations of my Day 3 solution actually made use of.

 

What I maybe didn't like so much

I actually wasn't aware of this ahead of time, but Kotlin is built on top of Java. (Or perhaps it's more accurate to say that Kotlin, like Java, is a language that runs on the JVM?) The first time I became aware of this was when my program threw an exception... and there was a mix of Java and Kotlin code in the call stack. I have no idea to what extent aspects of Java poke their heads up while working in Kotlin... but it's something that I'd want to understand more about before committing to using Kotlin for a real project, versus other available languages where that kind of thing is much more of a non-issue.

JetBrains' Kotlin template for AoC helpfully included a check call to test each problem's provided sample answer against the corresponding sample input. What wasn't so helpful was that a failure of the test just resulted in a generic java.lang.IllegalStateException : Check failed -- with no accompanying mention of the check's expected or actual values. I had to manually add a print statement to find out what the failure was. Maybe I was just missing something?

I ran into some trouble using the built-in pow to raise 2 to the power of a particular variable:

  • It took me a little while to figure out why I was getting an Unresolved reference: pow.  I ended up googling for that exact phrase, while led me to discover that an import kotlin.math.* is needed. Not surprising in retrospect, but it would have been nice to a a prompt in Kotlin's error message about an import/reference possibly being needed. (I believe C# does this, probably among others.)
  • The pow method (as of the current version, 1.6) can't be used on integers. After a little more confusion, I figured out that I had to use the literal 2.0 (instead of just 2), and then manually convert the result back to an Int after getting my result. Why make developers do that?

 

Verdict

Verdict? It's much too early for a verdict! I only worked with Kotlin for a few hours, on some toy problems, on my own! 

It was fun, though, to get to play with a new language! Kudos to the Kotlin team at JetBrains for their combination of the Advent of Code sponsored message, their blog post, and the Kotlin Advent of Code GitHub template, which taken together, were enough to get me to take a look at Kotlin!

And if you're a developer but have never taken a look at Advent of Code before, I strongly recommend checking it out! The event is extremely well crafted and executed each year. It's worth your time!

Thursday, October 07, 2021

Git tip: Visual indicator of the 50-character git commit summary message limit

Although it's somewhat too short for my taste, I generally comply with the conventional wisdom of having the summary line of git commit messages be no more than 50 characters.

Even using an editor that shows the current position of the insertion point (such as vim with set ruler enabled), it's not readily discernible how much of the available 50 characters remains, relative to text that has been keyed in so far.

My solution to this has been to set up a ".gitmessage" commit message template that includes a comment showing the 50-character limit:

 
 
#                                                  |<-- 50 char summary line limit

As long as my summary message ends before that vertical pipe character, I'm good!

Friday, September 03, 2021

New iOS app: Gong Sound

Would you like the ability to make your iPhone to emit a "gong" sound? Further, would you, ideally, like that gong sound to be accompanied by a low-fidelity, semi-realistic animation of an actual swinging gong? If so, then do I have the app for you!

Introducing Gong Sound, available for free on Apple's App Store!

Amazing features

  • On a tap, the app emits a "GONG!" sound! Wow!
  • The gong swings back and forth -- in a physics-approximating, 7-frame animation! -- for a few seconds after being tapped!
  • iPad support!
  • Supports landscape (device held sideways) mode!
  • High score counter! (With classic-arcade-like non-persistence!)
  • No ads! No in-app purchases! No data harvesting! No review nags! No network connectivity used or required! 
  • FREE!

Wait... so it's just a gong app?

Yep. 🙂 The Gong Sound app is just a "toy" project. I got the code written, and the art and sound assets adapted, for the initial 1.0 version in all of a couple of hours. (As compared to the dozens of hours that I spent on Desktop Journey, or the hundreds spent making Vigil RPG!)

At my company, teams strike a gong that we have in the office as (part of) a celebration of notable achievements.  In these days of remote work, I figured: Why not give folks an easy way to "gong" from home which sounds better than banging pots and pans together, and isn't likely to play an ad instead of the desired sound effect when the "Play" button is pressed. 

(And doesn't violate any of the items in that second-to-last bulleted list item above, in the fashion of most existing similar apps on the App Store.)

Gong Sound is a free download on iOS devices, so if you're reading this post on your iPhone: Share and Enjoy!

Thursday, August 05, 2021

Impressions: Final Fantasy 1 Pixel Remaster (iPhone)

Square Enix recently released "Pixel Remaster" versions of the first three games in the Final Fantasy series. Over the past four or so days, I purchased, played through, and completed the iPhone version of Final Fantasy 1 Pixel Remaster.

As a veteran of multiple playthroughs of the original NES version of Final Fantasy 1, I thought I'd share my impressions of this update to this classic game, focusing mostly on compare/contrast of the new pixel remaster version with the original.

With the original Final Fantasy 1 having a high frequency of standard enemy encounters plus a very limited number of spell slots, my favorite party composition is Fighter, Black Belt (Monk), Thief, and Red Mage. That’s also the party that I used for my playthrough of the remaster.

Final Fantasy 1 Pixel Remaster Battle: 6 ogres vs party of Fighter, Red Mage, Thief, and Monk

All-caps character names for old times' sake!

Spoiler statement: This article avoids spoilers about game plot / events, and for the most part, about specifics of particular dungeons and enemies. There are some mentions of particular character abilities and spells.

Quality-of-life improvements 💆

These are numerous! Some highlights that I noted during my playthrough:

Auto-battle. ⏩ The remaster has a button available on the combat screen which causes the party continuously repeat whatever actions they performed last round, and also increases the speed at which the battle plays out. Both a convenience (particularly on mobile, where performing precise button taps multiple times every round to select actions is more annoying) and a time-saver for when the party is moving through an area of easily-winnable battles.

Tap to move. 👆 The iPhone remaster takes nice advantage of the touch screen by providing an ability to tap a location on the screen to move there (as well as a traditional on-screen D-pad option). Movement speed when en-route to a tapped location is also significantly increased, which is a nice time-saver.

Save anywhere. 💾 One “quick save” slot is available which can be used in any location. Definitely a must-have feature in a mobile game like this — at least, for a game not featuring automatic continuous progress saving (like at least one other RPG native to the iOS platform I’m familiar with!).

Unlimited inventory space for weapons and armor. In the NES original, there was no shared inventory pool for weapons and armor. Instead, each of the four characters could hold four weapons and four pieces of armor — and once those 16 slots of each type were full, there was no picking up more until space was freed up. (This resulted in a sort of primitive encumbrance system!)

The remaster features a modern-style, unlimited-size shared inventory pool (similar to later Final Fantasy games). This ends up being a gameplay advantage as well as a quality-of-life improvement. There isn't, for example, a decision between keeping a helmet with the best armor rating, and a helmet with a lower armor rating but with a special ability usable in battle. Now you can equip the former, while using the latter as an item in battle out of the shared inventory pool.

Dungeon maps. While in dungeons, a scrollable map of the current dungeon level is available — even portions that haven’t been explored yet. Handy for avoiding the dead end corridors that are a part of a number of the dungeons.

World map. 🗺 It’s readily available now — no “TCELES B HUSP” required! Additionally the maps shows counts of the treasures and key items available in each visited location, and the number of each of those obtained. Handy for going for 100% completion! Speaking of which:

Achievements. 🏆 The remaster has them! I’m not sure they’re integrated with the iOS Game Center achievements system, though. (I can’t speak to the Steam or other versions of the game.)

No more invisible, fixed enemy encounters. In the NES original, there were a number of spots/squares in dungeons -- often immediately in front of important treasure chests -- where a fixed enemy encounter would take place when entered. (Repeatedly, if you left the square and then returned!) This has been replaced with (1) those encounters being triggered via the relevant treasure chest being opened, or (2) the enemy being visible on the map, with the encounter initiating when the enemy is character is interacted with. (The "Hall of Giants" is implemented in the latter fashion.)

Automatic use of key items. 🗝     There were a few spots in the original game where you needed to open the menu and use a particular key item at a particular location in order to progress. That's smoothed out in the remaster, with the appropriate key item being used automatically when you arrive at the appropriate location. I can definitely see this feature saving a few new players a trip to a FAQ to figure out what they need to do next.

Fast potion buying. Buying 99 healing potions is quick and easy now! No need to visit a shop with healing potion of at the top of the list, and zone out for several minutes while mashing the A button (or using a controller with a turbo function!).

Balance and Gameplay changes ⚖

(📉 Difficulty nerf) Better potions! 🍾 The original Final Fantasy featured only three types of potions: HEAL (restoring 50 HP), PURE (removing poison), and SOFT (curing petrification).  The remaster has those, and additionally makes available at stores Hi-Potions (restoring 150 HP), and more significantly, Phoenix Down (restoring a slain warrior to 1 HP). 

The availability of Phoenix Down in particular is a game-changer, as it makes reviving slain warriors possible before the Life spell is available at white magic level 5, and also removes the limit on the number of revives that can be performed in a given dungeon delve being tied to the number of level 5 white magic slots available.

Ether potions (restores 1 spell slot of each level) are also available at shops, making it possible to restore spell slots while in dungeons -- something that was not possible at all in the original game.

There are also a few additional status-restoring items in the game, although I found that I didn’t really use those in my playthrough. (The enemies in the game’s first large dungeon are as poisonous as ever, though! I burned through some 20 or 30 antidote potions while in there.)

Finally, there are a just a few X-Potions (fully restores HP) and Elixirs (fully restores HP and MP). These came in handy for me at one particular spot in the late game, when the warriors have much more HP than a Hi-Potion is able to recover.

(📉 Difficulty nerf) Lower gold costs / more gold rewards. 💰 Costs at shops are lower in the remaster. I was always able to afford everything I wanted at shops, with no need to grind for gold at all, or otherwise save up. I even bought the expensive “steel armor” / “knight armor” that’s available for sale at a high price (about a third of the way through the game), which I don’t believe I ever did in the original game.

(📉 Difficulty nerf) Faster leveling / easier foes? Most enemies and encounters seemed less deadly in the remaster. For example, in the original, having the entire party get stun-locked for multiple rounds by groups of undead with paralysis attacks was a big concern in some mid-game dungeons. I never came close to having this happen in the remaster. 

Further, in some spots in my playthrough of the remaster, my party felt over-leveled for the enemies I was facing. A particular undead mini-boss in the first half of the game went down especially easily (in the first combat round). Much of the second half of the game in general felt pretty easy difficulty-wise. The major dungeon after the “prove your courage” event in particular felt more like a victory lap than a challenge. (I do recall this to some extent being the case in the original game as well, however.)

(📈 Minor difficulty buff) Multiple large enemies. 👹 In the NES original game, fights were limited to a maximum of four large-size enemies (such as ogres) at a time, due to screen space constraints. In the remaster, although most fights stuck to the constraints of the NES original, I did have a handful of fights against 5 or 6 large enemies at one time, as pictured at the top of the article.

(📈 Difficulty buff) The final boss. 👿 Without getting into spoiler territory: With a well-prepared and properly-equipped party, the final boss in the NES original game could be fairly reliably defeated. In the remaster, although my party never had a wipe prior to the final boss, beating that last boss took me a good dozen or so attempts! (I do suspect that having a White Mage on the team might have made things significantly easier.) I was definitely glad for the ability to create a save immediately before the final boss fight in the remaster!


Bugs fixed 🐞🔨

This is almost certainly not a complete list, but here are a couple of fixes that I noticed that the remaster made over the original in my play through: 

The TMPR / Temper and SABR / Saber spells. Evidently in the original game, these spells were buggy, and had no effect on combat at all! I verified that they do indeed work now, and are effective melee buffs — along with the FAST / Haste spell, which is a very effective melee buff in both the original game and the remaster. (Pro tip: In the remaster, these spells can all be stacked onto the same character for a greater effect, too!)

Darkness status. 🕶 This is another one in the original game that didn’t seem to do anything at all. In the remaster, although I didn’t test exhaustively, it did appear to cause both warriors and enemies to deal fewer hits in melee. I actually did have my Red Mage use the black magic Darkness spell in a few combats against large groups of melee enemies.

New bugs 😱

Unfortunately, I did notice a couple of new bugs introduced by the remaster! (At least in the 1.0 launch version. Maybe these will get corrected in a post-launch update?) 

Elemental protection buff spells miss! 🔥 The NulShock / NulBlaze / NulFrost spells (formerly ALIT / AFIR / AICE) (reducing damage of the applicable element by half for the entire party) worked great and were effective when I first obtained them in the remaster. In particular, a battle with a fire-themed major boss was made much easier in my playthrough by the NulBlaze spell. 

Unfortunately, when I tried using these spells in the late game, about 90% of the time, they resulted in “miss!” on each of my own party members, instead of the buff being applied! I assume there’s some bug where the warriors’ evade chance is being applied to these spells, as they would be to incoming enemy status-affecting spells. 

Monk “optimal” equipment. 👊 When pressing the “Optimal” button on the equip screen for my Monk (formerly “Black Belt”) character in the early parts of the game, the game equipped the monk with one of my nunchaku items — even past the point where the monk would work better fighting unarmed (dealing a bit less damage per hit, but more hits). It’s easy to see this issue tripping up new players, making the monk class less effective than it should be for them.

Miscellaneous improvements ⚔

Music. 🎶 The music is not just remastered versions of the original chiptune NES tracks, but actually re-recorded as orchestral tracks. They really are great-sounding. They are very true to the original versions. Some of the original tracks that were very tight loops in the NES original, such as the shopping music and menu music, have gotten new extended versions, which are also great.

Dungeon backgrounds. 🌵 Each location has a new and nice-looking battle backdrop.

Spell animations. 💥 Each spell in the remaster has a unique and beautiful animation!

Dialog text. 💬 All of the dialog text in the game has been retranslated and improved. (The protagonists are still completely silent, however.) I did notice and appreciate that the classic line very early on in the game, "I, Garland, will knock you all down!" was preserved as-is, though!

Enemy names. The enemies have been assigned names that are more true to (what I assume are) the Japanese originals, are better translations, or can fit now that name length constraints are relaxed somewhat. A few such changes off the top of my head:

  • IMP ➡ Goblin
  • MadPONY ➡ Crazy Horse
  • BONE ➡ Skeleton
  • CREEP ➡ Gigas Worm
  • SAHAG ➡ Sahagin
  • KYZOKU ➡ Buccaneer

In-game hints. 💡 At least in the early portions of the game, if you talk to the dancer NPC in the starting town, she'll give you a hint as to what you should be doing next, a feature which is new to the remaster. (Another NPC in the castle near the starting town will clue you in that the dancer will do this.)

Things kept the same! 🛡

Character classes. No new ones, and they work the same as before!

Magic. 🪄 The system of a fixed count of available spell slots per level remains in place (instead of a more modern MP pool system). This keeps the system of needing to use potions instead of white magic for most healing outside of battle, and needing to use offensive black magic sparingly in general -- especially in the early game -- the same as it was originally.

The available spells, what they do, and which character classes can learn which spells, are also unchanged.

Items. The equippable items and key items available in the game, where they can be found, what they do, and which character classes can use which items, are almost entirely the same. 

(A single exception that I noticed: The "silver sword" / "mithril sword" is no longer available for sale in the elf town. Getting into why it was probably removed would touch on spoiler territory!)

World map, towns, and dungeon layouts. No changes that I spotted!

High random encounter rate. Random encounters occur quite often in both versions of this game! The above-mentioned auto-battle feature definitely makes this more palatable in this current day and age, particularly for a mobile game.

Deadly enemies! Some enemies that were particularly deadly in the original game remain so in the remaster! A particular type of enemy present in a mid-game ice-themed area with multiple abilities that can instant-kill individual warriors retains those abilities in the remaster. (The availability of Phoenix Down potions in the remaster does make the possibility of a warrior being taken down in that way a lot less scary!)


Overall recommendation: 👍

For anyone nostalgic for the NES original and looking for a solid premium RPG for their iPhone, I can easily recommend picking up this version of Final Fantasy!