Cubiq
engineering.mdImplementation

Implementation

Inside Cubiq

Every cube turn relies on a custom system: a mathematical model, a 3D engine, and a solver that accounts for lesson goals. The Android app uses Kotlin and Jetpack Compose.

Project snapshot

lines of source and text resources
740 244
app modules
39
physical Kotlin lines outside tests
136 019
locale variants
42
test declarationstest* / androidTest* · @Test
1 624

stack.kt

Modern Android stack

Project snapshot
Kotlin2.4.21
Compose BOM2026.09.00
Material 31.5.0-beta01
Adaptive1.3.0
Navigation 31.2.0
AGP9.4.1
KSP2.3.12
Gradle9.7.0
  • Kotlin
  • Jetpack Compose
  • Material 3
  • Adaptive
  • Navigation 3

Jetpack Compose and Material 3 define interface components and themes. Adaptive handles layout by window size, while Navigation 3 handles navigation and screen restoration. State arrives through Coroutines and Flow; Hilt connects the app modules.

architecture.kt

Independent application layers

app01Hilt / DI
feature07Compose / ViewModel
  • onboarding
  • learning
  • lesson
  • practice
  • progress
  • settings
  • events
domain07contracts / use cases
  • learning
  • lesson
  • practice
  • portability
  • progress
  • settings
  • events
data09repositories / storage
  • content
  • storage
  • learning
  • lesson
  • practice
  • portability
  • progress
  • settings
  • events
core14UI kit / cube / solver
  • common
  • model
  • designsystem
  • uikit
  • navigation
  • analytics
  • crashlytics
  • ads
  • billing
  • push
  • hardware
  • cube
  • scrambleimage
  • solver
baselineprofile01startup / frame timing

feature → domain ← data

modulesΣ 39
  • app1
  • baselineprofile1
  • core14
  • data9
  • domain7
  • feature7
Kotlin · physical LOCΣ 136 019
feature
82 86360.9%
core
21 16715.6%
data
14 34110.5%
app
9 5147.0%
domain
6 7595.0%
buildSrc
9610.7%
baselineprofile
4140.3%

The interface, domain contracts, and data have separate modules; Hilt connects their implementations. Compose receives immutable state and explicit events. Room stores history and learning progress, DataStore stores settings, and Navigation 3 restores section stacks.

  • Coroutines / Flow
  • Hilt
  • Room
  • DataStore

android-ux.md

UX guided by Android recommendations

Cubiq implements approaches Google highlights in the Apps Experience Program: Compose, adaptive layout, and edge-to-edge.

Layout by window size
On a wide screen, theory and practice sit side by side. On a compact screen, content and navigation adjust to the available space; window size determines the layout.
Native navigation
Edge-to-edge accounts for system bars and the keyboard. Navigation 3 preserves section stacks and supports Predictive Back with a preview of the return transition.
Readability and accessibility
Light and dark themes, text scaling, and semantic navigation labels help people use the app with TalkBack and a keyboard. At large font sizes, section names remain available to the screen reader.
Google guidance · Apps Experience Program
OpenGL ES 3.0

engine.glsl

Geometry that follows the mathematics

moving cubies
26
facelets
54
meshes
8
triangles
2 964

GLSL shaders calculate PBR materials, roughness, and environment lighting. The model and animation stay in sync: stepping back applies the inverse move, and the camera accounts for the space between panels.

  • OpenGL ES 3.0
  • GLSL
  • PBR
  • Instancing

Cube state / formula playback

Typed notation converts into moves and consistent cube states. The renderer queue animates layer turns while preserving piece and facelet identities. A formula plays as a sequence of real moves, with play/pause and tempo controls.

  1. Notation
  2. Cube state
  3. Move queue
  4. OpenGL ES 3.0

Stepping forward animates a new move; stepping back applies the inverse move. Seeking restores the base scene and target sequence. Cancellation stops issuing further moves; a turn already started completes. The EGL lifecycle handles pause/release; if GL is unavailable, the learning path remains usable without 3D.

solver.kt

Solutions for lesson goals

  • BFS
  • Beam search
  • F2L

The custom solver builds a solution from the current lesson's formulas and auxiliary moves. SolverRequest includes cube state, target pieces, locked targets, allowed formulas, cases, and orientation. The planner respects the order of learning goals and protects pieces already solved.

Phase-specific planning uses bounded BFS, beam search, and F2L case recognition. Validation checks piece composition, flips/twists, and permutation parity. Search policy limits depth/beam width. Changing the lesson cancels the search and prevents an outdated result.

The result is a PracticePlan: steps, formula references, a display timeline, and an execution timeline. Explanations preserve the lesson orientation; the engine receives the full execution sequence. Outcomes: plan / solved / invalid input / no constrained path.

  1. Cube state
  2. Model validation
  3. Learning plan
  4. 3D practice

content.md

Content passes through the build

Theory lives in 756 Markdown documents, and practice is defined in 336 localized scenarios. Gradle validates translation structure and references to 316 original illustrations. Graphics were prepared in Blender/Cycles; the Android engine uses separate procedural geometry.

workflow.md

Docs as code / agent workflow

AGENTS.md
48
README.md
16

The repository is organized for agent development: the AGENTS.md hierarchy defines ownership, architectural constraints, and validation gates; README.md files describe module contracts, while KDoc describes API and invariants.

Architecture, design, and localization contracts are versioned alongside the code. PLAN.md records scope and handoff; contract changes include updates to the owner docs. Checks and generation run through Gradle; CI builds both store variants.

physical text linesΣ 740 244
Resources / localization
399 56854.0%
Kotlin · non-test
136 01918.4%
Lesson Markdown
132 64217.9%
Kotlin · JVM tests
46 6456.3%
Kotlin · Android tests
13 6361.8%
Build tooling / web
8 9851.2%
Documentation
2 7490.4%
Quality and counting methodology

Tests cover impossible cube states, preserving solved layers, learning plans, canceling outdated requests, session restoration, and data import. CI builds both store variants; release checks cover R8, APK/AAB, checksums, and native library alignment for 16 KB pages.

Kotlin volume counts physical lines, including comments, blank lines, buildSrc, and benchmark code, excluding test directories. The test count means 1 343 JVM declarations and 281 Android declarations, not executions. Documents include fallback text; a scenario's presence does not mean every lesson includes practice.

baselineprofile · @Test
3

Total text counts physical lines in tracked UTF-8 source, tests, XML/JSON resources, Markdown content, localization, documentation, build tooling, and web source. Comments, blank lines, and locale copies are included. Media, generated/build output, vendor code, service config, and the temporary PLAN.md are excluded. This measures the project's text inputs, not executable LOC.

Explore Cubiq