The eras
Each entry below is one step of the work, grouped into eras. The last era is what comes next.
One platform for every game
Each game had grown its own sign-in, saves, feedback and translations. In one week they became shared services: one account across every game, per-game saves, achievements, leaderboards, player reports and a translation review site, with a typed client for the browser games and one for the native games, all storing their data in the EU.
Hearing from players, talking back
Opt-in release news on phones, a careful console to send it with, and crash reports that arrive without an account and are grouped by cause, so the same bug in the next build lands on the same line.
The admin portal
One private page for everything we run: who plays and who comes back, how far players get in each game, every tool one click away, and the one page that writes: game settings, small switches every game reads at runtime.
Fair cosmetics
Every game is fully free to play, and the store was built so it stays that way: it only knows looks, checks every purchase with the phone's own store, keeps test and real purchases apart, and shows supporter and season badges on the boards.
Friends, neighbours and news
Second Spring joined the platform and brought the first social features: friend codes, visits to a friend's valley, postcards and kindnesses, neighbours behind a switch, friends on the weekly boards, and a sign-up for release news by e-mail.
Phones and new games
A shared add-on that helps the native games work with an Android phone instead of against it, and a new game registered on every service from its first day.
What we are working on
Sending the release news itself, and more games moving onto the shared services they don't use yet.
One platform for every game
Each game had grown its own sign-in, saves, feedback and translations. In one week they became shared services: one account across every game, per-game saves, achievements, leaderboards, player reports and a translation review site, with a typed client for the browser games and one for the native games, all storing their data in the EU.
- 1 14 Oct
One account for every game
doneHarrowfall and Hush Money each had their own account service, and they had already drifted apart from the same starting code. We merged them into one shared platform. A player signs in with a code sent by e-mail, no password, and the same account works in every game. Each game keeps its own save on the account: the server stores it as it is and never merges it. When two devices save at once, the second one gets the newer copy back and the game merges it by its own rules, so a save is never silently lost.
Single sign-on came the same day: sign in once on one of our sites and the others know you, and signing out can end every session at once.
8c22e24, b7cde36, 7e000fb, 7f79a48 - 2 14 Oct
Achievements and leaderboards for every game
doneAchievements became a service of their own. Each game describes its achievements in a file that its build pushes on every deploy, with up to three tiers per achievement, and the universe site shows them per game with how rare each one is.
Hush Money's run ladder moved over as it was, with the server recomputing every score from the run instead of trusting the client. Every other game got generic score boards: daily or weekly boards, a shared seed so everyone plays the same puzzle, your own rank, and limits on how often a score may be sent.
a41625f, 853c6d5, 7013bc3, 5881550, b549c49 - 3 14 Oct
Player reports and translations, per game
donePlayers can send a report from inside a game, with a category, an optional save and up to three screenshots. Our triage site turns a report into an issue in the right game's repository with one click, and the save can be opened through a one-time link.
The translation review site, built for Harrowfall, now holds a separate catalogue for every game. A game's build sends its English text and pulls in the reviewed translations at build time, so a fixed translation reaches the game with the next build.
0f20f4d, 6b3427f, 50eca8b, 72f10c8 - 4 15 Oct
Clients for the browser games and the native games
doneThe browser games get a typed client with no dependencies of its own: sign-in, saves with the merge on a conflict, achievements, boards and reports. The native games get the same in their own scripting language, copied into each game: sign-in, an encrypted token on the device, save sync, and an offline queue, so an achievement or a score earned offline is sent the next time the game is online.
837b0a5, f33bfc0, 2c0da59 - 5 15 Oct
Deleting an account deletes everything
doneDeleting an account now reaches every service: saves, achievements, scores and reports go together. If one service can't be reached, nothing is deleted and the player is told to try again, so an account is never left half deleted. Players can delete their account from inside a game and on the universe site, and ask for everything we hold about them as one file.
Every game links to one shared privacy policy, and any change to what a service stores updates that policy in the same change.
5de9136, 8bc25c2, a134987 - 6 16 Oct
Private web builds for testing
doneThe native games can also run in a browser. Their builds are uploaded by each game's own build pipeline to private web demos, stored in the EU and only open to signed-in testers, with a smoke test that catches a page that freezes on start. What we learned there (shader warm-up, frame rate, freezes) is written down once for every game.
c4ce424, cbe24a2, 2c08452, fe56419 - 7 20 Oct
A home of its own
doneThe universe site moved to its own repository, and every service moved to hollowcut.com. Nothing was public yet, so the old names were simply switched off, with no redirects left behind to maintain.
4c938dc, 9b2d8f3
Hearing from players, talking back
Opt-in release news on phones, a careful console to send it with, and crash reports that arrive without an account and are grouped by cause, so the same bug in the next build lands on the same line.
- 8 18 Oct
Release news on phones, opt-in only
doneA game can now ask the player whether they want news on their phone, such as a new season or a new world. Only phones that said yes are stored, by their push address, language and topic, with no link to an account. A notice can open the game on a chosen screen, like the shop or the map, and comes in all seven of the games' languages.
7f7f17b, 765e8f8, 0c27911 - 9 23 Oct
A push console that is hard to misuse
doneSending news to every player is easy to get wrong, so the console is strict. You pick the game, the languages, the platforms and how recently the phones were active, and see how many phones that reaches. The page previews the notice on a lock screen and as a folded notice, per language, and warns about long titles, capitals, links and languages that will get English.
Then the rules: the exact text must have reached one of your own test phones first, you type the game's name to confirm, a large audience needs an extra tick, the send is refused if the audience grew since you confirmed it, and a game gets at most one broadcast a day and three a week. An AI can draft the other languages from the English text; each draft is marked until someone has read it, and nothing about players is sent to it.
afdfc06, 0354681, 7e23187The push console with test data: audience, notice and AI-drafted German, with the previews and checks. From the repo · 23 Oct - 10 23 Oct
Crash reports, anonymous and grouped
doneEvery game can send its crashes to the platform, before anyone has signed in. A report never names a player: no account, no stored IP address, and the server strips e-mail addresses, tokens, user names in file paths and the query part of every link before saving.
Reports are grouped by a fingerprint built from the error and its first stack frames, with build numbers, file hashes and line numbers taken out, so the same bug in the next build still lands in the same group. A group can be resolved; a crash after that reopens it as a regression. One click files an issue in the game's repository with the counts, builds and the newest stack.
6eaa33b, 26266d6The crash viewer with test reports from four games. From the repo · 23 Oct
The admin portal
One private page for everything we run: who plays and who comes back, how far players get in each game, every tool one click away, and the one page that writes: game settings, small switches every game reads at runtime.
- 11 23 Oct
One private page for everything we run
doneThe admin portal sits behind a sign-in gate that only lets the team in, and it checks that gate itself on every request. It reads the other services' databases and never writes to them. Because no service kept a history of who played on which day, an hourly job collects one row per day, game and player, and that history is pruned after 400 days and when an account is deleted.
It shows who plays and who comes back the next day, week and month, retention per sign-up week, how many games each player plays, and per game a funnel from first save to first achievement and how far players get. The team's own accounts are left out of every number.
fcf69e4, 7c3da0a, e5ff9f7The admin portal's front page, with demo data for 400 made-up players. From the repo · 23 Oct Players and retention, demo data. From the repo · 23 Oct One game's page: players per day, how far players get, achievement completion. Demo data. From the repo · 23 Oct - 12 23 Oct
Game settings: switches every game reads
doneA small remote config. Per game, the team sets toggles, numbers and text in the admin portal, and the game reads them at start, cached for a minute. A game can declare the keys it reads, with a default and a description, so they show up ready to switch. Every save is a version with a history of what changed.
The answer is public, so the server refuses anything that looks like a secret. And the free-to-play rule holds here too: a setting may switch on an event, a banner or a look, never sell or gate gameplay.
cbf8b64, 443b34aGame settings for Chime Walk, with the public answer the game gets and the history of saves. Test values. From the repo · 23 Oct
Fair cosmetics
Every game is fully free to play, and the store was built so it stays that way: it only knows looks, checks every purchase with the phone's own store, keeps test and real purchases apart, and shows supporter and season badges on the boards.
- 13 22 Oct
A store that only sells looks
doneEvery game is fully free to play: every level, mode, unit and feature. The store was built to keep it that way. It only accepts products marked as having no gameplay benefit, it stores no prices (the phone's own store shows the local price), and a game uses what a player owns for looks only, never to unlock play.
Every purchase is checked on the server with the phone's store before anything is granted, and restore works from the store's own records, not from a save a player could edit. Development, acceptance and production each have their own database, so a test purchase can never turn into a real one.
fe6dba3, 252d0f7, fce3e23 - 14 24 Oct
Seasons, supporter badges and opt-in thanks
doneA season calendar shared by every game, season and supporter badges shown next to a player's name on every board, and an opt-in list of supporters' names for a game's thank-you screen. Badge boards let a game's score tiers show on all of its boards. Store notifications only hint that a purchase should be checked again; the server always re-verifies.
d0b6664, 35993cc, 67ba006, cbd3da3
Phones and new games
A shared add-on that helps the native games work with an Android phone instead of against it, and a new game registered on every service from its first day.
- 19 6 Nov
Working with the phone, not against it
doneA shared add-on for the native games on Android. It tells the phone the frame time the game is aiming for and how long each frame really took, so the processor runs as fast as the frame rate needs and no faster: smoother when busy, cooler when not. It passes on the player's choice of performance or battery mode, and warns the game when the phone is getting warm, so the game can go lighter before the phone slows itself down. On every other platform it does nothing.
5cc7ce5 - 20 6 Nov
A new game on every service from day one
doneA new game in early development was registered on every platform service at once (accounts, achievements, boards, store, reports, translations, settings and push) instead of one at a time as it needs them. Adding a game is now a short checklist.
9bd89b8, 443b34a
What we are working on
Sending the release news itself, and more games moving onto the shared services they don't use yet.
- N1 Later
Sending the release news
plannedThe sign-ups are in place; the page that writes one mail per game and language, previews it and sends it in batches to confirmed addresses is next.
The images are screenshots of the platform’s private pages, made with test or demo data. E-mail addresses and private addresses are left out.
Friends, neighbours and news
Second Spring joined the platform and brought the first social features: friend codes, visits to a friend's valley, postcards and kindnesses, neighbours behind a switch, friends on the weekly boards, and a sign-up for release news by e-mail.
Second Spring joins, and the sign-in mail names the game
doneSecond Spring was registered on the platform for sign-in, saves, reports, crashes and its own translation catalogue. The sign-in mail now carries the name of the game that asked for it, instead of always Harrowfall's.
901db3f, 8a314a7, ff44563, 1962064Friend codes, visits, postcards and kindnesses
doneSecond Spring had no social features at all, so the platform got its first. A player picks a name and gets a friend code; there is no search and no list of strangers, and codes can't be guessed because only a few may be tried a day. Friends can visit each other's valleys read-only, send a postcard with a photo, or leave a kindness on a visit. Mail carries ids and numbers only, never free text, so nothing between players needs moderating.
Neighbours came next, behind a game setting that starts off: a valley can opt in to sit among up to six others, friends first, then players at a similar pace. Strangers never see a name.
22bcc06, 5e55009Release news by e-mail, double opt-in
doneA game's own site can ask visitors for an e-mail address to hear when the game is out. It runs on our own platform, not a mailing service: we store the address, the language and when it was confirmed, nothing else, with no tracking pixels or click tracking. Only addresses that clicked the confirmation link will ever get news, and the form never reveals whether an address was already on the list. Unsubscribing deletes the row at once. Second Spring's site is the first to use it.
cd3010bFriends on the weekly boards
doneA board can now be read for just your friends, so Second Spring's weekly boards can show how you did against the people you know.
0c0e230