A fun, fast merge-puzzle game (2048-style: slide, match, grow blooms) with a cosmetic skin shop and real microtransactions via Stripe Checkout.
Live app: this val's HTTP endpoint (see the val's page on val.town for the
exact URL — click the file index.tsx to see it, or check "Endpoints").
- Game: 4x4 sliding merge grid. Arrow keys or swipe. Matching blooms merge and grow through stages (seed → sprout → ... → legendary bloom). Combos (multiple merges in one move) give a score multiplier.
- Soft currency (🌷 Petals): earned automatically at the end of every game
(
floor(score / 50)). Spend them on a few of the skins. - Hard currency (💎 Gems): bought with real money via Stripe Checkout, in three packs. Spend them on premium skins.
- Skins are 100% cosmetic — board/tile color themes only. No skin changes scoring or gameplay, so nobody is paying to win.
- Players are tracked by an anonymous cookie (
pid), no login required. State (petals, gems, best score, unlocked/active skin) lives instd/sqlite.
The shop UI and free (petal-based) skins work out of the box. Gem purchases are disabled until a Stripe test (or live) secret key is set:
👉 Add STRIPE_TEST_API_KEY here: https://www.val.town/x/dusty_medic/hono-jsx-starter/environment-variables?key=STRIPE_TEST_API_KEY
Once that's set, the "Buy Gems" section appears in the shop automatically
(shopEnabled flips to true) and /api/checkout creates real Stripe
Checkout sessions.
Fulfillment (crediting gems after a successful payment) happens two ways, either is enough on its own:
/confirmationredirect — Stripe sends the shopper back here after checkout; the val verifies the session server-side and credits gems once (idempotent onstripe_session_id). This works with zero extra setup.- Webhook (optional, more robust against a shopper closing the tab
before the redirect) — point a Stripe webhook at
/api/stripe-webhookfor thecheckout.session.completedevent and set:
👉 Add STRIPE_WEBHOOK_SECRET here: https://www.val.town/x/dusty_medic/hono-jsx-starter/environment-variables?key=STRIPE_WEBHOOK_SECRET
Swap STRIPE_TEST_API_KEY for a live secret key when ready to charge real
cards — no code changes needed.
index.tsx Hono app: game page, player/session API, shop, Stripe checkout + webhook
public/
favicon.svg Static asset
game.css All styling (skin themes are CSS custom properties)
game.js Client-side game logic (vanilla JS, no build step)
players— id (cookie-based), petals, gems, best_score, games_played, unlocked_skins (JSON array), active_skinpurchases— one row per Stripe Checkout session, used to fulfill gems exactly once per payment
- Daily challenge / streaks
- Leaderboard (would need a display name, currently fully anonymous)
- Push notifications for "come back and play"
- Real accounts so progress isn't tied to one browser's cookie