After a few false starts and lots of iteration, I’ve got the process of using the crank to alter the count functioning and feeling the way I intended. First was replacing the functionality that used playdate.getCrankTicks(ticksPerRevolution), with one that used playdate.getCrankChange(), so that instead of being event-driven, it simply tells me how much the angle of the crank has changed each frame (the delta). This change was easy enough to make, but having the numbers smoothly driven by the crank felt like advancing a tape on a reel, while what I wanted was the chunkiness of a ratchet, so of course I had to make things difficult for myself impart a feeling of mechanical operation and friction.
In order to get the numbers to feel like they were “clicking” into place instead of being smoothly translated, I added a multiplier for how far an angle delta would move the affected digit, which decreases as the digit approaches the halfway point. If the delta this frame would move the digit past the halfway point, it adds a little extra so that it jumps ahead (as well as playing a sound effect).
The end effect is indeed more ratchety, getting progressively “harder” until it slips past, which makes it easy to tell when the count updates. The Playdate’s crank moves smoothly and not like the clicky (I’m sure there’s a better word for it) knob on the side of a mechanical tally counter, but the effect is still fairly convincing, especially with the addition of sound (which I’ll need to detail in another post).
Another thing I had to account for was what happens when the crank advances so far in a single frame that two or more digits should go by. In order to make the count increase the proper amount, I check the difference between the current offset and the predicted offset, find how many times the height of the number (100 in this case) it encompasses and change the count accordingly. I considered adding characters to the font that looked like a blur of numbers when this occurs, but even at the Playdate’s default frame rate of 30 FPS, the rapidly changing numbers appear close enough to a blur that I’m satisfied.
Here’s what it looks like in Lua:
function updateVerticalOffsetFromCrank(amount, digit)
local changeToCount = 0
local countMultiplier = 1
if digit == 2 then
countMultiplier = 100 -- adjust for hundreds place
end
local slipAmount = 25 -- slipAmount is how far the tumbler jumps after the count is updated, to emphasize the count changing and feel mechanical
-- change the count if moving the digit this far down would put it more than halfway outside the window
if yOffsets[digit] + amount > (fontHeight/2) then
-- Account for rotating past multiple numbers in one frame
changeToCount = -countMultiplier * ((math.floor((yOffsets[digit] + amount)/fontHeight)) + 1)
yOffsets[digit] = ((yOffsets[digit] + amount) % (fontHeight/2)) - slipAmount
crankMultiplier = crankMultiplierDefault -- reset multiplier
-- change the count if moving this digit this far up would put it more than halfway outside the window
elseif (yOffsets[digit] + amount < -(fontHeight/2)) then
-- Account for rotating past multiple numbers in one frame
changeToCount = countMultiplier * ( ((math.floor((yOffsets[digit] + amount)/fontHeight)) * -1 )) -- + 1
yOffsets[digit] = slipAmount + ((yOffsets[digit] + amount) % -(fontHeight/2))
crankMultiplier = crankMultiplierDefault -- reset multiplier
else
-- Reduce ratio of cranking to tumbler movement as it approaches the halfway point to build up a feeling of tension.
if amount ~= 0 and crankMultiplier < -1 then
crankMultiplier = crankMultiplier - (crankMultiplier / 3)
end
-- not increasing count, just move the tumbler in the appropriate direction
yOffsets[digit] = yOffsets[digit] + amount
end
updateTally(changeToCount, countMultiplier)
end
One last feature I implemented was having the A Button + Crank drive the ones digits and B Button + Crank drive the hundreds digits. This way, it’s easy to very quickly and precisely use them in tandem to set the count to any amount.
Having completed the main ways that the user would interact with it, Tally Pal is pretty close to the minimum viable product at this point, but I still want to do some polish and write some posts about adding audio and the framework for creating/saving/editing tallies.