<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Sunstone Apps Blog</title>
    <link>https://sunstoneapps.com/blog/</link>
    <description>Field notes from Sunstone Apps about mobile games, app publishing, Google Play, and calm product engineering.</description>
    <language>en-US</language>
    <atom:link href="https://sunstoneapps.com/rss.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>When astro check says a dependency is missing but the real bug is a pnpm override</title>
      <link>https://sunstoneapps.com/blog/astro-check-vscode-languageserver-protocol-override/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/astro-check-vscode-languageserver-protocol-override/</guid>
      <pubDate>Mon, 20 Jul 2026 01:00:00 GMT</pubDate>
      <category>Astro and pnpm</category>
      <description>How a global vscode-languageserver-protocol override broke @astrojs/check with ERR_PACKAGE_PATH_NOT_EXPORTED, and why removing the override fixed typechecking across Astro sites.</description>
    </item>
    <item>
      <title>What changed when our institutional site started using analytics</title>
      <link>https://sunstoneapps.com/blog/institutional-site-privacy-analytics-chrome/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/institutional-site-privacy-analytics-chrome/</guid>
      <pubDate>Mon, 20 Jul 2026 00:00:00 GMT</pubDate>
      <category>Studio operations</category>
      <description>A practical note on adding GA4 and Cloudflare Web Analytics to a small studio site without turning legal pages, sitemap rules, and header/footer links into copy-paste drift.</description>
    </item>
    <item>
      <title>Choosing mobile layout targets from production logs instead of device guesses</title>
      <link>https://sunstoneapps.com/blog/production-logs-mobile-aspect-ratio-react-native-layout/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/production-logs-mobile-aspect-ratio-react-native-layout/</guid>
      <pubDate>Thu, 16 Jul 2026 02:00:00 GMT</pubDate>
      <category>Engineering process</category>
      <description>How we used Loki user-agent logs, iPhone model usage data, and mobile screen-resolution stats to choose practical aspect-ratio targets for a React Native game layout.</description>
    </item>
    <item>
      <title>How we reorganized app documentation before it became unmaintainable</title>
      <link>https://sunstoneapps.com/blog/app-documentation-release-notes-structure/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/app-documentation-release-notes-structure/</guid>
      <pubDate>Thu, 16 Jul 2026 01:00:00 GMT</pubDate>
      <category>Studio process</category>
      <description>A practical structure for app documentation: living plans, dated history, versioned release notes, product references, store copy, and release gates without turning one Markdown file into a junk drawer.</description>
    </item>
    <item>
      <title>Running a heuristic UX critique on my own app — and actually fixing what it found</title>
      <link>https://sunstoneapps.com/blog/ux-heuristic-critique-react-native-mobile-game/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/ux-heuristic-critique-react-native-mobile-game/</guid>
      <pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate>
      <category>UX and product</category>
      <description>A solo developer walks through a Nielsen-based heuristic evaluation of a published React Native game, prioritizes the findings, and measures the score change after fixing them. Practical process for indie devs without a UX team.</description>
    </item>
    <item>
      <title>Rebuilding the Daily Sudoku landing page after the Play Store launch</title>
      <link>https://sunstoneapps.com/blog/app-landing-page-after-launch-play-store/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/app-landing-page-after-launch-play-store/</guid>
      <pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
      <category>Landing pages and conversion</category>
      <description>The app was already published, but the website still talked like a pre-launch teaser. Here is what we changed — with AI assistants and an automated design critique — to turn it into a real conversion surface.</description>
    </item>
    <item>
      <title>Blog dates off by one day: the timezone bug that affects every Astro site</title>
      <link>https://sunstoneapps.com/blog/astro-blog-date-off-by-one-timezone/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/astro-blog-date-off-by-one-timezone/</guid>
      <pubDate>Tue, 14 Jul 2026 00:00:00 GMT</pubDate>
      <category>Astro and Cloudflare Pages</category>
      <description>Every blog post on our Astro site showed the wrong date — one day earlier than the frontmatter value. The root cause was simple, but the complete fix touched frontmatter, formatting, sorting, and the content schema.</description>
    </item>
    <item>
      <title>Version, versionCode, and generated config: three numbers an Android release must align</title>
      <link>https://sunstoneapps.com/blog/expo-android-release-semver-config-generated/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/expo-android-release-semver-config-generated/</guid>
      <pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate>
      <category>Expo Android release</category>
      <description>After nine Play uploads on versionName 0.1.0, lint overwriting production config, and ambiguous build script names, we documented SemVer rules, dev/prd commands, and why lint must not regenerate config.</description>
    </item>
    <item>
      <title>GA4 screen tracking in React Native: why custom events are not enough</title>
      <link>https://sunstoneapps.com/blog/react-native-ga4-screen-view-firebase-debug/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-ga4-screen-view-firebase-debug/</guid>
      <pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native Analytics</category>
      <description>Daily Sudoku had hundreds of Firebase events but zero Pages and screens views. Here is how we added screen_view from React Navigation, user properties, GA4 custom dimensions, and logcat validation when DebugView fails on physical devices.</description>
    </item>
    <item>
      <title>AdMob UMP in React Native: privacy messages are not just console setup</title>
      <link>https://sunstoneapps.com/blog/react-native-admob-ump-privacy-messages/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-admob-ump-privacy-messages/</guid>
      <pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native Ads</category>
      <description>A practical release checklist for AdMob UMP in an Expo/React Native Android app, covering GDPR messages, US state privacy messages, app store linking, and the SDK gate before ads can request.</description>
    </item>
    <item>
      <title>Your React Native confetti renders behind the cards: sibling order, zIndex, and elevation</title>
      <link>https://sunstoneapps.com/blog/react-native-overlay-zindex-elevation-confetti/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-overlay-zindex-elevation-confetti/</guid>
      <pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native</category>
      <description>A win-screen celebration overlay fell behind the result cards and dropped too fast. The cause was React Native&apos;s sibling paint order, not a missing z-index. Here is why zIndex alone is not enough on Android and how we fixed both bugs.</description>
    </item>
    <item>
      <title>When helpful validation becomes a cheat: Sudoku notes that leaked the answer</title>
      <link>https://sunstoneapps.com/blog/sudoku-notes-candidate-filter-exploit/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/sudoku-notes-candidate-filter-exploit/</guid>
      <pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate>
      <category>Game Design</category>
      <description>Our Sudoku blocked pencil marks that conflicted with the row, column, or box. It felt like a safety check. It was actually a free solver that told players which numbers were still possible. Here is the fix and the principle behind it.</description>
    </item>
    <item>
      <title>A hidden TextInput can&apos;t capture a hardware keyboard on React Native&apos;s New Architecture</title>
      <link>https://sunstoneapps.com/blog/react-native-hardware-keyboard-android-new-architecture/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-hardware-keyboard-android-new-architecture/</guid>
      <pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native</category>
      <description>We wanted physical-keyboard input in a React Native game on Android. The classic hidden TextInput trick failed under Fabric because showSoftInputOnFocus is ignored. adb proved it, and a config plugin fixed it for good.</description>
    </item>
    <item>
      <title>The rounded border that pushed every Sudoku digit off-center</title>
      <link>https://sunstoneapps.com/blog/react-native-skia-text-centering-border-clip/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-skia-text-centering-border-clip/</guid>
      <pubDate>Mon, 06 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native Skia</category>
      <description>A border on an overflow-hidden container silently shifted our Skia board and un-centered every digit. Here is how screenshots, not eyeballs, found the real cause in a React Native game.</description>
    </item>
    <item>
      <title>Why __DEV__ is false in release builds, and how we gated dev tools by config instead</title>
      <link>https://sunstoneapps.com/blog/react-native-dev-tools-config-vs-dev-flag/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-dev-tools-config-vs-dev-flag/</guid>
      <pubDate>Sun, 05 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native tooling</category>
      <description>A developer shortcut hidden behind __DEV__ disappeared exactly when we needed it in a release build. Here is why that happens in React Native and how we moved the gate to runtime config.</description>
    </item>
    <item>
      <title>Design tokens as one source of truth: giving a Sudoku app a real art direction</title>
      <link>https://sunstoneapps.com/blog/react-native-design-tokens-sudoku-art-direction/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-design-tokens-sudoku-art-direction/</guid>
      <pubDate>Sat, 04 Jul 2026 00:00:00 GMT</pubDate>
      <category>Design systems</category>
      <description>How we gave a template-looking Sudoku a bold art direction by changing the theme tokens first, sharing them with our website, and staying inside a low-end performance budget.</description>
    </item>
    <item>
      <title>Adding Expo haptics to a React Native game without making vibration a sound setting</title>
      <link>https://sunstoneapps.com/blog/expo-haptics-react-native-game-settings/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/expo-haptics-react-native-game-settings/</guid>
      <pubDate>Fri, 03 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native Haptics</category>
      <description>How Daily Sudoku added a persisted vibration toggle, reused gameplay feedback events, and kept Web bundling safe while using expo-haptics on native.</description>
    </item>
    <item>
      <title>Playing the same WAV files in Expo Web and a React Native app</title>
      <link>https://sunstoneapps.com/blog/expo-react-native-web-audio-wav-assets/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/expo-react-native-web-audio-wav-assets/</guid>
      <pubDate>Thu, 02 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native Web</category>
      <description>How we reduced the gap between Web and app in an Expo/React Native game by replacing synthetic tones with bundled WAV assets and configurable audio logs.</description>
    </item>
    <item>
      <title>How to keep Playwright E2E useful when React Native Skia renders a canvas</title>
      <link>https://sunstoneapps.com/blog/react-native-skia-e2e-github-actions-pnpm/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-skia-e2e-github-actions-pnpm/</guid>
      <pubDate>Wed, 01 Jul 2026 00:00:00 GMT</pubDate>
      <category>React Native Testing</category>
      <description>A field note on testing a React Native Skia canvas board with Playwright, replacing DOM-only selectors with a narrow test bridge, and keeping persistence deterministic.</description>
    </item>
    <item>
      <title>Google indexing checklist for Astro sites on Cloudflare Pages</title>
      <link>https://sunstoneapps.com/blog/google-indexing-astro-cloudflare-pages/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/google-indexing-astro-cloudflare-pages/</guid>
      <pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate>
      <category>Technical SEO</category>
      <description>A field checklist for proving that Astro sites on Cloudflare Pages are crawlable, submitted in Search Console, and actually indexed by Google.</description>
    </item>
    <item>
      <title>Disabling Android touch sounds in React Native without fighting Switch</title>
      <link>https://sunstoneapps.com/blog/react-native-android-touch-sound-toggle/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-android-touch-sound-toggle/</guid>
      <pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate>
      <category>React Native Android</category>
      <description>How one React Native sound setting ended up owning gameplay effects, Android tap feedback, and a double-toggle bug in a nested Switch.</description>
    </item>
    <item>
      <title>Measuring perceived latency in React Native when frame metrics are not enough</title>
      <link>https://sunstoneapps.com/blog/react-native-perceived-latency-probe/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-perceived-latency-probe/</guid>
      <pubDate>Sun, 28 Jun 2026 00:00:00 GMT</pubDate>
      <category>React Native performance</category>
      <description>How we measured React Native response time from tap handler to state update and paint when frame stats did not explain what players felt.</description>
    </item>
    <item>
      <title>Moving a React Native Sudoku board to Skia without deleting the old renderer</title>
      <link>https://sunstoneapps.com/blog/react-native-sudoku-skia-renderer/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-sudoku-skia-renderer/</guid>
      <pubDate>Sat, 27 Jun 2026 00:00:00 GMT</pubDate>
      <category>React Native performance</category>
      <description>How we tested a Skia Sudoku board behind config without deleting the React Native renderer, accessibility layer, or rollback path.</description>
    </item>
    <item>
      <title>When an Expo upgrade turns your splash screen into a white screen</title>
      <link>https://sunstoneapps.com/blog/expo-splash-screen-sdk-upgrade/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/expo-splash-screen-sdk-upgrade/</guid>
      <pubDate>Fri, 26 Jun 2026 00:00:00 GMT</pubDate>
      <category>Expo Native Builds</category>
      <description>A practical field note on fixing a missing native splash after an Expo SDK upgrade by moving from the legacy splash block to the expo-splash-screen plugin.</description>
    </item>
    <item>
      <title>How to validate a Google Play test purchase with RevenueCat</title>
      <link>https://sunstoneapps.com/blog/validar-compra-teste-google-play-revenuecat/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/validar-compra-teste-google-play-revenuecat/</guid>
      <pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate>
      <category>Android monetization</category>
      <description>A field checklist for tying one Google Play test purchase to RevenueCat credentials, the Play Console order, sandbox data, SDK identity, and Sentry.</description>
    </item>
    <item>
      <title>An honest checklist before expanding an Android internal test</title>
      <link>https://sunstoneapps.com/blog/checklist-teste-interno-android-google-play/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/checklist-teste-interno-android-google-play/</guid>
      <pubDate>Wed, 24 Jun 2026 00:00:00 GMT</pubDate>
      <category>Quality before beta</category>
      <description>How to separate what a Google Play build has proven from SDK, billing, ads, and observability gaps before inviting more testers.</description>
    </item>
    <item>
      <title>Publishing an Expo/React Native app to Google Play with a local AAB</title>
      <link>https://sunstoneapps.com/blog/expo-react-native-google-play-aab-local/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/expo-react-native-google-play-aab-local/</guid>
      <pubDate>Tue, 23 Jun 2026 00:00:00 GMT</pubDate>
      <category>React Native on Google Play</category>
      <description>How to build a local Expo/React Native AAB for Google Play and still validate signing, Firebase, Sentry, AdMob, RevenueCat, and Play delivery like a real release.</description>
    </item>
    <item>
      <title>When versionCode changes but JavaScript does not: a React Native release trap</title>
      <link>https://sunstoneapps.com/blog/react-native-versioncode-bundle-js-cacheado/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/react-native-versioncode-bundle-js-cacheado/</guid>
      <pubDate>Mon, 22 Jun 2026 00:00:00 GMT</pubDate>
      <category>React Native release debugging</category>
      <description>A release bug where Google Play installed a new Android versionCode while the React Native JavaScript bundle still reported the old Sentry release.</description>
    </item>
    <item>
      <title>When does RevenueCat make sense instead of direct Google Play Billing?</title>
      <link>https://sunstoneapps.com/blog/revenuecat-vs-google-play-billing-app-indie/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/revenuecat-vs-google-play-billing-app-indie/</guid>
      <pubDate>Sun, 21 Jun 2026 00:00:00 GMT</pubDate>
      <category>Mobile monetization</category>
      <description>A margin and operations breakdown for deciding whether an indie app should pay RevenueCat or own Google Play Billing support itself.</description>
    </item>
    <item>
      <title>How to prepare a Google Play Console account for publishing an Android app in Brazil</title>
      <link>https://sunstoneapps.com/blog/google-play-console-app-android-brasil/</link>
      <guid isPermaLink="true">https://sunstoneapps.com/blog/google-play-console-app-android-brasil/</guid>
      <pubDate>Sat, 20 Jun 2026 00:00:00 GMT</pubDate>
      <category>Google Play in Brazil</category>
      <description>A practical order for getting developer identity, payments, public profile, account groups, signing keys, and legal pages ready before a first Google Play upload.</description>
    </item>
  </channel>
</rss>
