At ten in the morning in Tokyo, under 94% cloud cover, I needed my app's paywall to show a clear sunset.Waiting was the obvious option. What I did instead took one command: I moved my iOS Simulator to Albuquerque, where it was 7 p.m. with no clouds at all, waited 22 seconds, and took the screenshot. No mock data, no code change, no image editing.The same trick then carried my App Store screenshots — though the sunset in my final screenshot set came from somewhere much closer to home. This is how it works, where it stops working, and the script that grew out of it.Why I couldn't just fake the skyAmana is an iOS app that draws the sky outside your window — from the time, your location and the current weather — and then tries to get you to go look at the real one. I wrote about why it draws the sky on-device instead of using satellite images earlier in this series.The app does have debug flags that let me set the sun altitude and cloud cover by hand. The problem is honesty. One store screenshot's caption reads "Night, too — real moon phase, real weather." Put a hand-placed moon under that caption and the screenshot is lying. And the paywall's widget preview runs on live weather too: on a cloudy day it renders grey, and a grey preview on a paywall is not a great look.So the sky had to be real. It just didn't have to be my sky.The one commandSIM=xcrun simctl location "$SIM" set 35.0844,-106.6504 # Albuquerquexcrun simctl terminate "$SIM" "$BUNDLE_ID"xcrun simctl launch "$SIM" "$BUNDLE_ID"sleep 22xcrun simctl io "$SIM" screenshot home.pngThe write-ups of simctl location I found use it to test location features: maps, geofences, permission prompts. The part I hadn't seen written down is what happens downstream. The app never asks "where am I?" for its own sake. It asks CoreLocation for coordinates, then hands those coordinates to WeatherKit, to reverse geocoding for the place name, and to its sun-position math. Move the coordinates and every one of those follows: cloud cover, the place-name line, and the one-line "the sky may catch fire soon" hint.I checked it by counting pixels instead of trusting my eyes. In the paywall's widget preview, a grey preview measures only a few percent warm-coloured pixels. After the jump it measured 30–32%.The 22 seconds matter. My first attempt waited 13 seconds and captured the app's default cloud cover (0.40) — the placeholder it shows before the first weather refresh finishes. It looks plausible, which is exactly the problem. Real data arrived later, so the script now waits 22.Three knobs, and only one of them turnsOnce location worked, I assumed the simulator could produce any sky on demand. It can't, and the reason is worth spelling out, because it applies to any app whose UI depends on the world.Every input to a screenshot comes from one of three places:Place (latitude, longitude): sun altitude, weather, place name, the hint. Movable with simctl location.Calendar (the date): moon phase, and the season used for naming skies. Not movable.Clock (the device's actual time): the time-of-day band used for naming. Not movable.Place is free because the Earth is round: at any moment, 24 time zones exist at once, and one of them is having a clear dusk. There is only one calendar and one clock.You can see it in the code. The moon phase has no latitude or longitude in it at all:static func currentMoonPhase(date: Date = Date()) -> Double { let synodic = 29.530588853 // days in a lunar cycle let refNewMoon = 947_182_440.0 // a new moon: 2000-01-06 18:14 UTC let days = (date.timeIntervalSince1970 - refNewMoon) / 86400.0 let phase = (days / synodic).truncatingRemainder(dividingBy: 1.0) return phase < 0 ? phase + 1.0 : phase}Fly anywhere you like; the moon stays the same shape. And when you name a photo, the naming engine reads the hour from the device:static func timeBand(forHour hour: Int) -> TimeBand { let h = ((hour % 24) + 24) % 24 switch h { case 4..