SPIDER.PRG
WHAT IT IS.
A long-running personal project to write a working Spider solitaire by hand, twice, in two unrelated stacks. The first version was an iOS application written in Objective-C between August 2011 and May 2013 — the original kind of holiday side project, picked up between work weeks and put back down again. The second version is a browser build written in Phaser 3 and React in 2020, scaffolded on an upstream template and finished across a quiet month. The two are not ports of each other: the second version was a fresh build, written to learn the modern web stack the way the first was written to learn iOS. The shape of the rules is the same; the architecture underneath is whatever the language wanted. The web build lives at deodoro.net/solitaire and is the playable one today; the iOS sources are archived in this repo.
The cards are hand-drawn. Every face, every pip, every back-pattern — the entire deck was drawn by hand on paper, scanned in, and converted to bitmap assets before any of the layouts, the splash screens, or the colour picker went in. That decision pre-dated the project: the artwork exists because I drew it, and the project exists because the artwork had a game to live in. The pride I take in this build lives in the artwork first and in the rules second; everything else is scaffolding around the deck.
HOW THE CLASS — OR THE ROOM — USED IT.
"Used" is the wrong verb here. The two Spider builds never had users beyond me; the entire point of both was that I was the audience. The iOS app was a year-end side project I picked up between December 2011 and the spring of 2013 — written on a MacBook, deployed to my own phone, never shipped to the App Store. The web build picked up the same name six years later because I wanted to learn a different stack, not because anyone asked for a Solitaire app. Both versions treat Spider solitaire as a way to make a hard stack of cards and rules tractable in a language I didn't yet know, and both treat the rules as a problem to be reasoned about rather than a feature to be imported.
THE ARC — FIRST PASS, IOS, 2011–2013.
The original is the easiest half to read because the project's real lessons are in the first season. "Checkin inicial" lands in August 2011, an end-of-summer setup of a brand-new iOS project in a language I was still learning. The first month is the model — a Card object, a Pile object (renamed from Slot mid-stream), the two as singletons, then the resize problem: stacks had to expand and compress to fit a screen, and the zoom had to behave when the stack overflowed. That is where the iOS-era bug log starts: orientation changes that animated through the wrong state, animations that froze on game start, end-of-game stats that didn't appear, the splash and options screens missing from one or both orientations. December 30, 2011 is the first commit that closes a holiday season — a single long message listing, in order, every bug that surfaced at year-end and what was done about it. The list is unusually honest: freeze, stats, menus, color picker, config, error dialogs, orientation layout, low-res images, card overlap during zoom. That's the full surface of an iOS card-game UI, written into one commit.
The project stayed off the shelf through 2012. The late-summer 2012 commits land the original hand-drawn artwork into the asset folder (Adicionada arte original) and convert the bitmaps to Retina resolution in the next commit (Tela de histórico, bitmaps acertados para funcionar em Retina). A first attempt at a "peeler" — the page-curl animation — appears in the same window and becomes the colour picker in 2013. The early-2013 work is the one the user-visible UI hangs off: the page-curl library (Adicionada biblioteca para fazer page curl, twice), the iOS 6 rotation fix, the splash rename and the colour-code migration to RGB, then the curl picker, the merge of two branches, and the menu pass — sliding buttons that wrap the curl animation, the page indicator on the menu, the colour definition moving to its final location in May 2013. The commit count for the iOS era is 49. The last commit (Definição das cores (mudança de local)) is housekeeping: a file moved, no logic change, the project put down for the second time.
THE ARC — SECOND PASS, WEB, 2019–2020.
The JavaScript port started in April 2019 as a fork of an upstream Phaser 3 + React + Webpack 4 template (init commit, 8,391 insertions on day one). The first year is dependency hygiene: a steady stream of dependabot-preview bumps keeps the inherited template buildable while I work out what the project is going to be. The game commits start in May 2020 and run for about a month. The first week is the table — cards on the table, sprites on deck, drag and drop, all stacks, all card moves. Then nine "More refactoring" / "Yet more refactoring" commits in three days. Rules land in parallel (most rules in place, promote stack, promotion location corrected, cards flipped), then the do/undo arc from "Do/undo implemented not tested" through "Do/undo working", then save/load, splash and level selection, the visual pass. The mid-project architectural split is Moved from gamerules to scene (rules and scene swap responsibilities), and the tween discipline — Tweens are serialized and Moved tweens to timeline — closes an entire class of mid-animation bugs that the iOS port also had. The ship sequence is the second rule set: Creating a traditional solitaire, Trad solitaire working, Trad rules do and undo, and the final commit Traditional+spider with both rule sets working on one engine.
ROLE.
Solo on both passes. The web build's template origin (Taylor's phaser3-react-template, 97 commits) is upstream, not co-authorship: the template init, the first Jest setup, dependabot merges and security updates are theirs; every game rule, scene, tween, save/load, do/undo and both solitaire variants are mine. The iOS build has no third-party authorship to call out — Objective-C, UIKit, and the page-curl library I picked up are the only ingredients.
WHAT I LEARNED.
The same game written twice in different stacks is mostly the same project. The rules engine, the rule-do/undo machinery, the orientation-and-layout bug class, and the tween-discipline pattern all show up in both. The names of the files change; the structure of the problems doesn't.
The cleanest commit in the web build is
Tweens are serialized. Mid-animation bugs were a whole class of failure before that commit, in both versions; the timeline owns ordering, the scene owns placement. That same rule shows up as the iOS-era pause-on-orientation change: the alternative is to let the view redraw before the animation has finished, and the bugs are the same.Two rule sets on one engine force-multiplies scene testing. Every rule change gets exercised twice, once in Spider, once in Klondike. That choice paid off when the web build shipped: the second rule set was a third of the work because the engine was already correct.
A decade-long side project is mostly about coming back. The web build picked up the same name and the same author and the same orientation-bug class as the iOS build; what changed between them was the language, and that was the whole point.
The lessons that survive across both passes are smaller than the lessons that change: rule-do/undo, the orientation/layout boundary, the tween/scene split. The lessons that change are the language idioms — the way you ask the screen to redraw, the way you package a build.