Tone is part of the word, and it changed how I built Asụsụ Ọma
Igbo has four words spelled akwa. Depending on the pitch your voice moves through, it's egg, bed, cloth or crying:
- àkwá, egg. The voice starts low and rises.
- àkwà, bed. Both syllables stay low.
- ákwà, cloth. The voice starts high and falls.
- ákwá, crying. Both syllables stay high.
Same four letters, four meanings. Tone isn't an accent laid over the word. It's part of the word, the way a vowel is.

I've been building Asụsụ Ọma, a free app for learning Igbo, and that one fact decided more of its architecture than anything else.
It rules out synthetic speech
The obvious way to give a language app audio is text to speech. For Igbo that produces confident nonsense. A synthesiser that has not learned the tone system will read akwa with whatever melody its English model suggests, and the learner memorises a word that means something else.
So every phrase in the app is a recording of a person. There are 1,385 of them so far, each tied to the exact line it belongs to. That's slower than generating audio and it's the only version of this that works.

Pronunciation guides have to come from somewhere
Every word in the app shows how it is said, syllable by syllable, with its tone marked: á-kwà for cloth. Mark it wrong and you've taught a different word.
So a script writes the marks, from two dictionaries: 3,350 entries from Kay Williamson's Dictionary of Ọ̀nịchà Igbo and 3,551 from Nkọwa okwu's open Igbo dictionary. What they don't cover, I mark by hand.
The build refuses to ship a word it can't explain
Any Igbo word in the app can be tapped for its meaning and pronunciation. That promise is easy to make and easy to break: add one example sentence containing a word nobody has defined, and the learner taps it and gets nothing.
So it's a test. Every tappable token in every line of the course is checked against the dictionary, and the build fails if one is missing. The dictionary is 733 entries and grows whenever a lesson needs a word it doesn't have.
This is the part I would keep if I built another language app tomorrow. The failure mode of language software isn't a crash. It's being wrong in a way that looks fine, and the only defence is to make the wrongness mechanical: a test that knows what the app has promised, and refuses the build when a new line breaks the promise.
Asụsụ Ọma is free, with no ads and nothing behind a payment. Please give it a try at asusuoma.com.