Holy expletive, Batman! One-Armed Space Bandit for Playdate has been updated to version 1.0.2!
This update includes the following improvements and features:
- New cheat mode
- Custom pause screen
Cheat Mode
The original version of the Slots o' Death from Space Quest 1 was infuriatingly difficult, which generally was only possible to defeat via save scumming. In the VGA remake of the game, Roger can find a gadget to attach to the slot machine which assists in more wins. But one alternate way to "win" in the original EGA version of the game was to type the phrase HOLY and then an expletive word, then the game would allow you to select which winning combination you want.
Issue #10 of Uncrank'd magazine had an article about the RUBDUBDUB cheat code which has become the unofficial Konami-code for Playdate games. This was exactly in line with what I had already been looking into for the previous version of this game, but did not manage to implement the "feature" at that time, especially since there is no START button on the Playdate to emulate the Konami code.
Try out the RUBDUBDUB code from the title screen of this update and see what happens!
Pause Screen
A little extra polish was added to the game by adding a custom pause screen, which shows the game's name and version number, laid on top of an image of the famous Pillars of Creation. The background image was created using a Shidoku ordered dithering method, as part of my ordered_dithering project which experiments with a number of different algorithms.
Technical Details
Cheat Code
During the development of version 1.0.1 I had been looking around for a way to implement a Konami-style cheat code and had come across the Tanuk_CodeSequence. Trying to implement the actual Konami code wouldn't work, but once I read the Uncrank'd article about the RUBDUBDUB code, that inspired me to take another crack at getting this to work.
From the title screen's initialization method I added the following code snippet to set up the code listener:
-- RUBDUBDUB Cheat Code
local cheatCode = Tanuk_CodeSequence({pd.kButtonRight, pd.kButtonUp, pd.kButtonB, pd.kButtonDown, pd.kButtonUp, pd.kButtonB, pd.kButtonDown, pd.kButtonUp, pd.kButtonB}, function()
Noble.GameData.CheatMode = true
playCheatSound()
end, false)
I initially tried a couple of different codes at the same time, and I was not always able to get each of the codes to trigger, or on some occasions, it would cause other parts of the game to lock up, or even worse, cause the entire Playdate to crash. The following is an example of one crash error I saw a few times during testing:
libraries/Tanuk_CodeSequence.lua:39: attempt to perform bitwise operation on a nil value (field '?')
stack traceback:
libraries/Tanuk_CodeSequence.lua:39: in function
[C]: in field 'update'
libraries/noble/Noble.lua:430: in function (playdate)
Fortunately, this is an open-source library, so I went into the Tanuk_CodeSequence.lua file and made the following addition to guard against any nil values.
local initialValue = self.sequence[self.sequenceIndex]
-- Also validate the first item in the sequence array is not empty to avoid the crash
if initialValue == nil then
return
end
if self.sequence[self.sequenceIndex] & released ~= 0 then
...
end
Trying to use the RUBDUBDUB code may not work in many areas of a game, especially if the controls affect the gameplay, but in certain cases like a title screen, it works as a useful way to implement that classic Konami code functionality.
Pause Screen
Displaying a custom pause screen is fairly straightforward by calling the playdate.gameWillPause() method and setting the background image. The background image still needs to be the same dimensions of the screen at 400x240 resolution, but only the left half of the image will be visible, effectively 200x240. For this particular background, I experimented with a variety of different ordered dithering algorithms (Bayer, Magic Square, Shidoku, Void-and-Cluster) before settling on the look of the Shidoku variant. To add further custom details on the screen, such as current game stats, everything is treated as a rendered image. By creating graphics context, one can add and alter additional content, which will be rendered onto the final pause screen image.
-- Set up the Pause screen when the Home button is pressed
function playdate.gameWillPause()
local pauseImage = gfx.image.new("images/pillars_small_shidoku_dithered_4x4")
assert(pauseImage)
gfx.pushContext(pauseImage)
local versionString = "*v" .. playdate.metadata.version .. "*"
-- Set both of these to black to ensure the background remains dark, even on the game screen
Graphics.setColor(Graphics.kColorBlack)
gfx.setImageDrawMode(gfx.kDrawModeFillBlack)
gfx.setDitherPattern(0.25, gfx.image.kDitherTypeBayer4x4)
playdate.graphics.fillRect(0, 216, 200, 240)
-- Clear the dithering pattern
gfx.setImageDrawMode(gfx.kDrawModeFillBlack)
gfx.drawText(versionString, 80, 221)
gfx.setImageDrawMode(gfx.kDrawModeFillWhite)
gfx.drawText(versionString, 80, 220)
gfx.setImageDrawMode(gfx.kDrawModeFillBlack)
gfx.popContext()
playdate.setMenuImage(pauseImage)
end
Keep on cranking and earn (or steal) those Buckazoids!