Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Abax

Abax is a soroban trainer. The soroban is the Japanese abacus: a frame of rods, each carrying one bead worth 5 above a beam and four beads worth 1 below it. Abax teaches which finger moves which bead, and in what order, for every kind of addition and subtraction; drills those moves; then fades the beads for mental calculation.

A lesson in Abax: the heaven bead to move is ringed in vermilion, with an arrow and the instruction 'Index finger: push the heaven bead down'.

Linux, Windows, macOS, and Android 7.0 or newer. MIT licence.

What is in this manual

  • Using Abax: installing it, how the soroban works, the finger rules, the fifteen skills of the curriculum, the drills, anzan, how the scheduler decides what you practise next, every setting, and the save file.
  • Under the hood: building from source (including the Android APK without Gradle), how the soroban is drawn on the GPU, and where things live in the code.

Where the content comes from

The bead moves, the finger order and the multiplication and division methods follow Takashi Kojima, The Japanese Abacus: Its Use and Theory (Tuttle, 1954). The grading ladders and the flash anzan speeds were checked against the Japanese federations’ published exam tables. The scheduler is built on Bayesian Knowledge Tracing (Corbett and Anderson, 1995) and an Elo-style ability estimate. Sources and the full bead-move tables: research/soroban-mechanics-and-curriculum.md.

Source: https://github.com/ZahakJ/abax.

Getting started

Install

The commands below use v0.3.0; the newest version is on the releases page. Check a download with sha256sum -c SHA256SUMS.txt --ignore-missing.

PlatformFile
Linux x86_64abax-v0.3.0-linux-x86_64.tar.gz
Windows x86_64abax-v0.3.0-windows-x86_64.zip
macOS, Apple siliconabax-v0.3.0-macos-aarch64.dmg
macOS, Intelabax-v0.3.0-macos-x86_64.dmg
Android, 64-bit ARMabax-v0.3.0-android-arm64-v8a.apk
Android, universal (adds 32-bit ARM and x86_64)abax-v0.3.0-android-universal.apk

Linux

curl -L https://github.com/ZahakJ/abax/releases/download/v0.3.0/abax-v0.3.0-linux-x86_64.tar.gz | tar xz
./abax-v0.3.0-linux-x86_64/install.sh

install.sh needs no root. It copies the binary to ~/.local/bin/abax (or $XDG_BIN_HOME), the desktop entry to ~/.local/share/applications/ and the icon to ~/.local/share/icons/. The binary also runs in place, ./abax-v0.3.0-linux-x86_64/abax. It needs a Vulkan or OpenGL driver.

Windows

In PowerShell:

Invoke-WebRequest https://github.com/ZahakJ/abax/releases/download/v0.3.0/abax-v0.3.0-windows-x86_64.zip -OutFile abax.zip; Expand-Archive abax.zip -DestinationPath abax

Then run abax\abax.exe. The binary is not code-signed, so SmartScreen may stop the first launch; choose “More info”, then “Run anyway”.

macOS

Download the dmg for your Mac (Apple menu > About This Mac: “Apple M1” or later means Apple silicon, “Intel” means Intel), open it and drag Abax.app to Applications.

The app is ad-hoc signed but not notarized, so the first launch says “Apple could not verify Abax”. Right-click the app > Open > Open; on macOS 15 and later, open it once, then click Open Anyway in System Settings > Privacy & Security. Or run once in a terminal:

xattr -cr /Applications/Abax.app

Android

On the phone, open the arm64-v8a APK link and install it, allowing installs from the browser when asked. Abax needs Android 7.0 (API 24) or newer. The universal APK also contains 32-bit ARM and x86_64 code; use it on an old 32-bit phone or an emulator. There is no sound on Android.

Your first session

  1. Home. The card at the top says what comes next. On a new profile that is the first lesson, “The rods, the beam and the beads”. Press Continue.
  2. The lesson. A few short paragraphs explain one idea. Below them the soroban plays demonstrations: the bead to move is ringed in vermilion, an arrow shows the direction, and a line of text names the finger (“Index finger: push the heaven bead down”). Use Next move to step through a demonstration by hand, Replay to see it again, and Next demo for the next example.
  3. Guided practice. Press Try it with hints. You get three items to work on the beads yourself. If you pause for 1.5 s, the next move is shown. Nothing here counts towards your record.
  4. The drill. Press Start the drill for ten items. Now the hint waits for the delay set in Settings (4 s by default) and every answer is recorded. A wrong answer replays the correct bead moves, in order.
  5. Back home. The card now offers the suggested next lesson as soon as its prerequisites are known well enough, or a planned session: a short warm-up, a focus drill on your weakest skill and a cool-down. The scheduler chapter explains how it chooses.

Nothing is locked. Open any lesson in any order, and tap I know this already on the ones you can skip (how that works). The home screen has eight entries:

EntryWhat it does
PracticeA free soroban. Tap or drag beads, or type digits.
LessonsEvery lesson, all open, with the suggested next one marked.
DrillsPick a skill and a difficulty step yourself.
AnzanA drill where the beads fade and you finish in your head.
FlashFlash anzan with your own digits, count and speed.
SprintSixty seconds, as many items as you can.
StatsMomentum, per-skill mastery, accuracy and speed.
SettingsRods, input, theme, finish, sound, data.

Working the soroban

Touch and mouse. Tap an earth bead and it moves together with the beads between it and the beam. Tap the heaven bead to toggle it. Dragged beads snap to the nearer position on release. A bead’s hit area is the full width of its rod.

Keyboard. Digits set the active rod and move one rod to the right; Backspace clears the active rod and moves left; the Left and Right arrows move the active rod in free practice; Enter or Space checks the answer; Escape or Delete clears the soroban.

Keypad. An on-screen keypad sits under the soroban. Settings can turn it off or move it to the left.

The soroban

Parts and values

The parts of a sorobanFive rods of a soroban showing 20579. The heaven bead above the beam counts 5, each earth bead below counts 1, and a bead counts only when it touches the beam.20579heaven bead: 5beam (reckoning bar)earth beads: 1 eachframeunit dots: every third rod

  • Rods. Each rod is one decimal place. The rightmost rod in use is the units, the next one to the left the tens, and so on, exactly as you write numbers.
  • Beam. The horizontal bar (the reckoning bar) divides every rod into two parts.
  • Heaven bead. The single bead above the beam is worth 5.
  • Earth beads. The four beads below the beam are worth 1 each.
  • Frame. No part in the arithmetic.

A bead counts only when it touches the beam. So each rod shows one digit:

DigitHeaven beadEarth beads at the beam
0up (away)none
1 to 4up (away)1 to 4
5down (touching)none
6 to 9down (touching)1 to 4

Four ones and one five are exactly enough for 0 to 9, so every digit has one picture. Older soroban had 5 earth beads and 2 heaven beads; the 1:4 form became the Japanese standard in the first half of the twentieth century.

Unit dots

The beam carries a small dot on every third rod. You choose one dotted rod as the units rod; the dots to its left then fall on the thousands, the millions, and so on, the way commas group digits on paper. In the diagram above the rightmost rod is the units rod and the dot on the second rod marks the thousands, so the soroban shows 20579.

Abax counts rods from the right: the rightmost rod is always the units rod and carries a dot, as does every third rod to its left.

Reading a number

Read left to right, one rod at a time, the way you read written digits. For each rod: is the heaven bead down (5) or not (0); how many earth beads touch the beam (0 to 4); add the two. Leading rods with nothing at the beam are leading zeros.

Setting a number

Start from a clear soroban: every heaven bead up, every earth bead down. Then set the digits from left to right, with the finger the finger rules give:

  • Set 3: the thumb pushes three earth beads up.
  • Set 7: the index finger brings the heaven bead down and the thumb pushes two earth beads up, in one pinch.
  • Set 406: four earth beads up on the hundreds rod, nothing on the tens, heaven bead down and one earth bead up on the units.

These are the first demonstrations of lesson S0 in Abax (3, 7, 50, 406).

Clearing

On a physical soroban you clear by tilting it towards you so every bead drops away from the beam, laying it flat and running the index finger along the top of the beam to push the heaven beads up. In Abax the Clear button (or Escape) does the same with a short sweep from the right.

How many rods

Abax offers 9, 13, 17, 21, 23 and 27 rods. A real soroban always has an odd number of rods; 13 is the usual beginner size and 23 the usual school and exam size. On phones, drills size the soroban to the problem.

Finger rules

Every move is made with one of two fingers, in a fixed order. Abax shows the finger with every move and follows the order below.

Which finger

Which finger moves which beadOne rod. The index finger moves the heaven bead in both directions. The thumb pushes earth beads up to the beam. The index finger pushes earth beads down, away from the beam.heaven bead, both ways: index fingerearth beads up: thumbearth beads down: index finger

The standard Japanese method uses two fingers of one hand:

MoveFinger
Earth beads up, towards the beam (adds)thumb
Earth beads down, away from the beam (subtracts)index
Heaven bead down, to the beam (adds 5)index
Heaven bead up, away from the beam (subtracts 5)index

The thumb only pushes up. Everything else is the index finger.

Kojima’s six ordering rules

When one digit needs both a heaven-bead move and an earth-bead move, or needs a second rod, the order is fixed. Kojima (1954, chapter III) gives six rules; Japanese school materials teach the same.

  1. Adding 6 to 9 directly (for example 1 + 6): bring the heaven bead down and push the earth beads up at the same time, as one pinch.
  2. Subtracting 6 to 9 directly (for example 9 − 7): earth beads down first, then the heaven bead up.
  3. Five-complement addition (for example 4 + 3, done as +5 −2): heaven bead down first, then the earth beads down, in quick succession.
  4. Five-complement subtraction (for example 7 − 3, done as +2 −5): earth beads up first, then the heaven bead up.
  5. Ten-complement addition (for example 4 + 8, done as −2 then +1 on the left): finish the unit rod first, then carry 1 onto the tens rod.
  6. Ten-complement subtraction (for example 11 − 7, done as −1 on the left then +3): borrow 1 from the tens rod first, then work the unit rod.

Across rods the rule is simpler: numbers are entered from the highest place to the lowest, left to right, one rod at a time, carrying and borrowing as you go. A carry always lands on a rod you have already visited, never on one still to come.

Some English tutorials narrate the carry first (“add 10, take away 3”). The hand order taught in Japan, and used by Abax, is the one above: complement first and carry second when adding, borrow first and complement second when subtracting.

The move notation

The manual writes moves on one rod like this:

NotationMeaningFinger
+1 … +4push that many earth beads upthumb
−1 … −4push that many earth beads downindex
+5heaven bead downindex
−5heaven bead upindex
+1 left, −1 leftcarry to, or borrow from, the next rod to the leftthumb, index

So “4 + 3” on a rod showing 4 is +5, −2; “4 + 8” is −2, +1 left.

The curriculum

Fifteen skills: twelve bead skills (S0 to S11) and three mental skills (A1 to A3). Each has a lesson, a drill generator that only produces items exercising its rule, and a difficulty ladder (crates/abax-core/src/curriculum.rs, generator.rs).

The graph

Nothing is locked. The prerequisites below are the suggested path, not a gate.

A skill’s prerequisites count as met when every one of them has a knowledge estimate of at least 0.80 (see the scheduler). That threshold drives three things:

  • The suggested next lesson. The lesson list marks one lesson next, and Home’s Continue opens it: the first skill, in the order of the table, whose prerequisites are met and which you have neither practised nor marked as known. It does not wait for the prerequisite to be mastered.
  • The “builds on” note. Open a lesson whose prerequisites are not met yet and a small line under its title names them, for example Builds on: S10 Multiplication, each a link to that lesson. It appears once.
  • A light review in planned sessions, described under the session planner.
The lesson list: every lesson is open. Practised skills show their estimate and step, S8 is marked next, A1 is marked known, the rest are new.

Skipping what you know

Every lesson has I know this already at the top right. It marks the skill as known, sets its knowledge estimate to 0.80 (never lowering a higher one) and moves on to the suggested next lesson. A known skill counts as met and is mixed into focus drills and cool-downs like any practised skill.

A lesson you marked shows Reset this skill in the same place; Settings → Data → Reset one skill does the same for any skill. A reset puts that one skill back to new, as if never met; your history in Stats is kept. When the skill has real practice behind it, the reset asks for a second tap.

IdSkillPrerequisites
S0Reading and setting numbersnone
S1Adding without complementsS0
S2Subtracting without complementsS0
S3Adding with the five-complementS1
S4Subtracting with the five-complementS2, S3
S5Adding with the ten-complementS3
S6Subtracting with the ten-complementS4, S5
S7Combined complementsS5, S6
S8Multi-digit additionS7
S9Mixed addition and subtractionS8
S10MultiplicationS8
S11DivisionS10
A1Anzan: the mental sorobanS7
A2Flash anzan, one digitA1, S9
A3Flash anzan, more digitsA2

Moves below use the notation from Finger rules: +3 is three earth beads up (thumb), −2 two earth beads down (index), +5 and −5 the heaven bead down and up (index), +1 left a carry onto the next rod.

Ladders

Each skill climbs a ladder of steps, raising one thing at a time: first the number of operands, then digits, then time pressure. “Gentle” timing allows 2.0 times your typical time per operand, “tight” 1.3 times, never less than 1.2 s per operand.

LadderUsed bySteps (digits × operands, timing)
SettingS01, 2, 3 digits untimed; 3 gentle; 4 gentle; 5 tight
SimpleS1, S21×2, 1×3, 1×5 untimed; 1×5 gentle; 1×8 gentle; 1×8 tight
ComplementS3 to S7same steps as Simple
Multi-digitS8, S92×2, 2×3, 2×5, 3×3, 3×5 untimed; 2×5 gentle; 3×5 gentle; 3×10 tight
MultiplyS101×1, 2×1, 3×1, 2×2 untimed; 2×2 gentle; 3×2 gentle; 3×2 tight
DivideS112÷1, 3÷1, 4÷1, 3÷2 untimed; 4÷2 gentle; 4÷2 tight
AnzanA11×2, 1×3, 1×5 untimed; 1×5 gentle; 2×3 gentle; 2×5 tight
Flash, one digitA2see Anzan and flash anzan
Flash, more digitsA3see Anzan and flash anzan

For multiplication “3×2” means a 3-digit multiplicand times a 2-digit multiplier; for division “4÷2” a 4-digit dividend and a 2-digit divisor.

S0: Reading and setting numbers

Teaches the rods, the beam, the values of the beads and the unit dots. Drills “Set this number” and “Read this soroban”, half each, with 1 to 5 digits. Set 7 is +5, +2 (one pinch); set 406 is +4 on the hundreds, then +5, +1 on the units.

S1: Adding without complements

Rule: when the beads you need are free, push them to the beam. The thumb pushes earth beads up, the index finger brings the heaven bead down; for 6 to 9 both move together. Drills chains of one-digit additions in which no complement is ever needed. Examples from the lesson: 2 + 2 is +2; 3 + 5 is +5; 1 + 6 is +5, +1 in one pinch; 12 + 36 is +3 on the tens, then +5, +1 on the units.

S2: Subtracting without complements

Rule: move beads away from the beam with the index finger; for 6 to 9, earth beads first, then the heaven bead. Drills one-digit subtraction chains with no complement. Examples: 4 − 3 is −3; 8 − 5 is −5; 9 − 7 is −2, −5; 87 − 52 is −5 on the tens, −2 on the units.

S3: Adding with the five-complement

Rule: when the earth beads you need are not free, add 5 and take away the “small friend” (the number that makes 5 with it: 1 and 4, 2 and 3). Heaven bead first, then the earth beads, both with the index finger. Drills addition chains that must use the five-complement at least once and never need a carry. Examples: 1 + 4 is +5, −1; 3 + 3 is +5, −2; 4 + 2 is +5, −3; 23 + 34 is +5, −2 on the tens and +5, −1 on the units.

Adding 3 to 3 with the five-complementThree panels of one rod. It shows 3. The index finger brings the heaven bead down, making 8. Then the index finger pushes two earth beads down, leaving 6. Adding 3 is done as adding 5 and taking away 2.33+58−26start: 3index: heaven bead downindex: 2 earth down

S4: Subtracting with the five-complement

Rule: when the earth beads to take are not at the beam, take 5 away and give back the small friend: earth beads up with the thumb first, then the heaven bead up with the index finger. Drills subtraction chains that use it. Examples: 6 − 4 is +1, −5; 5 − 2 is +3, −5; 7 − 3 is +2, −5; 65 − 42 is +1, −5 on the tens and +3, −5 on the units.

S5: Adding with the ten-complement

Rule: when the sum would pass 9, take away the “big friend” (the number that makes 10: 1 and 9, 2 and 8, 3 and 7, 4 and 6, 5 and 5) on this rod, then carry 1 onto the rod to the left. Drills addition chains that need a carry at least once (five-complements may appear too). Examples: 4 + 8 is −2, +1 left; 9 + 1 is −4, −5, +1 left (taking away 9, the friend of 1); 5 + 5 is −5, +1 left; 38 + 27 is +5, −3 on the tens (a five-complement), then −3 on the units and +1 left, giving 65.

Adding 8 to 4 with the ten-complementThree panels of two rods. The units rod shows 4. The index finger takes away 2 earth beads, the friend of 8, leaving 2. Then the thumb pushes one earth bead up on the tens rod. The result is 12.404−202+1 on the left12start: 4index: take the friend 2thumb: carry 1 left

S6: Subtracting with the ten-complement

Rule: when the rod does not hold enough, borrow 1 from the rod on the left first, then add the big friend on this rod. Drills subtraction chains that need a borrow. Examples: 11 − 7 is −1 left, +3; 10 − 1 is −1 left, +5, +4; 15 − 8 is −1 left, +2; 62 − 38 is +2, −5 on the tens, then −1 left, +2 on the units, giving 24.

S7: Combined complements

Rule: the ten-complement’s own move on the rod sometimes cannot be made directly and needs a five-complement inside it. 7 + 6: taking away 4 (the friend of 6) from 7 is impossible with two earth beads up, so take 4 through 5: +1, −5, then +1 left, giving 13. In subtraction, 12 − 7: borrow (−1 left), then add 3 to the 2 on the units rod, which needs the small friend: +5, −2, giving 5. Drills mixed chains that must contain a combined move. Other lesson examples: 6 + 8 is +3, −5, +1 left; 13 − 6 is −1 left, +5, −1.

Exactly these one-rod additions are combined: 5 + 6 to 5 + 9, 6 + 6 to 6 + 8, 7 + 6, 7 + 7 and 8 + 6. (8 + 7 is not: 8 has three earth beads up, so −3, +1 left works directly.)

S8: Multi-digit addition

Rule: nothing new. Add each digit on its own rod, from the left; carries travel left, so they never land on a rod you still have to visit. Drills chains of 2- and 3-digit numbers, 2 to 10 operands, any complement allowed. Example: 478 + 365. Hundreds: 4 + 3 is +5, −2. Tens: 7 + 6 is the combined move +1, −5, then +1 on the hundreds. Units: 8 + 5 is −5, then +1 on the tens. Result 843. And 1999 + 1, where one carry ripples across three rods: −4, −5 on the units, tens and hundreds in turn, then +1 on the thousands.

S9: Mixed addition and subtraction

Rule: every operation lands on the running total, so plus and minus mix freely. Before a subtraction, look left to see where a borrow will come from. Drills mixed chains of multi-digit numbers. Example: 843 − 599. Hundreds: −5. Tens: 4 − 9 borrows 1 from the hundreds and adds 1 to the tens, which on a rod showing 4 is +5, −4. Units: 3 − 9 borrows from the tens (5 − 1 is +4, −5), then adds 1 on the units. Result 244.

S10: Multiplication

Method: Kojima’s standard method. Set the multiplier on the left and the multiplicand to its right with two empty rods between. Multiply the rightmost digit of the multiplicand by each multiplier digit from left to right. Each two-digit partial product goes with its tens on the first rod to the right of the multiplicand digit being used, and each next one shifts a rod further right. Clear the multiplicand digit, move to the next one to the left. The product’s units end up (digits of the multiplier + 1) rods to the right of the multiplicand’s units. Drills products from 1 × 1 digits up to 3 × 2 digits; you type the answer and can step through the worked procedure.

Abax’s own walk-through of 23 × 12:

  1. Set the multiplier 12 on the left.
  2. Set the multiplicand 23 with its units on the unit rod, two empty rods after the multiplier.
  3. 3 × 1 = 03: add it with its tens on the first rod right of the 3.
  4. 3 × 2 = 06: add it one rod further right.
  5. Clear the 3.
  6. 2 × 1 = 02, tens on the first rod right of the 2; 2 × 2 = 04 one rod further right.
  7. Clear the 2 and read 276, three rods right of where the multiplicand’s units were.

S11: Division

Method: the standard method (商除法, shōjohō). Set the dividend with its units on a unit rod and the divisor on the left, four empty rods away. Compare the divisor with the leading digits of the dividend and guess a quotient digit; it goes two rods left of the dividend’s leading digit when the divisor goes into that one digit, one rod left when two digits are needed. Subtract quotient × divisor digit by digit. If a partial product cannot be subtracted, the guess was too large: lower it by one and add back what was already taken. If what remains is still at least the divisor, the guess was too small: raise it and subtract once more. Drills exact divisions from 2-digit ÷ 1-digit up to 4-digit ÷ 2-digit.

Abax’s walk-through of 391 ÷ 17 revises twice: try 3 (from 3 ÷ 1), find 3 × 7 cannot be taken, revise to 2 and take 2 × 7; then try 5, revise to 4, then to 3, and take 3 × 7. The quotient 23 is read three rods left of the dividend’s units.

A1: Anzan, the mental soroban

Teaches calculating on a soroban you picture. The start of each item is set on the beads, the beads fade to glass and vanish, and you add the rest in your head and type the total. Drills one-digit chains of mixed addition and subtraction with any complement, then 2-digit chains. Details in Anzan and flash anzan.

A2 and A3: Flash anzan

Teaches adding numbers that flash one after another, without beads at all. A2 uses one-digit numbers, A3 two and three digits. The ladders are in Anzan and flash anzan.

Drill types

A drill is a short run of items, 8 to 15 in a planned session, 3 to 30 when you choose one yourself under Drills. Every item has exactly one focus skill, and the generator builds it so that the bead moves it needs use that skill’s rule and nothing you have not met yet. A “small friends” drill never asks for a carry; a “combined” drill always contains at least one combined move.

The item kinds

KindYou seeYou doSkills
Set this number“Set 4071” and a clear sorobanMove the beads until they show itS0
Read this sorobanA number on the beads, digits hiddenType the numberS0
Chain“6 + 5 + 6”, the start already on the beadsWork each operation on the beadsS1 to S9
Multiplication“34 × 6”Type the product; the worked procedure is availableS10
Division“391 ÷ 17”Type the quotient; the worked procedure is availableS11
Anzan chainA chain whose start fades from the beadsFinish in your head, type the totalA1
FlashNumbers shown one at a timeType the sumA2, A3

Working on the beads. For “set” and chain items you do not type the answer. The current operand is highlighted in the problem line; Abax follows the running total on the beads and accepts the item once the beads have shown the final answer for about half a second. You can also press Enter to check early (the Check button).

Hints. If you make no move for the hint delay (4 s by default, see Settings; 1.5 s in a lesson’s guided practice), the next move is shown on the soroban: the beads to move are haloed in vermilion, with an arrow, for one rod at a time.

When you are wrong. Abax shows the correct answer and replays the correct bead moves on the soroban in order, from where the item started. For multiplication and division the step-by-step procedure takes that role.

Where the drills come from

  • A planned session (the Continue button on the home screen): warm-up, focus and cool-down drills chosen by the scheduler. About 30 % of the focus drill’s items are drawn from other skills you have already practised, each at its own current step.
  • Drills on the home screen: choose a skill (grouped as set and read, add and subtract, longer numbers, multiply, divide, anzan), a step on its ladder (it starts at your current step; you can move it either way) and the number of items. Every skill can be chosen, whatever you have learned so far; it starts on the furthest skill you have met.
  • Sprint: choose a skill and a step; you get as many items as you can answer in 60 seconds. Mistakes do not end it.
  • Lessons end in three guided items (not recorded), then a 10-item drill.

Difficulty and time pressure

Each skill’s ladder (see the curriculum) raises one thing at a time: more operands, then more digits, then time pressure. Timed steps have a time budget per operand: 2.0 times your typical time on a “gentle” step, 1.3 times on a “tight” one, never below 1.2 s. The budget is not a countdown on the screen; the scheduler uses it to decide when you are fluent enough to go further: on a timed step you step up only when your typical time is at most 80 % of the budget.

Every answer and its time goes into the history and the scheduler, except in guided lesson practice.

Anzan and flash anzan

Anzan (暗算) is mental calculation. Soroban-trained anzan is a particular kind: you picture a soroban and move its beads in your mind with the same moves your fingers make. Expert users hold the numbers as a visual image, rod by rod, rather than as words.

Schools build the image in stages: the real soroban, then covered, then finger movements in the air, then no movement. Abax does this in two skills, after the bead skills.

A1: fading beads

An anzan item is a chain, like a bead drill. The first number is set on the soroban and you see it for a moment (0.8 s). Then the beads fade over 2.5 s: the body of each bead turns to translucent glass first, the highlights stay until late, and in the last quarter everything vanishes. The frame stays. You finish the chain on the soroban you now only imagine, and type the total.

Kojima recommends moving the index finger and thumb in the air as if working real beads.

The soroban part-way through the anzan fade: the beads are half transparent, like glass, while the frame stays solid.

The A1 ladder: one-digit chains of 2, 3 and 5 numbers untimed, then 5 with gentle timing, then 2-digit chains of 3 (gentle) and 5 (tight). The chains mix addition and subtraction and may use every complement. The Anzan button on the home screen starts an 8-item anzan drill at your current step.

A2 and A3: flash anzan

Flash anzan (フラッシュ暗算) shows numbers one at a time in the same place; you add them as they appear and type the total after the last one. There are no beads on screen at all. The form was developed in Japan by Yūji Miyamoto and is now examined and competed in by the Japanese soroban federations; at the top level, fifteen 3-digit numbers flash in under two seconds.

Each number in Abax is shown for the display time, with a short blank between numbers (12 % of the display time, between 0.04 and 0.2 s) so that two equal numbers in a row still read as two. A run is five rounds; after each answer you see “Correct” or the true total.

The ladders

The display time is per number.

A2, one digit:

StepNumbersDisplay timeWhole sequence
131.5 s4.5 s
251.5 s7.5 s
351.2 s6.0 s
451.0 s5.0 s
580.8 s6.4 s
6100.6 s6.0 s
7100.5 s5.0 s
8150.4 s6.0 s

A3, more digits:

StepDigitsNumbersDisplay timeWhole sequence
1231.5 s4.5 s
2251.2 s6.0 s
3251.0 s5.0 s
4280.8 s6.4 s
52100.6 s6.0 s
6351.0 s5.0 s
73100.8 s8.0 s
83150.5 s7.5 s

Every step is faster, longer or wider than the one before it. The Japan Flash Anzan Association’s exam ladder starts at three one-digit numbers in 5 s (1.67 s each); its tenth dan is fifteen 3-digit numbers in 3 s (0.2 s each). Free flash goes down to 0.2 s.

The usual step-up and step-down rules move you along the ladder; a message says when you moved up or eased back a step.

Free flash

The Flash button on the home screen opens flash anzan with your own settings: 1 to 4 digits, 2 to 20 numbers, 0.2 to 3.0 s per number. Abax remembers them (flash_digits, flash_count, flash_ms in the save file). Answers in free flash are recorded under A2 when the numbers have one digit and under A3 otherwise.

The adaptive scheduler

The scheduler decides what to practise next from your answers and their times. The numbers below are those in crates/abax-core/src/scheduler.rs.

PieceQuestion
Bayesian Knowledge TracingDo you know this rule?
Accuracy averageHow are you doing lately?
Time averageHow fast are you when you are right?
Elo abilityIs this particular step too hard for you?
Ladder rulesShould the next items be harder or easier?
Mastery gateAre you done with this skill?
Forgetting and reviewHave you started to lose it?
Session plannerWhich drills, in which order, today?

Do you know the rule? Bayesian Knowledge Tracing

Bayesian Knowledge Tracing (Corbett and Anderson, 1995) keeps one number per skill, L, the probability that you know it, allowing for guesses and slips:

ParameterValueMeaning
P(L₀)0.10before any answer, a 10 % chance you already know it
P(G)0.20chance of a right answer without knowing the rule (guess)
P(S)0.10chance of a wrong answer although you know it (slip)
P(T)0.10chance of learning it from one more item

After a right answer, Bayes’ rule gives

post = L (1 − P(S)) / ( L (1 − P(S)) + (1 − L) P(G) )

after a wrong answer

post = L P(S) / ( L P(S) + (1 − L) (1 − P(G)) )

and then the chance that this item taught you the rule is added:

L′ = post + (1 − post) P(T).

By hand

Start at L = 0.10 and answer correctly.

  • Numerator: 0.10 × 0.90 = 0.09. Denominator: 0.09 + 0.90 × 0.20 = 0.27. post = 0.09 / 0.27 = 0.333.
  • Learning step: 0.333 + 0.667 × 0.10 = 0.400.

Correct again from 0.400: 0.36 / (0.36 + 0.60 × 0.20) = 0.75, then 0.75 + 0.25 × 0.10 = 0.775. Two more right answers give 0.9455 and 0.9886.

Now a wrong answer from 0.9886: 0.09886 / (0.09886 + 0.0114 × 0.80) = 0.9156, plus the learning step: 0.924. The same slip after three right answers, from 0.9455, gives 0.09455 / (0.09455 + 0.0545 × 0.80) = 0.684, then 0.716.

The curriculum graph uses L directly: a skill’s prerequisites count as met when every one has L ≥ 0.80. Three right answers in a row on S3 (0.9455) are already enough to make S5 the suggested next step.

I know this already sets L to exactly 0.80 (and θ to the matching ln(0.8 / 0.2) = 1.386) without adding any answers. One right answer from there: 0.72 / (0.72 + 0.20 × 0.20) = 0.947, then 0.953. One wrong answer: 0.08 / (0.08 + 0.20 × 0.80) = 0.333, then 0.400, back below the threshold.

How are you doing lately? The accuracy average

An exponentially weighted moving average (EWMA) of accuracy tracks recent performance:

acc′ = acc + 0.2 × (correct − acc), with correct = 1 or 0, starting at 0.5.

Each answer moves the average a fifth of the way towards itself, so it mostly reflects the last ten or so items. From 0.5, right answers give 0.6, 0.68, 0.744; a wrong one then drops it to 0.744 − 0.2 × 0.744 = 0.595. Ten right answers in a row from 0.5 reach 0.946.

How fast? The time average

An EWMA of the logarithm of seconds per operand, on right answers only:

log_t′ = log_t + 0.3 × (ln(seconds per operand) − log_t).

Your “typical time” is exp(log_t). It starts at three times the skill’s benchmark. Benchmarks, in seconds per operand: S0 3.0; S1 and S2 2.5; S3 and S4 3.0; S5, S6 and S7 3.5; S8 and S9 5.0; S10 12; S11 15; A1 2.0; A2 and A3 1.0.

Is this step too hard? Elo ability

You and the item are rated on one scale, as in chess. Each item has a difficulty d computed from its step:

d = base(skill) + 0.40 (digits − 1) + 0.25 (operands − 2) + 0.50 [timed] + 0.30 [flash]

with base −1.5 for S0; −1.0 for S1 and S2; 0.0 for S3 and S4; 0.5 for S5 and S6; 1.0 for S7; 1.5 for S8 and A1; 2.0 for S9 and S10; 2.5 for S11 and A2; 3.0 for A3. Your ability θ on the skill starts at 0. The predicted chance of a right answer is the logistic curve

P = 1 / (1 + e^−(θ − d)),

and after each answer

θ′ = θ + U(n) × (correct − P), with U(n) = 1 / (1 + 0.06 n),

where n is how many items of this skill you have answered. A surprise moves θ a lot, an expected result very little, and U shrinks as evidence accumulates: U(0) = 1, U(10) = 0.625, U(100) = 0.14.

Harder or easier? The ladder rules

Every skill has a ladder of steps. After each answer:

Step down (if not already on the first step) when you have made two errors in a row on this step, or when accuracy has fallen below 0.60 after at least 6 items on the step.

Step up when all of these hold:

  • accuracy ≥ 0.85;
  • at least 8 items on this step;
  • the Elo prediction for this step, P, is at least 0.85;
  • on a timed step: typical time ≤ 0.8 × the time budget that was fixed when you entered the step;
  • when the next step is the first timed one: accuracy ≥ 0.90.

A worked session

A learner starts S3 (adding with the five-complement) at step 1: two one-digit operands, untimed, so d = 0. Each item takes 4.0 s, which is 2.0 s per operand. They answer right, right, right, wrong, then right eight times. These are the scheduler’s actual numbers:

ItemAnswerLacctypical s/operandθStep
1right0.4000.6005.730.5001
2right0.7750.6804.180.8561
3right0.9460.7443.351.1221
4wrong0.7160.5953.350.4831
5right0.9270.6762.870.7911
6right0.9850.7412.581.0311
7right0.9970.7932.391.2241
8right0.9990.8342.261.3841
9right1.0000.8672.181.5201
10right1.0000.8942.131.6361
11right1.0000.9152.091.7382
12right1.0000.9321.821.8492

Follow item 1 through every piece:

  • L: 0.10 → 0.400, as computed above.
  • acc: 0.5 + 0.2 × (1 − 0.5) = 0.6.
  • time: the average starts at ln(3 × 3.0) = ln 9 = 2.197. The sample is ln 2.0 = 0.693. 2.197 + 0.3 × (0.693 − 2.197) = 1.746, and e^1.746 = 5.73 s.
  • Elo: P = 1 / (1 + e^0) = 0.5 and U(0) = 1, so θ = 0 + 1 × (1 − 0.5) = 0.5.

Item 2’s Elo update: P = 1 / (1 + e^−0.5) = 0.622, U(1) = 1 / 1.06 = 0.943, θ = 0.5 + 0.943 × 0.378 = 0.856.

Why no step up before item 11? At item 9 the learner already had 9 items on the step, L near 1 and accuracy 0.867, but the Elo prediction was 1 / (1 + e^−1.520) = 0.82, under 0.85. At item 10 it was 0.837. At item 11, θ = 1.738 gives 0.850, accuracy is 0.915, and the next step is still untimed: up to three operands. The wrong answer at item 4 cost about three items.

Readiness follows the live estimate. S3’s L passed 0.80 at item 3, which made S5 a suggested next step (and S4, once S2 is there too); the error at item 4 took that back until item 5.

Are you done? The mastery gate

A skill is marked mastered when all five hold:

  • L ≥ 0.95;
  • at least 10 answers on the skill;
  • accuracy ≥ 0.90;
  • you have reached at least the second-to-last step of its ladder, which for most skills is the first timed one;
  • typical time ≤ 1.5 × the skill’s benchmark.

Four lucky answers reach L = 0.989 but fail the count. The learner above, after twelve items, is on step 2 of 6: S3 counts as met, but is not mastered.

Have you started to lose it? Forgetting and review

L decays with the days since the skill was last practised:

L_eff = L × e^(−days / τ), with τ = 14 × review interval (in days).

A mastered skill starts with a review interval of 1 day. It is due for review when L_eff falls below 0.80 or when the interval has passed. Example: L = 0.96, 14 days without practice, interval 1 day: τ = 14 and L_eff = 0.96 × e^−1 = 0.353, clearly due. Had the interval grown to 10 days, τ = 140 and L_eff = 0.869: not due by decay, but due because 14 days exceeds 10.

When you answer a due review with accuracy ≥ 0.90, the interval grows by a factor of 1.6, up to 60 days. If accuracy on a mastered skill drops below 0.70, the mastered mark is removed and the interval resets to 1 day.

What today? The session planner

A planned session is three short drills. They pick from the skills on the suggested path (prerequisites met) plus every skill you have already met, practised or marked as known. A gap in the prerequisites never stops it.

  1. Warm-up, 7 items. The due review that has waited longest, at its current step. If nothing is due and the focus skill below has a prerequisite under 0.80 (you went ahead of the suggested path), a light review of that prerequisite instead: 5 untimed items at its current step, the weakest prerequisite first. Otherwise the most recently mastered skill at its top step. Target success about 90 % (85 % for the light review).
  2. Focus, 12 items. Among those skills that are not yet mastered, sort by L_eff and take the weakest, with probability 0.7, or the second weakest, with probability 0.3. About 30 % of its items come from other skills you have already met, each at its own step. Target success about 80 %. The focus runs whatever the state of its prerequisites.
  3. Cool-down, 6 items. Untimed items from the skills you know well (L_eff ≥ 0.80), strongest first, mixed together. A skill marked as known starts here at exactly 0.80.

An example with a gap. A new learner opens S10 straight away and answers six multiplication items, half of them right, and has also done some S0. S10 is now a skill they have met, so the planner can choose it; with the lowest L it is the usual focus. Its prerequisite S8 has never been touched (L = 0.10), nothing is due, so the warm-up becomes five untimed S8 items at step 1, and then the twelve S10 items run as normal.

On a brand-new profile the only skill on the path is S0, so the plan is a single 12-item S0 drill. And before any of this, the home screen’s Continue sends you to the suggested next lesson, the first skill on the path you have neither tried nor marked as known.

Momentum

The stats screen shows the last 14 days: items, minutes, days active, and a “momentum” figure that halves every three days without practice.

Sources

  • Corbett, A. T. and Anderson, J. R. (1995), “Knowledge tracing: Modeling the acquisition of procedural knowledge”, User Modeling and User-Adapted Interaction 4: 253–278.
  • Pelánek, R. et al., “Elo-based learner modeling for the adaptive practice of facts”, User Modeling and User-Adapted Interaction (the uncertainty function U(n) = α / (1 + βn), with α = 1 and β = 0.06).
  • Klinkenberg, Straatemeier and van der Maas (2011), Math Garden: item difficulty and ability on one logistic scale.
  • Rohrer and Taylor (2007), on interleaved practice.

Settings

Open Settings from the home screen. Every change is applied at once and saved with your profile; the name in brackets is the field in the save file.

The settings screen with sections Soroban, Appearance, Sound, Data and About.

Soroban

SettingChoicesDefaultWhat it does
Rods (rod_count)9, 13, 17, 21, 23, 2713 (9 on a new Android profile)Rods on the free-practice soroban and the upper limit for drills. Drills use fewer when the problem needs fewer, so beads stay large on phones.
Beads move by (input_mode)tap, drag, bothbothTap moves a bead group in one go; drag lets beads follow the finger and snap on release.
Show the number under the rods in free practice (show_numbers)on, offonThe digit under each rod. Drills decide for themselves: a “read” item hides them, anzan hides them.
Show the on-screen keypad (show_keypad)on, offonItems that need a typed answer always show it.
Left-handed layout (left_handed)on, offoffPuts the keypad on the left.
Hint after (hint_delay_seconds)1.5 to 10 s4 sHow long Abax waits after your last move before showing the next one in a drill. Guided practice in lessons always uses 1.5 s.

Appearance

SettingChoicesDefaultWhat it does
Theme (theme)system, light, darksystemPaper and ink, or the dark variant. “system” follows the operating system.
Finish (finish)walnut, ebony, maplewalnutThe soroban’s material. Walnut: lacquered walnut frame, bamboo rods, bone beads. Ebony: near-black frame, brass rods and beam, bone beads. Maple: pale maple frame, steel rods, slate beads. Vermilion stays the one accent in all three.
Large text (large_text)on, offoffScales all text by 1.22.
Reduce motion (reduce_motion)on, offoffBeads jump to their new place instead of gliding, and the hint halo stays steady instead of pulsing.

The walnut finish The ebony finish The maple finish

Sound

SettingChoicesDefaultWhat it does
Bead click (sound)on, offoffA short synthesised click per bead group: a 2 ms noise burst into a decaying 1.8 kHz resonance, a little lower for the heaven bead.
Volume (volume)0 to 10.6Loudness of the click.

There is no sound on Android; the settings screen says so when there is no audio output.

Flash anzan

The three free-flash settings, digits (flash_digits, default 1), numbers (flash_count, default 5) and seconds per number (flash_ms, default 1000 ms), are set on the flash screen itself before each run and remembered there. See Anzan and flash anzan.

Data

  • Profile shows the path of your save file.
  • Save now writes it immediately (Abax also saves by itself within 5 seconds of a change, and when it closes).
  • Reset all progress asks for confirmation, then deletes lesson progress, mastery and history. Your settings stay.

About

The Abax version, and the average and 95th-percentile frame time over the last 120 frames.

The save file

Settings, scheduler state and history are one JSON file, profile.json.

Where it is

PlatformDirectory
Linux~/.local/share/abax/ (or $XDG_DATA_HOME/abax/)
macOS~/Library/Application Support/abax/
Windows%APPDATA%\abax\data\
Androidthe app’s internal storage (not visible without root)

Settings > Data shows the exact path. Set the environment variable ABAX_DATA_DIR to use another directory on the desktop:

ABAX_DATA_DIR=~/abax-test abax     # a separate, throwaway profile

To move your progress to another computer, copy profile.json into the same place there while Abax is closed.

How it is written

Abax writes the whole document to profile.json.tmp, flushes it to disk (fsync), and renames it over profile.json. The rename is atomic: the file is either the old version or the new one.

If the file cannot be read (damaged, or written by a newer Abax), Abax copies it to profile.json.bak, starts a fresh profile and logs a warning.

Versioning

The document carries a version field. This build writes version 1 and reads versions up to 1; a missing or newer version is rejected. Two rules let the format grow:

  • Unknown fields are ignored, so an older Abax can open a file a newer one wrote, as long as the version number did not change.
  • Missing fields take their defaults, so a newer Abax can open an older file. The finish setting was added in 0.2.0; a 0.1.0 profile has no such field and loads as walnut. 0.3.0 added marked_known to each skill and builds_on_noted at the top level; a 0.2 profile loads with every skill unmarked and no notes shown. Both changes are additive, so the version stays 1 and 0.2.x can still open a 0.3.0 file (it ignores the two fields).

When the curriculum gains a skill, loading fills in a fresh state for it. When a change needs real conversion, the version number goes up and SaveFile::migrate in crates/abax-core/src/store.rs gets a step for it.

The schema, annotated

The file is written on one line. Formatted and commented, after one answered item, with one of the fifteen skill entries:

{
  "version": 1,                       // format version
  "settings": {
    "rod_count": 13,                  // 9, 13, 17, 21, 23 or 27
    "theme": "System",                // "System" | "Light" | "Dark"
    "finish": "Walnut",               // "Walnut" | "Ebony" | "Maple" (0.2.0)
    "sound": false,
    "volume": 0.6,                    // 0..1
    "left_handed": false,
    "show_numbers": true,
    "show_keypad": true,
    "input_mode": "Both",             // "Tap" | "Drag" | "Both"
    "reduce_motion": false,
    "large_text": false,
    "hint_delay_seconds": 4.0,
    "flash_digits": 1,                // free flash anzan defaults
    "flash_count": 5,
    "flash_ms": 1000
  },
  "scheduler": {
    "skills": {                       // one entry per skill, keyed by name
      "Setting": {                    // S0; others: AddSimple, SubSimple, AddFive,
                                      // SubFive, AddTen, SubTen, Combined, MultiAdd,
                                      // MultiMixed, Multiply, Divide, Anzan,
                                      // FlashOne, FlashMulti
        "p_known": 0.4,               // BKT probability the skill is known
        "acc_ewma": 0.6,              // accuracy average
        "log_t_ewma": 1.8007,         // average ln(seconds per operand)
        "theta": 0.1824,              // Elo ability on this skill
        "n": 1,                       // answers so far
        "level": 0,                   // current ladder step, 0-based
        "last_practised": 1760000060, // unix seconds; 0 = never
        "mastered_at": null,          // unix seconds, or null
        "review_interval_days": 1.0,
        "consecutive_errors": 0,      // on the current step
        "items_at_level": 1,          // since the last step change
        "budget_seconds": 0.0,        // time budget per operand on a timed step
        "marked_known": false         // "I know this already" (0.3.0)
      }
    }
  },
  "history": {
    "attempts": [                     // oldest first, at most 50,000 kept
      {
        "ts": 1760000060,             // unix seconds
        "skill": "Setting",
        "level": 0,                   // ladder step the item came from
        "kind": "Set",                // Set | Read | AddSub | Multiply | Divide |
                                      // Mixed | Sprint | Anzan | Flash | Lesson
        "correct": true,
        "seconds": 2.4                // time for the whole item
      }
    ]
  },
  "created": 1760000000,              // unix seconds the profile was created
  "updated": 1760000060,              // unix seconds of the last save
  "builds_on_noted": []               // lessons whose "builds on" note was
                                      // shown once, e.g. ["Divide"] (0.3.0)
}

The scheduler chapter explains every field under scheduler. Everything on the stats screen (momentum, mastery bars, accuracy and speed curves, the session log) is computed from history when it is shown; none of it is stored separately.

Building from source

Desktop

You need a stable Rust toolchain (install it with rustup). On Linux you also need the development headers for ALSA (sound) and for X11/Wayland windowing. On Debian or Ubuntu:

sudo apt-get install libasound2-dev libxkbcommon-dev libwayland-dev \
  libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev

Windows and macOS need nothing beyond Rust (and the Xcode command-line tools on macOS).

git clone https://github.com/ZahakJ/abax
cd abax
cargo run --release -p abax

The release profile uses link-time optimisation, strips symbols and aborts on panic.

The release gate: ./verify

./verify

runs, in order, and stops at the first failure:

  1. cargo fmt --all -- --check: formatting.
  2. cargo clippy --workspace --all-targets -- -D warnings: lints, with every warning an error.
  3. cargo test --workspace: all unit tests.
  4. cargo build --release -p abax: the desktop binary.

CI runs the same script on every push.

Android, without Gradle

Abax on Android is a pure native app: the manifest says hasCode="false" and the activity is Android’s built-in NativeActivity, which loads libabax.so and calls its android_main. android/build-apk.sh builds the APK with the SDK’s command-line tools.

What you need

  • The Android SDK with build-tools;35.0.0 and platforms;android-35.
  • The NDK (CI uses 27.2.12479018).
  • A JDK, for apksigner and keytool.
  • cargo-ndk and the Rust Android targets:
cargo install cargo-ndk
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
export ANDROID_HOME=/path/to/android-sdk
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/27.2.12479018
export JAVA_HOME=/path/to/jdk

Build

android/build-apk.sh --abis arm64-v8a --out dist/abax.apk
android/build-apk.sh --abis "arm64-v8a armeabi-v7a x86_64" --out dist/abax-universal.apk

Add --debug for an unoptimised build.

What the script does, step by step

  1. Native library. cargo ndk -t <abi> … --platform 24 build -p abax --release compiles the abax crate as libabax.so for each ABI, against API level 24 (Android 7.0). .cargo/config.toml adds -z max-page-size=16384 to the link, which Android 15 devices with 16 KB memory pages require.
  2. Resources. aapt2 compile turns android/res/ (icon, label, theme) into compiled resources; aapt2 link combines them with android/AndroidManifest.xml and the platform’s android.jar into an unsigned APK. The version name comes from the workspace Cargo.toml and the version code is major × 10000 + minor × 100 + patch (0.3.0 is 300).
  3. Libraries in. A few lines of Python add lib/<abi>/libabax.so to the APK uncompressed, so Android can map them straight from the APK instead of extracting them.
  4. Align. zipalign -P 16 -f 4 aligns the uncompressed libraries to 16 KB pages and everything else to 4 bytes.
  5. Sign. apksigner sign signs with APK signature schemes v2 and v3, then apksigner verify and aapt dump badging print what was built: the package, minSdkVersion 24, targetSdkVersion 35, the launchable android.app.NativeActivity and the native ABIs.

Pinned SDK components

The script uses fixed versions, not the newest in your SDK:

VariableDefaultSelects
ABAX_BUILD_TOOLS35.0.0$ANDROID_HOME/build-tools/<version>
ABAX_PLATFORM35$ANDROID_HOME/platforms/android-<version>/android.jar

It stops if either is missing.

Signing

Without ABAX_KEYSTORE the script signs with a throwaway debug key under target/android/. Android refuses to update an app signed with a different key, so a release needs a stable one:

VariableMeaning
ABAX_KEYSTOREpath to the keystore
ABAX_KEYSTORE_PASSWORDits password (also used as the key password)
ABAX_KEY_ALIASthe key’s alias

In the release workflow the keystore arrives base64-encoded in the ABAX_KEYSTORE_B64 secret; the job fails without the three secrets.

Releases

Pushing a tag vX.Y.Z runs .github/workflows/release.yml: it builds Linux (tarball with an installer), Windows (zip), macOS for Apple silicon and Intel (dmg, cross-compiled on one Apple silicon runner) and both Android APKs, writes SHA256SUMS.txt, and publishes a GitHub release whose text is the tag’s section of CHANGELOG.md.

The website

The landing page and this manual are built by docs/build.sh and published to GitHub Pages by .github/workflows/pages.yml on every push to main that touches docs/. To build them locally you need mdBook 0.5.4:

cargo install mdbook --version 0.5.4 --locked
docs/build.sh site-out
python3 -m http.server -d site-out 8000   # landing page at /, manual at /manual/

All links are relative, so the site works under any path.

Rendering

Everything except the soroban is ordinary egui: text, buttons, the keypad, charts, hint arrows and the digits under the rods. The soroban is one egui_wgpu paint callback: one pipeline, one instanced draw, shaded per pixel in WGSL (crates/abax/src/render/mod.rs and soroban.wgsl). eframe already renders through wgpu on every target; naga translates the WGSL to Vulkan, Metal, DirectX 12 and OpenGL ES.

The soroban: lit, rounded beads on bamboo rods in a grained walnut frame.

How it works

Every part of the instrument is one instance of a unit quad, drawn in this order: the board, the recessed well, the glow behind the active rod, the rods, the beam, the unit dots, an underline, hint halos, bead shadows, and the beads. Each instance is 96 bytes: a rectangle, a kind, four parameters and three colours. SorobanView::build_instances fills a reused Vec on the CPU each frame; the callback’s prepare copies it into the instance buffer and paint issues the single draw. Each soroban on screen (the home screen has a small live one) owns its own instance and uniform buffers.

The fragment shader picks a shading function by kind:

  • Beads are solids of revolution around the rod. The silhouette is a superellipse lens, pointed at the sides like a real biconical soroban bead, with the equator ridge slightly softened. From the profile the shader derives a surface normal, then lights it with a key light from the upper left: diffuse, a specular lobe, rim darkening at grazing angles, ambient occlusion where a bead touches its neighbour or the beam, and the dark bore where the rod enters. A short brightening marks a bead you just moved. For anzan the bead turns to glass: the body goes translucent first, the highlights last.
  • Shadows are the lens silhouette, blurred, under each bead.
  • Rods are thin cylinders: bamboo, brass or steel.
  • The beam is bevelled lacquered wood with faint grain, or metal, with small inset pins for the unit dots.
  • The board is grained wood with a lit and a shaded bevel, rounded corners and a soft diagonal sheen; the well inside it is darker, with an inner shadow cast by the frame and a vignette.

The shader works in linear light and encodes at the end for whichever target format egui uses, with premultiplied alpha, so its output blends exactly like egui’s own meshes.

Finishes

FinishFrameRods and beamBeads
Walnut (default)lacquered walnut, warm grainbamboobone
Ebonynear-black ebony, fine grainbrassbone
Maplepale maple, fine grainsteelslate

Each has a light and a dark variant.

Fallback

Without a wgpu render state, Abax logs a warning and draws the soroban with plain egui shapes.

Benchmarks

ABAX_BENCH=frames=400 ABAX_WINDOW=1200x800 ./target/release/abax

ABAX_BENCH=frames=N prints one line after N frames, leaving out the first 10:

ABAX_BENCH frames=390 rods=27 ui-pass avg/p95=… ms cpu-frame avg/p95=… ms frame period avg/p95=… ms

ABAX_BENCH=start prints the time from the top of App::new to the first frame. Both measure CPU time only.

Screenshot and capture modes

Captures come from the app itself, driven by environment variables (desktop only).

VariableEffect
ABAX_WINDOW=WxHWindow size in points, for example 1000x720 or 420x820.
ABAX_SHOT=<screen>:<file.png>Open <screen>, wait 40 frames, save a PNG, exit. The window is fixed-size and undecorated, so tiling window managers float it.
ABAX_SHOT=<screen>:<dir>/Sequence mode (the path ends in /): record 48 consecutive frames as frame-000.png … frame-047.png while the practice soroban runs a scripted set of moves.
ABAX_DEMO_DATA=1Fill the history and scheduler with two weeks of sample practice.
ABAX_DATA_DIR=<dir>Use the profile in <dir>; this is how a capture picks its theme and finish.
ABAX_BENCH=start or frames=NThe benchmarks above.

Screens for ABAX_SHOT: home, practice (4071583 on the beads), glass (the same, part-way through the anzan fade), lesson (lesson S3), lesson-gap (lesson S11, opened ahead of its prerequisite), drill (an S5 drill), stats, lessons, flash (the flash anzan setup), flash-run (a number mid-flash), settings. Anything else opens home.

ABAX_DEMO_DATA changes the profile it runs with; pair it with a throwaway ABAX_DATA_DIR. A capture in the dark theme with the ebony finish:

mkdir -p /tmp/abax-shot
echo '{"version":1,"settings":{"theme":"Dark","finish":"Ebony","rod_count":13}}' \
  > /tmp/abax-shot/profile.json
ABAX_DATA_DIR=/tmp/abax-shot ABAX_DEMO_DATA=1 ABAX_WINDOW=1000x720 \
  ABAX_SHOT=practice:practice-ebony-dark.png ./target/release/abax

The landing page’s hero loop is a sequence (empty, 4071583, 2958, 7310246), 48 frames cropped to the soroban at 20 frames per second:

mkdir -p shot/profile shot/frames
ABAX_DATA_DIR=shot/profile ABAX_WINDOW=1000x720 \
  ABAX_SHOT=practice:$PWD/shot/frames/ ./target/release/abax
# crop to the soroban, then encode the two formats the landing page uses
ffmpeg -framerate 20 -i shot/frames/frame-%03d.png -vf crop=976:370:12:118 \
  -pix_fmt yuv420p -c:v libx264 -crf 20 -movflags +faststart hero.mp4
ffmpeg -framerate 20 -i shot/frames/frame-%03d.png -vf crop=976:370:12:118 \
  -pix_fmt yuv420p -c:v libvpx-vp9 -b:v 0 -crf 30 -an hero.webm

Architecture for contributors

Two crates

crates/abax-core/     pure logic: no UI, no I/O, no randomness of its own
  soroban.rs          rods and the soroban: beads <-> digits <-> numbers
  moves.rs            the bead-move engine: the exact move list for adding or
                      subtracting a digit (complements, carry, borrow, finger order)
  arith.rs            multi-digit add/sub; multiplication and division as
                      narrated step sequences (Kojima's standard methods)
  curriculum.rs       the 15 skills, prerequisites, ladders, lesson text and demos
  generator.rs        drill items per skill and ladder step
  scheduler.rs        BKT, EWMAs, Elo, ladder rules, mastery, review, session plan
  stats.rs            history, momentum, chart series, session log
  store.rs            the versioned save document and its migration
crates/abax/          the eframe app: a binary on the desktop, a cdylib on Android
  lib.rs              App: screens, settings, autosave, capture and bench modes,
                      android_main
  main.rs             desktop entry point (window size, bench options)
  soroban_view.rs     the interactive soroban: hit testing, tap and drag,
                      spring animation, hints, building render instances
  render/             the wgpu paint callback (mod.rs) and its shader (soroban.wgsl)
  screens/            home, practice, lesson, drill, flash, picker, stats, settings
  keypad.rs           on-screen keypad and keyboard mapping
  theme.rs, ui.rs     palette, finishes, fonts; shared widgets
  charts.rs           the stats charts
  audio.rs            the synthesised click (desktop, cpal)
  storage.rs          data directory, atomic save, load with backup
android/              manifest, resources, build-apk.sh
packaging/            .desktop file, icon, install.sh, Info.plist, make-app.sh
docs/                 this manual, the landing page, the screenshots
research/             sources and the bead-move fixture tables
verify                the release gate

abax-core holds the rules and most of the tests. Randomness comes from the caller: generators take a dice closure, the scheduler a seeded xorshift generator.

Data flow

  1. Input. A tap, drag or key goes to SorobanView, which updates its Soroban model and animates the beads towards it.
  2. Checking. The active screen compares the model with the current Item (from generator::generate). Chain items follow the running total operand by operand; typed items compare the keypad buffer.
  3. Recording. DrillState::submit calls Scheduler::record(skill, correct, seconds, now), which updates that skill’s state and returns whether it stepped up, stepped down or became mastered, and appends an Attempt to History.
  4. Saving. The app marks itself dirty; within 5 seconds, and on exit, storage::save writes the whole SaveFile atomically.
  5. Planning. The home screen asks Scheduler::next_skill_to_learn for an untried lesson, otherwise Scheduler::plan_session for warm-up, focus and cool-down drills.

Adding a skill

  1. curriculum.rs: add a SkillId variant in teaching order and to SkillId::ALL; give it a code, name, short_name, prerequisites, base_difficulty, benchmark_seconds and a ladder; add its Lesson to LESSONS.
  2. generator.rs: generate its items in generate, and if it is a bead skill, give it a Constraint in constraint_for saying which rules it allows and which it must contain.
  3. The app: drill_kind_for in screens/drill.rs, the groups in screens/picker.rs, and the session start in App::start_pending_or if it needs a special mode.
  4. Tests already guard the shape: prerequisites must form a graph in teaching order with one root, and every skill needs a lesson and a ladder of at least three steps that starts untimed.

Old save files keep loading: Scheduler::fill_missing gives a new skill a fresh state. Do not rename existing variants: their names are the keys in the save file.

Adding a drill type

  1. generator.rs: an Item variant, with answer, prompt, operand_count and solution_steps (the moves a wrong-answer replay shows).
  2. stats.rs: a DrillKind variant, if the stats should tell it apart. Append it; variant names are stored.
  3. screens/drill.rs: how the item is set up on the soroban (setup_item), whether the answer is typed or worked on the beads (typed_answer), how many rods it needs (rods_needed) and what the replay shows (replay_steps_for).

Tests

The tests include:

  • the complete 10 × 9 addition and 10 × 9 subtraction tables from the research notes: for every digit on the rod and every digit added or subtracted, the exact move list, rule and order;
  • worked multiplication and division examples from Kojima, including division with revised quotient digits;
  • generators: every item for a skill uses that skill’s rule and nothing beyond it;
  • the scheduler: the BKT sequence, the EWMA sequences, U(n), Elo monotonicity, the mastery gate rejecting four lucky answers and slow answers, forgetting and the session planner choosing only skills on the suggested path or already met, adding a light review when a prerequisite is weak, and never failing on any mix of known, practised and skipped skills; “I know this” seeding 0.80 (not 1.0) and the per-skill reset;
  • save files: round trip, unknown fields ignored, missing fields defaulted, bad input an error rather than a crash; atomic write and backup on a damaged file.

Run them with cargo test --workspace, or the whole gate with ./verify. Bead-move changes must keep the full tables green.

Conventions

  • Clippy warnings are errors; cargo fmt decides formatting.
  • Western digits (0 to 9) in every string.
  • Palette, motion and interaction: docs/internals.md.
  • Captures live only in docs/screenshots/.

See CONTRIBUTING.md for how to propose a change.

Changelog

Unreleased

0.3.0 - 2026-10-11

Changed

  • Nothing is locked. Every lesson opens at any time from the lesson list, every skill can be picked in Drills and Sprint, and the stats bars show “new” instead of “locked”. Prerequisites are now recommendations: the list marks the suggested next lesson (“next”), Home’s Continue opens it, and a lesson whose prerequisites are not yet at 0.80 shows a small “Builds on: …” line with a link to each of them. The note appears once per lesson and never blocks.
  • The session planner chooses from skills on the suggested path plus every skill already practised or marked known, in any order. A focus skill with a weak prerequisite still runs; when no review is due, the warm-up becomes a light review of that prerequisite (5 untimed items).

Added

  • “I know this already” at the top of every lesson. It marks the skill as known, sets its knowledge estimate to 0.80 (the threshold, not 1.0, and never lower than an estimate already earned) and moves on to the suggested next lesson. Known skills are mixed into focus drills and cool-downs.
  • “Reset this skill” on a lesson marked known, and Settings > Data > Reset one skill for any skill. A skill with real practice asks for a second tap. History is kept.
  • Capture screen lesson-gap (lesson S11 opened ahead of its prerequisite) for ABAX_SHOT; the demo profile marks A1 as known.

Save file

  • Two additive fields: marked_known on each skill and builds_on_noted at the top level. 0.2 profiles load unchanged; the format version stays 1, so 0.2.x can still open a 0.3.0 profile.
  • Android versionCode 300.

0.2.1 - 2026-10-12

Fixed

  • macOS: the app opened as “Abax is damaged and can’t be opened”. make-app.sh now ad-hoc signs the finished Abax.app (codesign --force --deep --sign -), the release job signs the dmg too, and the job fails unless codesign --verify --deep --strict passes on the .app and on the copy inside the dmg. The app is still not notarized: the first launch needs right-click > Open (macOS 15 and later: Privacy & Security > Open Anyway) or xattr -cr /Applications/Abax.app. See docs/macos-gatekeeper.md.
  • Android versionCode 201.

0.2.0 - 2026-10-11

Rendering

  • The soroban is drawn by one wgpu paint callback: one pipeline, one instanced draw, shaded per pixel in WGSL. Beads are solids of revolution with a key light, specular highlight, rim darkening, contact occlusion and soft shadows; rods are shaded cylinders; the beam is bevelled lacquer with inset unit dots; the frame is grained, bevelled wood around a vignetted well.
  • Three finishes under Settings > Appearance, each tuned for light and dark: Walnut (bone beads, bamboo rods, the default), Ebony (bone beads, brass rods and beam) and Maple (slate beads, steel rods). Saves from 0.1.0 load as Walnut.
  • The anzan fade turns beads to glass: the body goes first, the highlights last.
  • The previous egui painter remains as a fallback when wgpu is unavailable.

Interface

  • Hints: a stronger vermilion halo and an outlined arrow with a shaft.
  • Bead moves settle on a critically damped spring; beads you move brighten briefly.
  • Flash anzan shows large numerals; the home screen carries a small live soroban.
  • Shared header, card, section and button styles across all screens.

Docs and site

  • A manual (mdBook) and a landing page with downloads for the latest release, published on GitHub Pages at https://zahakj.github.io/abax/.
  • New captures of every screen in light and dark, the three finishes, and a looping hero clip.
  • Screenshot mode can record a frame sequence (ABAX_SHOT=<screen>:<dir>/) and has glass and flash-run targets.
  • Contributing guide, code of conduct, security policy, issue and pull request templates.

Build and release

  • The Android build pins build-tools 35.0.0 and platform 35 (ABAX_BUILD_TOOLS, ABAX_PLATFORM).
  • Release notes are this file’s section for the tag.
  • The APK carries the workspace version: 0.2.0 is versionCode 200 and installs over 0.1.0 (versionCode 1).
  • A Pages workflow builds the site with a pinned mdBook 0.5.4.

0.1.0 - 2026-10-10

First release.

  • Soroban model and bead-move engine with every five- and ten-complement rule, carry and borrow, and Kojima’s finger-order rules; multiplication and division as step sequences.
  • Curriculum of 15 skills (S0-S11, A1-A3) with lessons (explanation, demonstration, guided practice), drills (set, read, chains, multiplication, division, mixed, 60 s sprint), anzan with fading beads and flash anzan.
  • Adaptive scheduler: Bayesian Knowledge Tracing per skill, accuracy and speed EWMAs, Elo-style item difficulty, mastery gate, session planner (warm-up, focus, cool-down), 14-day momentum instead of streaks.
  • egui/eframe app on wgpu: interactive soroban (tap, drag, keyboard), on-screen keypad, light and dark themes, stats charts, settings, synthesised bead click on desktop.
  • Versioned JSON profile written atomically.
  • Binaries for Linux, Windows and macOS; Android APKs (arm64 and universal) built without Gradle.

Roadmap

  • Sound on Android, through AAudio and the ndk crate.
  • Signed desktop builds: a notarized macOS app and a signed Windows binary.
  • More multiplication and division: decimals and Kojima’s rules for placing the point, longer multipliers and divisors, head-first methods.
  • Translations. Interface and lesson text live in curriculum.rs and the screens.
  • Dictated numbers (yomiage-zan).
  • A placement probe. The scheduler supports placing a learner from a short mixed test; there is no screen for it yet.
  • Faster flash steps. The ladders stop at 0.4 s per number for one digit and 0.5 s for three.

Suggestions go in GitHub issues.