A dev build now installs under its own applicationId, org.prolibertate.games.dev,
so it is a separate app to Android and sits beside the production copy instead
of replacing it. Each channel still updates itself normally, because an update
within a channel keeps the same package.
Three things move together off one isDevBuild flag, because a dev package
wearing the production name and colours is exactly the mix-up that having both
installed is meant to prevent:
- applicationId gets a .dev suffix;
- the launcher label becomes "Pro Libertate Games DEV";
- the cloth becomes Wallace Hunting, the same threadcount with green where
the clan sett has red.
The name and the colours reach the resources through resValue, so app_name,
tartan_field, splash_background and ic_launcher_background are generated by the
build rather than declared in res/values. The icon vectors reference
@color/tartan_field instead of a literal, which is how one set of vectors serves
both colourways without a second copy of the paths. BuildConfig.DEV_BUILD
carries the same flag into Kotlin, where AppSett picks the Compose sett for the
splash, and WallaceHuntingSett is derived from the same threadcount builder as
WallaceSett so the two cannot drift.
versionName now tracks isDevBuild rather than the CI stamp alone, so an
unstamped local build cannot claim a channel its applicationId contradicts.
Separate packages also mean a channel switch can no longer be refused as a
downgrade; the settings copy and the README said it could, and now say what
actually happens.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JDuAayWXLRoUNTsfE79Mg1
- The launcher icon is a single square of the tartan, drawn as a vector
so it stays sharp at any density and ships no PNGs. The adaptive
icon's foreground is deliberately empty: the cloth is the icon.
- Tartan.kt draws the sett as warp, then as weft at half opacity. That
overlap is what gives the blended squares and reads as woven cloth
rather than a printed grid, and it is reused by both the icon and the
splash.
- The app opens on the tartan under "Pro Libertate Games" in Uncial
Antiqua, holds two seconds, then fades. It is an overlay rather than a
destination, so the menu is already composed behind it and the fade
reveals a live screen. The window background is set to a dark red so
launch does not flash white before Compose draws.
Two things to be aware of:
- WallaceSett is an approximation. It reads as Wallace — bold red and
black check with a narrow gold overstripe — but the registered
threadcount could not be verified here, so the counts were chosen to
look right. They are plain data and can be swapped for the registered
ones without touching anything else.
- Uncial Antiqua is bundled under the SIL Open Font License 1.1, with
the full licence at docs/licenses/UncialAntiqua-OFL.txt. The OFL
requires that to be distributed with the font, so it must not be
separated from it.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
First vertical slice: the whole shell plus two games playable end to end,
so every layer is exercised before the other nine games are built on it.
Games
- Euchre: bowers, ordering up, dealer discard, going alone, stick the
dealer, and full scoring. Rule variants (deck size, points to win,
stick the dealer, going alone) are toggles in game setup.
- Sequence: two-eyed and one-eyed jacks, free corners, locked sequences,
the shared-chip limit, and dead-card exchange. Teams, players per team
and the sequence target are toggles.
- The board layout in SequenceBoard is generated, not the commercial
board — it holds every structural property the rules need, but does not
match a physical board. Documented in docs/RULES-sequence.md.
Multiplayer
- One transport abstraction over newline-delimited JSON, implemented
twice: LAN via NSD discovery and TCP, Bluetooth via Classic RFCOMM.
A lobby advertises on both at once, so a table can mix them.
- Host-authoritative: clients send move intents, the host re-validates
every one against the rules, and each client receives a state redacted
for its own seat so hidden information never crosses the wire.
- Seats start as AI and are handed to people as they join, which is what
makes any mix of humans and AI work without a separate code path.
Shell
- Main menu lists all eleven games; the nine without engines are marked
coming soon and are driven entirely by GameCatalog.
- Settings: sound, animation speed (one multiplier drives card movement
and AI thinking time), and OTA updates from the latest GitHub release.
- Layouts measure available space rather than assuming an orientation.
The game package is free of Android types, so the rules engines and AI
run under plain JUnit; 43 tests cover ranking, following suit, scoring,
sequence detection, redaction, wire round-trips and full random and AI
playthroughs.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN