Skip to content

Gym House · How it’s built

A workout can change. Earned progress stays.

An editable training log connected to a persistent game world. Separate rules govern correcting a workout, keeping earned progress, and choosing between conflicting saves.

← All work
Role & scope
Independent · iPhone
Built with
Swift · SwiftUI · CloudKit · Swift Testing
Gym House’s Today screen with a training plan and workout log
Today connects the training plan to a longer-lived household. Corrections to the log need to respect both kinds of progress.

Two kinds of history

Gym House pairs a strength-training log with a shared house of characters. Recording a workout advances the household, but someone may later need to correct their sets or change an entry to a rest day.

I separated the editable workout record from the rewards already credited to it. Revisions preserve the record’s identity and earned progress; a larger corrected workout can add the difference. The training history can become more accurate without taking away what the house has already earned.

A customizable bedroom in Gym House
The house holds progress earned through training. Revising a workout should not take that progress away.

When saves disagree

Progress is saved on the device, with backup to the user’s private iCloud account. The sync layer compares content fingerprints with the last shared save to decide whether either side has changed.

When both saves have diverged, the app asks which one to continue. Choosing replaces the other save, with a local recovery copy kept first. That is a deliberate tradeoff: the player reviews the conflict instead of the app attempting to merge interdependent workouts, relationships, and house state.

Check the interrupted paths

The sync tests exercise edits made while a fetch is in flight, failed uploads that must be retried, an Apple account changing during a request, and a conflict choice made stale by another device. These cases check the decisions around a backup, beyond a successful upload.

The implementation rechecks account identity and save revisions around network waits. This keeps the decision tied to the data being replaced. The tests establish specific behavior under those conditions; they are not a measurement of reliability across users’ devices.

What I take from this

Connecting a practical tool to a game means deciding what a correction is allowed to change. Making those rules explicit also makes it clearer when the app can reconcile progress itself and when the person needs to choose.