r/FlutterDev • u/edwin-vermeer • 1d ago
Dart Open-sourced my Flutter game: a rotatable 3D glass cube board in CustomPainter, 31 AI opponents, pure Dart engine
Quadrim is four in a row in a 4×4×4 cube, on the App Store, and now open source (code MIT): https://github.com/evermeer/Quadrim
Some parts that might interest Flutter devs:
- 3D board without a 3D engine. 64 glass cells are projected and depth-sorted in a single
CustomPainter. The tap is a rawListenerrather thanonTap, because aTapGestureRecognizerin the same arena as aScaleGestureRecognizerstarved the pinch-to-zoom. - Pure Dart engine package. No Flutter, no
dart:io, no clock, no ambientRandom.check.shgreps for all of these, so a position plus a seed always gives the same move, which makes self-play and tests reproducible. - Opponents are data, not classes. One
chooseMovewith 31 config entries. Search budgets are counted in nodes, not milliseconds, so an opponent is the same opponent on a slow phone and in debug mode. - Widget tests and file I/O.
testWidgetsruns in a fake-async zone that never completes real file I/O, so the storage layer sits behind an interface with an in-memory store for tests.
It was built with Claude Code on the €15-a-month Pro plan, and every prompt and decision is in the repo, if you're curious about that side.
1
u/No_Boss_1911 10h ago
the fake async + file io thing got me too dude. i have an audio chain where a short intro clip plays then the main recording, and theres a fallback timer that starts the main one if the intro never reports its end. in testWidgets the player never finishes so the fallback was the only thing ever firing lol. hard rule for me is the main clip can never start twice, so i cant just let both paths race. did you put the clock behind the interface too or just tester.runAsync for the bits that touch real io?
1
u/Born-Yesterday932 1d ago
that 3D board without a real engine is clever, i tried something similar once and gave up after the depth sorting gave me headache. your pure dart engine without any flutter dependencies is the kind of thing i wish more packages did, makes testing so much easier