Timing is easy. Logging honestly is the useful part.
Every speedcuber has a timer. What separates a toy from a training tool is what happens around the timer: a precise hold-to-ready start, a scramble you can trust, and rolling averages — Ao5, Ao12 — that show whether you're actually getting faster or just remembering your best days.
Rubiklog set out to be the training tool, and then added the ambitious bit: let the webcam read the real cube so entering a scrambled state doesn't mean typing 54 stickers by hand.
A timer measures a solve. A log measures a solver.
What the app had to nail.
The timer has to feel native.
Space-bar control with a hold-to-ready state and visual feedback, because a laggy or ambiguous start ruins a solve time.
Statistics that speedcubers trust.
Best time, count, and correct Ao5 / Ao12 rolling averages — the metrics the community actually uses to track progress.
Scanning is a bonus, not a blocker.
Manual scramble entry always works; the webcam scanner is an accelerant that must never get in the way of just timing a solve.
React front, Django core, CV on the side.
A React client owns the timer and stats display; a Django REST backend with Postgres persists solves; an OpenCV pipeline handles cube-state detection; and a TensorFlow model experiments with predicting solve times.
The whole thing is containerised — docker-compose up brings
the app up — and configured for Render deploys, so the CV dependencies
don't turn setup into a yak-shave.
Colour is a lie the lighting tells.
The cube scanner ran straight into the classic computer-vision headache: a cube's red under warm light and its orange under cool light can land on nearly the same raw pixel value. Naive colour thresholds misread faces the moment the lighting changed, which for a scanner is a fatal flaw — one wrong sticker invalidates the whole scramble.
That's exactly why manual entry stayed the reliable default and colour normalisation became the focus of the vision work — reducing the scan to relative colour relationships rather than absolute values.
Out of the way while you solve.
The timer screen is intentionally quiet — a big time, a scramble, and nothing competing for attention mid-solve, with a dark mode for the late-night practice sessions the audience actually lives in. Statistics and history sit one step away, so the loop of solve-log-check-average stays fast.
Three things, next time.
Detect stickers in a learned colour space.
Training a small classifier on cube stickers under varied lighting would beat hand-tuned thresholds and make the scanner trustworthy.
Validate the scanned state before use.
A quick solvability check would catch a misread cube before it becomes an impossible scramble.
Ground the prediction model in data.
Solve-time prediction needs a real personal history to be meaningful; it should ship only once the log has enough solves to learn from.