Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
Scryglass — a browser-based Magic: The Gathering deck simulator and game tool.
GamesTypeScript · CSSGitHub @efischer19OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
A lightweight, serverless virtual playmat for MTG. Protect your physical cards from the wear and tear of shuffling during local play, or connect peer-to-peer for frictionless remote matches without the hassle of webcams.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Scrymat turns your Magic: The Gathering decks into a shared virtual playmat — offline, at the table, or remotely with no account required.
Pre-release hobby project. Single-device play works today. Remote play is
written but does not work on the live site yet. Last checked 2026-09-28.
Scrymat is a free, open-source Progressive Web App (PWA) for MTG
goldfishing, couch play, and casual remote games. It runs
entirely in your browser, works offline after first load, and is designed for
use on a phone lying flat on a game store table.Read the full README ↗Scrymat turns your Magic: The Gathering decks into a shared virtual playmat — offline, at the table, or remotely with no account required.
Pre-release hobby project. Single-device play works today. Remote play is written but does not work on the live site yet. Last checked 2026-09-28.
| Area | Status |
|---|---|
| Deck import/export (Scrymat, Moxfield, Archidekt, MTGO/Arena) and saved decks | Works |
| Single-device play: shuffle, draw, mulligan, scry, tutor, fetch basic land, moving cards between zones | Works; covered by unit and Playwright tests in CI |
| Scryfall card images with IndexedDB cache; offline use after first load | Works |
Live site (scryglass.cards) | Up, but it serves the 2026-08-03 build under the old "Scryglass" name. Deploys have failed since the repo rename. |
| Remote play (WebRTC + signaling worker) | Partial. Client and worker code exist and are tested, but the worker has never been deployed. The live site has no /api/room backend, and /match/:code links return an error. |
| Hidden-information protection (commit-reveal) and shared seeded shuffling | Partial. Implemented in @scrymat/core but not used by the app yet. Remote sync sends plain actions and full GameState snapshots. |
| Local AI opponent over WebSocket | Partial. The app can connect to ws://127.0.0.1:8765; the repo ships only a prompt (agent/SKILL.md), not an agent. |
Scrymat is a free, open-source Progressive Web App (PWA) for MTG goldfishing, couch play, and casual remote games. It runs entirely in your browser, works offline after first load, and is designed for use on a phone lying flat on a game store table.
[!NOTE] The production TLD and some AWS infrastructure may still use the legacy
scryglassidentifier until the final DNS and deploy cutover is complete.
No installation. No account. Just open and play.
scryglass.cards).[!WARNING] Not working on the live site yet: the signaling worker is not deployed. See Project status. The steps below describe the intended flow.
/match/:roomCode invite URL with the guest.GameState
snapshot after reconnects or divergence.Scrymat began as a simple answer to the frustration that shuffling takes too long. I originally built it so I could play Magic with my kids. Previously, I was spending half of our "playtime" physically manipulating our cards. I wanted a way to let the computer handle the mechanics of the library so we could focus on actually playing the game together.
The pivot to Scrymat keeps that original goal, then pushes further into shared remote play:
Scrymat is designed for trusted casual play, not for adversarial tournament enforcement:
GameState so both sides converge
quickly.All significant decisions are documented as Architecture Decision Records:
| ADR | Title |
|---|---|
| ADR-001 | Use Architecture Decision Records (ADRs) to Document Decisions |
| ADR-002 | Preact + Vite for the PWA |
| ADR-003 | Scryfall API integration & compliance |
| ADR-004 | Fisher-Yates shuffle with Web Crypto API |
| ADR-005 | Action/Reducer state management — agent-ready game engine |
| ADR-006 | Semicolon-delimited deck import format |
| ADR-007 | Monorepo structure (core/PWA separation) |
| ADR-008 | TypeScript & Zod for strict typing |
| ADR-009 | Client-side routing strategy |
Scrymat is built as a monorepo with strict separation of concerns:
| Package | Purpose | Browser Dependencies |
|---|---|---|
@scrymat/core | Pure game logic: deck parsing, shared shuffling, zone-based state management, mulligan/setup flows, and card movement | ❌ None — runs in Node.js and browsers |
@scrymat/pwa | Preact + Vite frontend: UI rendering, Scryfall API integration, IndexedDB caching, Service Worker, and WebRTC match sync | ✅ Browser APIs required |
The @scrymat/core module uses a strict JSON-in/JSON-out action-reducer pattern with Zod schema validation, making it suitable for consumption by AI agents, CLI tools, or any TypeScript/JavaScript consumer.
repository-root/
├── packages/
│ ├── core/ # @scrymat/core — game logic library
│ │ ├── src/
│ │ ├── package.json
│ │ └── tsconfig.json
│ └── pwa/ # @scrymat/pwa — Preact + Vite frontend
│ ├── src/
│ ├── package.json
│ └── tsconfig.json
├── meta/ # Development philosophy, ADRs, and plans
│ ├── adr/ # Architecture Decision Records
│ └── plans/ # Implementation plans and roadmaps
├── docs-src/ # Documentation source files (MkDocs)
├── scripts/ # Utility and automation scripts
├── .github/ # GitHub-specific configuration
└── package.json # Root workspace configuration
The repository includes a GitHub Actions workflow (.github/workflows/deploy-aws.yml) that builds the PWA and deploys it to AWS S3, fronted by CloudFront.
Required AWS resources:
Required GitHub repository variables (Settings → Secrets and variables → Actions → Variables):
| Variable | Description |
|---|---|
AWS_ROLE_ARN | ARN of the IAM deploy role |
AWS_REGION | AWS region of the S3 bucket |
S3_BUCKET_NAME | Name of the S3 bucket |
CLOUDFRONT_DISTRIBUTION_ID | CloudFront distribution ID |
CLOUDFRONT_DOMAIN | (optional) Domain for post-deploy smoke test |
The workflow runs automatically on push to main and can be triggered manually via workflow_dispatch. See docs-src/deployment.md for the full step-by-step setup guide, including the IAM policy JSON and CloudFront configuration.
[!IMPORTANT] Final Scrymat cutover still requires manual infrastructure follow-up: rename or redeploy the AWS bucket / CloudFront resources as desired, update GitHub Actions variables if those names change, rotate any environment-specific tokens tied to the legacy identifier, and repoint the public TLD when the new deployment is ready.
Contributions are welcome! Please read CONTRIBUTING.md for guidelines. Note that this is primarily a hobby project for my own benefit - if there's something you'd like to see improved please LMK, but also know that maintaining Scrymat isn't my day job.
Card images and data are provided by Scryfall. Scrymat respects Scryfall's API guidelines by rate-limiting requests, caching aggressively, and including a descriptive User-Agent header. See our ROBOT_ETHICS.md policy.
This project is licensed under a GPL License.
Scrymat is unofficial Fan Content permitted under the Fan Content Policy. Not approved/endorsed by Wizards. Portions of the materials used are property of Wizards of the Coast. ©Wizards of the Coast LLC.
| Local storage strategy for decklists |
| ADR-011 | End-to-end testing strategy |
| ADR-012 | Expand state engine to full playmat |
| ADR-013 | Deterministic seeded PRNG for shared shuffling |
| ADR-014 | WebRTC data channels & stateless signaling |
| ADR-015 | URL-based match routing |