Florian Schroedl 434af6599b chore(art): refresh enemy sprites and surge card art
Add master renders for the canal, gatling, scrapper and surveillance enemies and repack their optimized assets alongside a re-optimized surge card.
2026-09-04 08:25:09 +02:00

DeckBuilder

A minimal portrait 2D deck builder boilerplate for Godot 4.6, configured for iOS release (and web-canvas prototyping — both use the GL Compatibility renderer).

What's in the box

A playable one-enemy combat loop:

  • Draw 5 cards each turn, 3 energy.
  • Strike (attack), Defend (skill/block), Bash (heavy attack).
  • Tap/click a card to play it; "End Turn" lets the enemy hit you.
  • Auto-reshuffle the discard pile, win/lose detection.

Project layout

project.godot          Portrait config + GameState autoload + GL Compatibility renderer
icon.svg
scenes/
  main.tscn            Combat screen layout (HUD, hand, end-turn button)
  card.tscn            Reusable card widget (cost / name / description)
scripts/
  game_state.gd        Autoload singleton — ALL game logic, signal-driven (no UI in here)
  card_data.gd         CardData resource — the data shape of a card
  card_database.gd     Builds the starting deck in code
  card.gd              Card widget behaviour (emits `played` on tap)
  main.gd              Wires HUD + dynamic hand to GameState signals

The architecture keeps logic and presentation separate: game_state.gd is pure state + signals, the UI only reads state and listens for hand_changed / stats_changed / combat_ended. That makes the rules easy to unit-test and the UI easy to replace.

Run it

godot project.godot          # opens the editor
godot                        # runs the main scene directly

The desktop window opens at 540×960 (a half-scale portrait preview); the design resolution is 1080×1920.

Configuration already set for mobile

In project.godot:

  • display/window/handheld/orientation=1portrait locked.
  • window/stretch/mode="canvas_items", aspect="expand" — scales the 1080×1920 design across iPhone aspect ratios.
  • renderer/rendering_method="gl_compatibility" — runs on iOS, Android, and the Web canvas export, so the same project prototypes in a browser and ships to the App Store.

Web (canvas) build — test on iOS over Tailscale

godot --headless --export-release "Web" build/web/index.html   # build the canvas export
bun serve.mjs                                                  # serve build/web on 0.0.0.0:8088

The Web preset has thread support disabled (no SharedArrayBuffer / COEP headers needed). But Godot's web runtime still requires a secure context, so it must be served over HTTPS (plain HTTP fails with "Secure Context ... use HTTPS"). serve.mjs serves HTTPS on :8443 using a self-signed cert.

One-time: trust the dev cert on iOS

The cert lives in certs/ (generate it once — see below). On your iPhone:

  1. Open http://100.64.0.2:8088/cert in Safari → “Allow” the profile download.
  2. Settings → General → VPN & Device Management → install the DeckBuilder Dev profile.
  3. Settings → General → About → Certificate Trust Settings → toggle it on.

Then open the game at https://100.64.0.2:8443/ (or https://desktop.ts.local:8443/ if MagicDNS resolves on the phone). Tap once to start (iOS needs a gesture for audio).

Play offline (add to Home Screen)

The web build is an installable PWA, so it runs even when this Mac/PC (the server) is off. Open the HTTPS URL once while the server is up, let it finish loading, then Share → Add to Home Screen. Launch it from the home-screen icon and it starts offline from cache (portrait, standalone, no Safari chrome). One loaded visit is enough to cache it; rebuilding (bb web) re-caches on the next online launch. See AGENTS.md → Offline (installable PWA) for how it works.

Generate the cert (once)

mkdir -p certs
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout certs/key.pem -out certs/cert.pem -days 824 \
  -subj "/CN=DeckBuilder Dev" \
  -addext "subjectAltName=IP:100.64.0.2,DNS:desktop.ts.local,DNS:desktop" \
  -addext "extendedKeyUsage=serverAuth" \
  -addext "basicConstraints=critical,CA:TRUE"

Replace the IP/DNS with your own Tailscale address. Re-run the export + restart serve.mjs after code changes to refresh the build.

Exporting to iOS

  1. Web prototype loop (no Mac needed): Project → Export → Add → Web, then run the .html locally to iterate fast.
  2. On-device test (free Apple ID, sideload): Project → Export → Add → iOS, set a unique Bundle Identifier (e.g. com.you.deckbuilder), export the Xcode project, open it in Xcode on a Mac, pick your personal team, and Run.
  3. App Store release: paid Apple Developer account ($99/yr), then archive + upload via Xcode / TestFlight for review.

iOS export templates must be installed: Editor → Manage Export Templates.

Extending it

  • New cards: add them in card_database.gd, or create .tres files from the CardData resource and load them from a resources/cards/ folder.
  • New effects: extend the match card.card_type block in game_state.gd::play_card (add a new CardData.Type).
  • More enemies / map / relics: add new autoload state or scenes; keep logic in plain scripts and let scenes subscribe to signals.
S
Description
No description provided
Readme 73 MiB
Languages
GDScript 76.9%
Clojure 18.1%
Shell 2.6%
JavaScript 1.1%
CSS 1.1%
Other 0.2%