James To (@jamesto) profile picture
22.239438,114.15189
Joined May 2009
Photo by James To (@jamesto)Photo by James To (@jamesto)Photo by James To (@jamesto)Photo by James To (@jamesto)Photo by James To (@jamesto)Photo by James To (@jamesto)Photo by James To (@jamesto)Photo by James To (@jamesto)Photo by James To (@jamesto)Photo by James To (@jamesto)
Every mythic card in Glassvow reads the same input: the angle you tilt it at. Each one does something different with it. Banked Fire: holds, then flares past 0.3 of a full lean. Silvering: a pale copy lags the other way. Unbowed: the world rotates, the figure stays level. The Known Road: the door's shadow swings. Clean Break: the fracture lights at one angle only. Same atlas format, same shader. One reason per card.
2
41
Hovering the outermost card in my hand pushed it 27 px or more off a phone screen. About 11 px on a pad. The fix is one rule: a lifted card stays wholly on screen, 8 px inside the edge. The 0.28 s glide didn't change. Then a test for the whole class of bug: 3 screen shapes, hand sizes 1 to 10, every seat, hovered and armed. On the old code it fails 183 times. If you've built a hand of cards, which edge case caught you out first?
21
Parents of Years 3–6: writing a word from memory can do more than rereading it. In one study (da Silva et al., 2023), Brazilian fifth graders who wrote words from memory recalled more 4 days later, but only when they were corrected straight away. A reason, not proof.
1
19
Our production deploy machine runs one job: the deploy workflow, from main. A hook checks GITHUB_WORKFLOW_REF before any step runs. If it's missing or names anything else, the job fails. The guard fails closed. When in doubt, nothing deploys.
14
Apple's keyword field is 100 characters. Or 100 bytes. Depends which Apple page you read. The product page guide says characters. The App Store Connect reference says bytes. In UTF-8 a Chinese character is 3 bytes, so a byte limit leaves about 33. Test before you plan for 100.
2
25
'For Kids' in an App Store name isn't a keyword. Apple reserves it. Guideline 2.3.8 keeps "For Kids" and "For Children" in metadata for the Kids Category. If your children's app is listed under Education, both phrases are off-limits. Pick the category before the name.
1
25
Blanket retries hide real faults. Our Go test helper retries a Postgres connect only when the server is busy: a full accept queue (EAGAIN), no free slots (53300) or a timeout. Up to a minute. Anything else, like a refused connect or the wrong cluster, fails at once.
21
Every fresh load of our admin console logged a 404 for /favicon.ico. The obvious fix, an inline data: icon, was blocked by our own CSP (default-src 'self'). So the server now answers /favicon.ico with an empty 204, cached for a day. No icon, no error, CSP untouched.
17
App Review rejected your bug-fix update? Read the top of the message before touching any code. If it says the issues are "eligible to be resolved on your next update", reply and ask them to approve this build. Don't resubmit: that starts a new review. This only works for updates to already-approved apps, and each issue can be deferred once.
1
18
If the fix can't wait, you can request an expedited review, but only after the build is submitted. Put the critical bug details in the Notes field. Apple aims to review at least 50% of submissions in under 24 hours and 90% in under 48.
11
My test build and my store build should differ in exactly one way. The testers' build has developer tools on. Everything else matches the store build: release-optimised, same signing route, same shader bake, so frame timings compare. The tooling won't send it to App Review, production, or any group except our internal testers. A separate check keeps developer tools out of store builds. One switch, guarded at both ends.
1
19
James To retweeted
Is 3am really the cheapest time? We checked a year of half-hourly prices (London region, Nov 2025 to Oct 2026). Nov–Feb: cheapest 4 hours started overnight on 106 of 120 days. Apr–Aug: late morning to midday, 134 of 153. 4pm–7pm: never, in 365 days. is-3am-really-the-cheapest-t…
1
1
23
Glassvow Devlog #7 I moved iOS builds to a clean release machine. The first runs all stopped before uploading anything, and every stop was the right call. What the fresh clone was missing: - art still as Git LFS pointers - no Godot import yet, so no imported assets - one .uid file I'd never committed, which left the tree dirty My own machine had all three by accident. Now the script pulls, imports and checks before it builds.
3
3
78
Spelling Camp v1.1 is here! 🔥 Meet our new friend, Jot! 🤩✨
28
James To retweeted
Last Sunday, electricity averaged 40.25p/kWh. The Sunday before: 3.01p. Same tariff, London region, half-hourly prices. Tue 27 Oct dipped to 1.36p. Then from Wed to Sun, not one half-hour went under 25p. New recap every Monday.
1
8
One mythic card in Glassvow has 14 layers of art. The shader reads 2 textures. Every layer sits in one cropped atlas, 1024x832. The card's existing surface shader samples the face and the atlas, and shifts each layer by its depth as the card tilts. What I avoided: - 15 separate textures - up to 13 extra draws from stacked nodes - extra passes or backbuffer copies - any motion while the card is still What I haven't tested yet is the cost on an iPad 8. That's next.
39
Our freshness check recorded the files a script read, not the files that decided what it read. A new test walked the repo: 48 of 115 files were unrecorded. Now adding one file under ops/ marks all seven golden files stale. The check is only as good as its list of inputs.
14
Our CI now does less, on purpose. Draft PR: lint only. A PR that only changes docs: no tests. Everything else: the full suite. Newsroom now calls one shared workflow instead of keeping its own copy, so those rules live in one place.
16
Spelling Camp asks children to spell tricky KS2 words from memory, and brings them back for another try. No tapping the answer, no autocomplete. Parents of Years 3–6: over the next few weeks I'll explain why it works this way, and which parts are simply our choice.
19