A standalone Flutter and AWS Blocks application. The Flutter client, Blocks backend, generated API contract, local data, and deployment configuration all live in this directory.
tabletop-flutter/
├── aws-blocks/ # Auth, data, Realtime, Agents, API, and deployment
├── lib/ # Flutter application and generated Dart client
├── .blocks/config.json # Independent stack identity
├── package.json # Backend, codegen, sandbox, and deploy commands
└── pubspec.yaml # Flutter dependencies
- AuthBasic sign-in and registration
- Character creation with all 20 pixel sprites
- Public/private Guild Hall games
- Responsive game table, turn order, actions, chat, dice, and timer
- Realtime state/chat/thinking subscriptions with polling fallback
- Host-only AI companion turn stepping
- Android, iOS, macOS, and web targets
- Flutter 3.41+ and Dart 3.12+
- Node.js 22+ and npm 10+
- Chrome, an emulator, or a supported desktop toolchain for the chosen target
- Optional: Ollama for live local model inference
- Optional: AWS credentials and a bootstrapped CDK environment for deployment
No AWS account or model API key is needed for local development.
Flutter UI
-> ViewModels -> Repository -> generated Blocks RPC client
|
v
aws-blocks/index.ts
-> AuthBasic
-> DistributedTable (characters, games, state, chat)
-> Realtime (state, chat, thinking)
-> Agent (Dungeon Master and four companion personas)
The backend is authoritative. Flutter sends commands and renders returned state; it does not roll dice, advance turns, or generate outcomes locally.
Install dependencies once:
cd tabletop-flutter
npm install
flutter pub getStart this app's Blocks backend:
npm run devThen run Flutter from another terminal in the same directory:
flutter run -d chromeUse -d macos, -d ios, or an Android device as needed. The default API is
http://localhost:3001/aws-blocks/api; Android emulators use 10.0.2.2
automatically. Physical devices need a reachable host URL:
flutter run \
--dart-define=BLOCKS_API_URL=http://YOUR_LAN_IP:3001/aws-blocks/apiThe React backend also defaults to port 3001. Stop it before starting this
app's backend; the two applications do not share services or data.
| Command | Purpose |
|---|---|
npm run dev |
Start this app's local Blocks backend on port 3001 |
npm run typecheck |
Type-check aws-blocks/ |
npm run generate |
Regenerate the OpenRPC spec and formatted Dart bindings |
npm run verify |
Type-check, analyze, test, and build Flutter web |
dart run tool/blocks_chat_smoke.dart |
Test auth, history, and Realtime against a running backend |
npm run sandbox |
Deploy an isolated AWS sandbox |
npm run deploy |
Deploy the backend and Flutter web Hosting |
After changing aws-blocks/index.ts, regenerate the spec and Dart client:
npm run generateNever edit lib/blocks.blocks.dart by hand.
The generation path is:
aws-blocks/index.ts
-> lib/blocks.spec.json
-> lib/blocks.blocks.dart
Commit the backend, spec, and generated Dart file together. API removals and renames are breaking changes for the Flutter client.
npm run verifyFor an end-to-end local Blocks check, keep npm run dev running and execute:
dart run tool/blocks_chat_smoke.dartLocal Blocks data belongs to this application and is stored in .bb-data/.
Deleting that directory resets local users, characters, games, and chat:
npm run cleanup
rm -rf .bb-dataDo not copy .bb-data/ from tabletop-app; the applications have independent
scope IDs and contracts.
The Dungeon Master and companion Agents use Ollama locally when available and fall back to the Blocks canned provider offline. Deployed Agents use Amazon Bedrock.
For live local inference:
ollama serve
ollama pull llama3.1:8bFixed or generic narration may indicate either the canned Agent provider or the backend's deterministic safety fallback.
npm run sandbox # deploy an isolated AWS sandbox
npm run sandbox:destroy # remove the sandbox
npm run deploy # deploy Blocks plus Flutter web Hosting
npm run destroy # remove the production stackUse the API URL printed by the sandbox when running Flutter locally:
flutter run -d chrome \
--dart-define=BLOCKS_API_URL=https://YOUR_API/aws-blocks/apiProduction Hosting builds Flutter with flutter build web --release and serves
build/web with the Blocks API on the same origin. Use the npm deployment
scripts rather than invoking CDK directly.
- Connection refused on port 3001: start
npm run devin this directory. - Port 3001 is already in use: stop the React backend or another local Blocks process.
- Android cannot reach localhost: use the emulator mapping, or provide a LAN
URL through
BLOCKS_API_URLfor a physical device. - Generated API types are stale: run
npm run generate, thennpm run verify. - Chat updates stop: polling keeps state usable; restart the backend and run the chat smoke command to check the Realtime subscription.
- Reset local accounts and games: stop the backend, run
npm run cleanup, then delete.bb-data/.
The app follows a UI/ViewModel/Repository/Service structure under lib/. Its
backend is independently namespaced with Blocks scope tf and stack ID
tabletop-flutter.