← All posts

The sky stops pretending, and the compass stops spinning

The living sky had exactly two pictures and picked one with an if statement. Now it's a continuous function of where the sun actually is, wherever you are.

The living sky shipped back on July 15th and I loved it for about two weeks. Then I noticed I'd stopped noticing it. The reason turned out to be structural, not aesthetic: it had exactly two gradients and picked between them with an if. Four phases — dawn, day, dusk, night — had already collapsed down to two. The sun was nailed to one fixed point on screen. The moon to another. Six garden plants used the same hard-coded seed every single launch, so the same six plants stood in the same six pixels forever. It wasn't a living sky. It was a photograph with a schedule.

Derive it, don't choose it

The fix was a small real ephemeris — where the sun and moon actually are, for a given moment and place — feeding a continuous ramp of eight sampled sky states between deep night and high noon. Nothing switches anymore. Everything slides: the gradient, the horizon glow, how bright the stars look, even whether text drawn over the sky should render light or dark. The moon shows its real phase in its real position, so a crescent hangs near the sun and a full moon rides high at midnight, because that's actually where a full moon is at midnight.

The garden got the same treatment. A plant is now f(seed, plantedAt, now) and nothing else — no growth stage stored anywhere. It's born on a schedule derived from its seed, grows on the daylight that's actually fallen since it was planted, ages, and gets replaced. That's what makes "survives an app update" true by construction instead of by careful migration: there's no counter to lose, nothing that can drift between the phone and the Mac, because there's nothing stored to drift.

Weather, without asking for your location

Weather now comes from Open-Meteo, fetched and cached server-side — no API key on the client, no Apple Weather entitlement, and critically, no location permission. The client just sends its time zone, which every timestamp it already renders implies anyway, and coordinates get rounded to a tenth of a degree on both ends. That one decision is what finally let the rain, snow, fog, and overcast rendering layers run for the first time — they'd been written a while ago and had never once executed on a real device.

The compass stops moving

Separately, and for a completely different reason: the home screen's compass — a gyroscope- driven needle that ran CoreMotion at 30Hz with a constant idle float animation — is now static. That single change took the home screen from roughly 7% to roughly 0.4% median CPU. My own report was what confirmed it mattered: "since removing the compass my phone temperature is barely even noticeable." A repeatForever animation doesn't just cost CPU on its own frame — it keeps the whole render pipeline compositing continuously and stops ProMotion from ever dropping to a lower refresh rate when nothing's actually changing. One number hid three separate costs.

The clouds stayed, on purpose. Two attempts to make them cheaper both made them visibly worse — a cloud's drawing extends past its own frame and depends on a blur applied after clipping to hide that fact, and every cheaper approach either clipped too early or left grey rectangles behind. Fixing that properly is a shape change, not a performance pass, so it's staying exactly as expensive as it is until it gets done right.

← Newer: One machine, and the app under a stopwatch Older: The bug that taught us to trust the wire →