42 KiB
Growing Core — design
A core vocabulary that grows from one button to eighty without any word leaving the place it lives. It is our own: its words come from open research lists and spoken frequency, its layout from a stated rule and a solver, and no word, position, wording or name comes from Core First, Crescendo, Super Core, WordPower, Gateway, Essence or any other vendor set.
- Source:
data/growing-core.yaml(what is in the set and when it appears),data/growing-core.layout.yaml(where everything sits, solved once and reviewed),data/lexicon.en.yaml(every word's class and sense). - Output: one
.obzpackage per size (growing-core-<size>.obz), plus two hide-and-reveal examples. Packages are not committed:catalog.pybuilds them wherever they are served (the site's build, into/app/models/pagesets/, each named by its content), and aac-core's tests build them for themselves. What is committed is the catalogue,aac-rs/data/pagesets/index.json, which names each package with its size and SHA-256 and is compiled into the app. - Check:
python3 tools/pagesets/build.py --check(the tables below),python3 tools/pagesets/catalog.py --check(the packages the sources build are the ones the catalogue names; the site's build runs it and fails otherwise), andcargo test -p aac-core --test pagesets. - Rebuild:
python3 tools/pagesets/build.py(the tables),catalog.py --write(the catalogue),build.py --out DIR(the packages, for a look); Python 3.11+ and PyYAML, no network. Re-solve the layout:python3 tools/pagesets/solve.py core, which reproduces the committed one byte for byte; any change to the design means re-solving, reviewing the grids, and committing the layout and the catalogue with it.
Tables between <!-- table:… --> markers are written by build.py from the
packages the sources build; do not edit them by hand.
1. How it grows
One point per word
Every item on the core lives at one point (v, u) of the screen, v down and u across, each from 0 to 1. On any grid R × C it is drawn in the cell that contains its point: row ⌊v·R⌋, column ⌊u·C⌋. So:
- A word's place at every size is a function of its point alone. Nothing about growing to a bigger grid can move it anywhere else.
- Every button a word has, at every size, contains the same point. A word learned at 3×3 in the top right is in the top right at 8×10, and the motor plan of reaching for it carries over.
- On any grid a word is at most half a cell (of that grid) from its point, so between two sizes its button moves less than one cell of the smaller grid.
The ladder is 1×1, 1×2, 2×2, 2×3, 3×3, 3×4, 4×5, 5×6, 6×8, 7×9, 8×10 (eleven sizes; 1×1 and 1×2 are both there, for a first switch-like button and a first choice).
Stages, and a board that is full at every size
Each item has a stage, the first size at which it appears. The number of items per stage is exactly the growth in cells — 1, 1, 2, 2, 3, 3, 8, 10, 18, 15, 17 = 80 — and no two items whose stages have been reached ever fall in one cell. Together those make every board full at every size, and mean nothing that appeared at a smaller size is ever pushed out at a larger one.
Points are not free. Going from 6×8 to 7×9 merges cells of an 8×10 grid that
6×8 keeps apart (rows 3–4 and columns 4–5 of 8×10 fall in one 7×9 cell, but in
four 6×8 cells), so no layout that puts words on 8×10 cell centres can keep
every size full: that was the first design, and it is provably impossible. The
fix: a word lives in an atom, one rectangle of the common refinement of all
eleven sizes' cell boundaries (22 × 26 atoms), which never straddles a cell
boundary of any size. pslib/grid.py has the rule; pslib/solve.py the
search.
The first boards are designed; the rest is solved
The boards a beginning communicator sees first are designed by hand, as
anchors in growing-core.yaml, and the solver must keep them exactly:
1x2: stop | more
2x2: go | more 2x3: go | like | more
stop | help stop | not | help
3x3: I | want | more 3x4: I | you | want | more
go | like | all done what | go | like | all done
stop | not | help stop | that | not | help
4x5: I | you | want | more | Social ▸
what | go | like | all done | Food ▸
it | look | yes | no | in
stop | that | not | help | up
Why these:
- 1×1 "more" and 1×2 "stop | more": a request to continue and a way to end. Both are in Universal Core, and "more" is in Banajee et al. (2003); they work in every activity, which is the point of a first word (Project Core's principle: core words usable everywhere, no nouns).
- 2×2 adds "go" and "help": starting something, and asking for a person.
- 2×3 adds "like" and "not": a comment and its negation.
- 3×3: the top row reads as a sentence, "I want more"; each word added since 2×2 stayed in the region it had.
- 3×4 adds "you", "that" and "what": the other person, pointing, asking.
- 4×5 adds yes/no side by side in the middle, "it", "look", two place words, and the first two pages — Social (greetings and repairs) and Food — on the right edge, where every page key will be.
Each anchor fixes a rectangle of points; their intersection, for every word, is non-empty (the solver refuses anchors that contradict each other).
From 5×6 on, the solver places the remaining 60 items in their regions:
Fitzgerald Key order left to right, as in an English sentence — questions,
people, actions, describing words, little words and place words — with
yes/no/not near the top and every page key on the right edge (regions in the
design). A region is a target, weighted more for items that appear earlier
(they appear at more sizes); the hard rules are the anchors and fullness.
| Stage | New | Words (U: Universal Core, B: Banajee et al. 2003, #: spoken rank) |
|---|---|---|
| 1x1 | 1 | more (U, B, #103) |
| 1x2 | 1 | stop (U, #151) |
| 2x2 | 2 | go (U, B, #42); help (U, B, #132) |
| 2x3 | 2 | like (U, #39); not (U, #25) |
| 3x3 | 3 | I (U, B, #2); want (U, B, #56); all done (U, B, #–) |
| 3x4 | 3 | you (U, B, #1); that (U, B, #8); what (U, B, #12) |
| 4x5 | 8 | it (U, B, #6); yes (B, #73); no (B, #24); up (U, #48); in (U, B, #11); look (U, #78); Social ▸; Food ▸ |
| 5x6 | 10 | do (U, #22); make (U, #106); get (U, #40); put (U, #161); open (U, #323); turn (U, #332); on (U, B, #19); good (U, #67); People ▸; Feelings ▸ |
| 6x8 | 18 | all (U, #33); can (U, #30); different (U, #393); same (U, #229); he (U, #16); she (U, #41); here (U, B, #37); some (U, B, #93); when (U, #74); where (U, #82); who (U, #68); why (U, #69); my (B, #18); eat (#353); play (#316); out (B, #46); Places ▸; Actions ▸ |
| 7x9 | 15 | is (B, #10); will (#61); see (#65); have (#20); need (#99); me (#14); your (#21); we (#13); they (#38); the (B, #3); a (B, #5); and (#7); to (#4); off (B, #121); Things ▸ |
| 8x10 | 17 | this (#15); know (#29); come (#54); now (#51); again (#145); there (#36); back (#77); little (#113); with (#31); for (#17); of (#9); down (#105); don't (#28); how (#59); Describe ▸; Time ▸; Word forms ▸ |
The boards at every size (▸ opens a page):
1x1
| more |
1x2
| stop | more |
2x2
| go | more |
| stop | help |
2x3
| go | like | more |
| stop | not | help |
3x3
| I | want | more |
| go | like | all done |
| stop | not | help |
3x4
| I | you | want | more |
| what | go | like | all done |
| stop | that | not | help |
4x5
| I | you | want | more | Social▸ |
| what | go | like | all done | Food▸ |
| it | look | yes | no | in |
| stop | that | not | help | up |
5x6
| I | you | good | want | more | Social▸ |
| what | go | get | like | all done | Feelings▸ |
| turn | put | do | yes | on | Food▸ |
| it | that | look | no | in | People▸ |
| open | stop | make | not | help | up |
6x8
| where | he | you | good | want | all | more | Social▸ |
| why | I | my | get | some | same | Feelings▸ | Actions▸ |
| what | when | go | do | like | different | all done | Food▸ |
| who | turn | put | look | yes | on | in | People▸ |
| it | stop | that | eat | not | no | help | Places▸ |
| she | open | can | make | play | here | up | out |
7x9
| where | he | you | is | want | all | more | the | Things▸ |
| why | I | my | get | good | some | same | Feelings▸ | Social▸ |
| what | me | go | do | like | different | all done | a | Actions▸ |
| who | when | they | will | see | yes | on | and | Food▸ |
| it | turn | put | look | eat | need | to | in | People▸ |
| we | stop | that | make | not | no | help | up | Places▸ |
| she | open | your | can | have | play | here | out | off |
8x10
| where | he | don't | is | back | want | all | the | Word forms▸ | Things▸ |
| why | I | you | again | good | some | same | more | for | Social▸ |
| what | know | my | go | get | like | down | all done | Feelings▸ | Actions▸ |
| how | when | me | do | see | now | different | a | Time▸ | Food▸ |
| who | turn | they | put | will | yes | there | on | and | People▸ |
| we | it | come | look | eat | need | no | to | in | Describe▸ |
| this | stop | that | make | have | not | of | help | up | Places▸ |
| she | open | your | can | little | play | with | here | out | off |
Hide and reveal at a fixed size
Location-centred growth — start at the largest grid a person can see and
reach, show a few words, reveal more over time — needs nothing new: a word's
reveal step is its stage. A person on the 8×10 board "at the 3×3 stage" sees
exactly the nine 3×3 words, each in the region it had at 3×3, and every other
cell hidden in place (SPEC §3 item 3, §3.1 item 3). Revealing the next stage
shows the three 3×4 words, then the eight of 4×5, and so on. Every button carries its stage
(ext_aurasense_pageset.stage), so the app reveals any stage without another
file: the chooser's "Start with fewer words on a bigger board" picks a size
and a stage, and aac_core::pagesets::reveal sets Cell.hidden from each
button's stage before the boards are added (the test holds it to the
generator's own reveal packages, two of which ship as examples for other OBF
apps). Track B's "Show hidden words for now" shows every word in its place
and hides them again; Edit mode reveals a word for good.
2. The words
Sources
Only open sources, each cited in sources/catalog.yaml and in every package's
manifest:
- Universal Core (UNC CLDS; CC BY 4.0 per UNC, CC BY-SA 4.0 per Project Core — treated as BY-SA): all 36 words are on the core by 6×8 ("finished" as "all done", the app's word that has a gloss and a symbol). Its symbols and its 6×6 layout are not used.
- Banajee, DiCarlo & Buras Stricklin (2003), the 23 words all 50 toddlers used across activities: all but "mine" on the core by 7×9 ("mine" is on People).
- Spoken frequency: FrequencyWords 2018 (OpenSubtitles dialogue, CC BY-SA
4.0), the best open proxy for conversation; the first 5,000 words are
committed in
sources/. The "top N spoken" metrics use it with clitic fragments ('s, 't), disfluencies, abbreviations and profanity left out and contraction stems read as the contraction ("don" → "don't"). - The app's own
vocabulary.rs(which cites Banajee 2003, Cross et al. 2006 and Yorkston et al. 2010): word classes, which agree with the app's everywhere but one word (below). - Project Core (CC BY-SA 4.0): the principle for the small grids.
The app's English pack (wordfreq) is not used for choice: it mixes Wikipedia, news and books with speech, so "government" outranks "help".
Why a word is at its stage
Small sizes are built from Universal Core and Banajee words — usable in every activity, mostly verbs and little words, no nouns. Larger sizes add what speech needs most by spoken frequency: the pronouns (he, she, we, they, me, your), the copula and modals (is, will, can, have, need), articles and connectors (the, a, and, to, of, for, with). At 8×10, 24 of the 25 most-spoken words are on the core itself ("was" is on Word forms), and 86 of the top 100 are in reach, 54 of them on the core (table in §6). Function words come late on purpose: early communicators combine core words first, and the grammar words matter most once sentences do.
Colours (Fitzgerald Key)
The Fitzgerald Key (1954) is a public method. aac-core gives every word class
its colour (WordCategory::fitzgerald: the app's own defaults.rs hues,
with text that reads at 4.5:1 or more on each, tested): yellow people, green
actions, blue describing words, orange things, pink social words, white
questions, red negation, and brown for the little words — prepositions and
conjunctions, the key's "other" colour, which the app's editor calls "Little
words". The sets use light tints of those hues with a strong border of the
same hue and black text (contrast 13:1 or more on every tint), so colour
carries the class without carrying the legibility. The class itself travels as
ext_aurasense_word_class, so a high-contrast theme can recolour by class.
| Role | Words | Background | Border |
|---|---|---|---|
| people | pronouns, possessives, this/that, people | #FFF4C2 | #A67C00 |
| action | verbs | #DDF3D8 | #2E7D32 |
| describe | adjectives, adverbs, some/all, feelings, time | #DCEBFF | #1565C0 |
| thing | nouns, places | #FFE3C4 | #C25E00 |
| social | social words and messages | #FCE1EC | #AD1457 |
| question | what, where, who, when, why, how | #FFFFFF | #6A1B9A |
| little | prepositions, conjunctions, articles, endings | #EFE6E1 | #6D4C41 |
| negation | no, not, don't, can't, won't, didn't, never | #FFD9D9 | #C62828 |
| control | Back, Home | #E0E0E0 | #37474F |
Word classes written are the app's own names, conjunction among them
(added to aac-core with this work: "and", "but", "or", "because", "if", "so"
are conjunctions in vocabulary.rs now); adverbs are written as "adjective",
as vocabulary.rs does. Where these sets and vocabulary.rs differ:
| Word | These sets | The app's vocabulary.rs | Why |
|---|---|---|---|
| back | adjective | core_noun | back again, as in come back or give it back (not the body part, which is what the app's glosses of back are) |
| clean | verb | adjective | to clean (the verb) |
Senses
The app glosses a word by its English spelling, and its glosses were audited
in the sense vocabulary.rs gives each word (gloss_audit_2026-10-01). Every
word here is used in that sense; the lexicon records the sense of each
homograph ("right" = correct, "close" = shut, "can" = able to, "watch" = look
at, "orange" = the colour), and words whose meaning a gloss would get wrong are
left out ("mean", "kind", "light", "well" as an adverb).
"Back" as in "come back" (the 77th most-spoken word) joins the core at 8×10,
in place of "big" (which is on Describe). Its glosses are the body part,
so its cell carries sense (aac-core Cell::sense, OBF ext_aurasense_sense):
its words are English only, never glossed, and in another language it is
hidden in place until someone gives it a word (§4). It may sit on a page
beside the Back control because the control has no words on screen: the app
draws it as its arrow, with the control's word as its accessible name
("Go back", or the word in the person's language).
Symbols
Every button names the symbol the app draws for it (Mulberry first, then
OpenMoji, then Bliss — the app's lookup_for_cell); the test checks each one
resolves in the app's index and is the one the app draws. Page keys whose
label is not a concept show an exemplar's picture (key_symbols), written as
Track B's ext_aurasense_symbol. No symbol id is invented. These words and
messages have no symbol yet (they show their words; adding them is the
symbol track's work):
+'s, +ed, +ing, +s, ?, already, am, an, are, as, at, been, by, can't, could, did, didn't, does, excuse me, from, good morning, good night, got, had, has, hey, him, how are you, I don't feel good, I don't like it, I feel good, I like it, I need a break, I need help, I'm not finished, jump, let me think, let me try, man, mine, my turn, nervous, never mind, not +, of, oh, ouch, said, say it again, see you later, slow down, something, talk, that's not what I meant, them, then, uh oh, us, was, well, went, were, will +, won't, would, yay, yeah, your turn (68)
3. Pages of more words
Ten pages, opened from keys on the right edge of the core: Social, Food (from 4×5), People, Feelings (5×6), Places, Actions (6×8), Things (7×9), Describe, Time and Word forms (8×10). A page is the size of the core it opens from (the same target size and motor scale), and grows by the same rule: its words, in priority order, appear at its first size and then in their own places as it grows. Cells left over at the larger sizes stay empty, for the person's own words (Track B's editor places a new word only in an empty cell, so space must be left on purpose).
| Page | Opens from | Words | First words (they appear at the page's first size) |
|---|---|---|---|
| Social | 4x5 | 37 | hi, bye, please, thank you, wait, I'm not finished, that's not what I meant, sorry, okay, I don't know, say it again, how are you, … |
| Food | 4x5 | 30 | eat, drink, food, water, milk, juice, snack, hungry, thirsty, breakfast, lunch, dinner, … |
| People | 5x6 | 38 | mom, dad, friend, teacher, he, she, we, they, me, my, your, brother, … |
| Feelings | 5x6 | 29 | feel, happy, sad, angry, scared, tired, sick, hurt, good, bad, excited, bored, … |
| Places | 6x8 | 19 | home, school, outside, inside, bathroom, bedroom, kitchen, park, store, playground, pool, beach, … |
| Actions | 6x8 | 78 | come, think, take, tell, say, love, give, find, work, wait, call, talk, … |
| Things | 7x9 | 56 | toy, ball, book, game, music, TV, phone, picture, car, bed, chair, table, … |
| Describe | 8x10 | 68 | big, little, hot, cold, good, bad, new, old, fast, slow, different, same, … |
| Time | 8x10 | 30 | now, later, today, tomorrow, yesterday, morning, afternoon, night, day, week, year, time, … |
| Word forms | 8x10 | 22 | +s, +ed, +ing, will +, +'s, not +, ?, is, am, are, was, were, … |
The price of the rule on pages: at 8×10 a page with 30 words spreads them over the whole board with gaps between, because each stays in the region it had at 4×5. A packed page would read faster but move every word when the person moves up a size. The words people say most are on the core, not on pages, so this design keeps the rule everywhere; see the decisions below.
A Back cell on every page
Every page has Back in the top-left corner, at every size; it goes to the core. The app already offers Back, Home and Help beside the board, scanned and dwelt on (SPEC §5.6), so a page does not need its own Back to be escapable. It has one anyway, for four reasons:
- Scanning cost. The navigation is scanned after the board by default, so leaving a page by it costs a full pass of the rows first; the top-left cell is the first a row-column scan reaches (2 steps).
- One place, every page. The way back is in the same place on every page and every size: a motor plan of its own.
- Open Board Format. The sets are for any OBF app; most do not scan or dwell on their own back button.
- Paper. A printed page needs its way back on the page.
It costs one cell per page. The top-left corner is the worst place for a webcam
gaze user (the edge), who has the navigation bar instead. It is drawn as its
arrow (the app's nav:back symbol, mirrored in right-to-left languages), with
no words on screen; its accessible name is the control's word in the person's
language where both readers agreed on it (aac-core/src/nav_labels.json),
"Go back" otherwise — never the gloss of "back", which is the body part (SPEC
§5.6 item 5). The navigation words moved from aac-web into aac-core with this
work, so the app and its Open Board Format export share them: Back and Home
cells are exported with the control's word in every language, never a gloss.
Social messages
Greetings (hi, bye, how are you, see you later, good morning, good night), politeness (please, thank you, sorry, excuse me, you're welcome), feelings as messages (I feel good, I don't feel good, I like it, I don't like it, I love you), turn-taking (my turn, your turn, let me try, let me think) and repairs first: wait, I'm not finished, that's not what I meant, say it again, I don't know, never mind, slow down, I need a break, I need help. Wait, I'm not finished, that's not what I meant, say it again and I don't know are among the page's first nineteen words, so they are there from 4×5; the rest of the repairs come at 5×6. These speak at once like any cell; a message bar that would let them skip the message (a "say now" action) is a Track B/C decision, not a page-set one.
Word forms
What the app has today: grammar endings that act on the last word of the
message (GrammarModifier: +s, +ed, +ing, will, 's, not, ?), English-regular
only (D11). The Word forms page (8×10) has those seven and, until irregular
forms exist, the irregular forms people say most as whole words: is, am, are,
was, were, be, been, has, had, did, does, didn't, got, went, said.
Where the endings get the sets' own words wrong (the lexicon records the right
form for every word whose ending is irregular or changes its spelling; this
table is computed against the app's apply_modifier):
| Word | Ending | The app says | Correct |
|---|---|---|---|
| be | present-progressive | bing | being |
| bring | past | bringed | brought |
| build | past | builded | built |
| buy | past | buyed | bought |
| carry | past | carryed | carried |
| catch | past | catched | caught |
| choose | past | choosed | chose |
| come | past | comed | came |
| cut | past | cuted | cut |
| cut | present-progressive | cuting | cutting |
| do | past | doed | did |
| draw | past | drawed | drew |
| drink | past | drinked | drank |
| drive | past | drived | drove |
| eat | past | eated | ate |
| feel | past | feeled | felt |
| find | past | finded | found |
| fish | plural | fishes | fish |
| foot | plural | foots | feet |
| forget | past | forgeted | forgot |
| forget | present-progressive | forgeting | forgetting |
| get | past | geted | got |
| get | present-progressive | geting | getting |
| give | past | gived | gave |
| go | past | goed | went |
| have | past | haved | had |
| hear | past | heared | heard |
| hold | past | holded | held |
| hug | past | huged | hugged |
| hug | present-progressive | huging | hugging |
| hurt | past | hurted | hurt |
| keep | past | keeped | kept |
| know | past | knowed | knew |
| leave | past | leaved | left |
| let | past | leted | let |
| let | present-progressive | leting | letting |
| lose | past | losed | lost |
| make | past | maked | made |
| man | plural | mans | men |
| pay | past | payed | paid |
| put | past | puted | put |
| put | present-progressive | puting | putting |
| read | past | readed | read |
| ride | past | rided | rode |
| run | past | runed | ran |
| run | present-progressive | runing | running |
| say | past | sayed | said |
| see | past | seed | saw |
| see | present-progressive | seing | seeing |
| send | past | sended | sent |
| sing | past | singed | sang |
| sit | past | sited | sat |
| sit | present-progressive | siting | sitting |
| sleep | past | sleeped | slept |
| stand | past | standed | stood |
| stop | past | stoped | stopped |
| stop | present-progressive | stoping | stopping |
| swim | past | swimed | swam |
| swim | present-progressive | swiming | swimming |
| take | past | taked | took |
| teach | past | teached | taught |
| tell | past | telled | told |
| think | past | thinked | thought |
| throw | past | throwed | threw |
| try | past | tryed | tried |
| understand | past | understanded | understood |
| wake up | past | wake uped | woke up |
| wake up | present-progressive | wake uping | waking up |
| win | past | wined | won |
| win | present-progressive | wining | winning |
| worry | past | worryed | worried |
| write | past | writed | wrote |
Plan for irregular forms (UniMorph):
- Data: per language, a table lemma → {feature bundle → form}, from UniMorph (https://github.com/unimorph; English is CC BY-SA 3.0, adaptable under 4.0; check each language's licence, most are Wiktionary-derived). Ship only the lemmas of the person's vocabulary (a few thousand rows per language), content-hashed beside the language packs.
- Mapping:
GrammarModifier→ UniMorph features — Plural → N;PL, PastTense → V;PST, PresentProgressive → V;V.PTCP;PRS (English adds "be"), FutureTense → V;FUT where the language inflects it (Spanish irá) and the periphrasis where it does not (English will), Possessive → the language's own construction. Fall back to today's regular rule only where the table has no row, and say so. - A Word Forms page that re-inflects the last word: show that word's forms from the table as cells (went, gone, going, goes), so a person picks the form instead of an ending; the endings stay for words the table lacks.
- The lexicon's
formshere become the English test vectors. - Order: English plus the ten largest languages first, as the gap report says (§4 item 16).
4. Languages
The sets are English (ValidatedNativeCorpus). In every other language the
app shows its glosses of the English words: GlossOnly (SPEC §4.1), never
that language's core vocabulary, and the chooser says so before a set is
added, with the share of the set's words that have words in the language.
On these sets, a word with no word in the person's language is hidden in
place (SPEC §4.1 item 4, proposed): they are made to be glossed, and their
cells carry ext_aurasense_pageset. Nowhere else is a word hidden for want of
a gloss: the app's own boards, the person's own and imported boards and the
phrase sets show such a word in English, marked lang="en" and said by an
English voice (aac-web translate::cell_words).
The gaps are mostly English function words that many languages do not have as
words ("is", "the", "of", "and"), which is exactly why a gloss is not a core;
and the social messages, which have no whole-phrase glosses yet. In Edit mode
such a cell shows "No Spanish word yet" (in the language's name) over its
English key, so a partner can give it their own words there (Track B's lang:
the person's own words, never glossed); showing hidden words for now does not
show it, since there is nothing to show. A page key is never blank: with no
name of its own in the language it shows the name of the board it opens
there, else its English name, marked as English (lang="en", said by an
English voice) — hiding is for words, never for the way around. build.py --out writes languages.json:
per language, every word and message without a gloss, the page keys without a
name, the control words, and the work needed.
| Code | Language | Core status | Prediction pack | Growing Core words glossed | Fixed Paths words glossed | Published native core list exists |
|---|---|---|---|---|---|---|
| en | English | ValidatedNativeCorpus | multi_source | source | source | – |
| es | Spanish | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| fr | French | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| de | German | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| pt | Portuguese | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| it | Italian | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| nl | Dutch | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| zh | Chinese (Simplified) | GlossOnly | multi_source | 90% (82% by use) | 88% (78% by use) | yes |
| ja | Japanese | GlossOnly | multi_source | 89% (78% by use) | 88% (75% by use) | |
| ko | Korean | GlossOnly | single_source | 89% (78% by use) | 88% (75% by use) | yes |
| ar | Arabic | GlossOnly | multi_source | 89% (82% by use) | 88% (78% by use) | yes |
| he | Hebrew | GlossOnly | multi_source | 89% (81% by use) | 87% (78% by use) | yes |
| ur | Urdu | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| fa | Persian | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| hi | Hindi | GlossOnly | multi_source | 90% (82% by use) | 88% (78% by use) | |
| bn | Bengali | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| ta | Tamil | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| te | Telugu | GlossOnly | single_source | 90% (87% by use) | 88% (83% by use) | |
| ml | Malayalam | GlossOnly | single_source | 90% (87% by use) | 88% (83% by use) | |
| mr | Marathi | GlossOnly | sparse | 90% (87% by use) | 88% (83% by use) | |
| kn | Kannada | GlossOnly | none | 90% (87% by use) | 88% (83% by use) | |
| gu | Gujarati | GlossOnly | none | 90% (87% by use) | 88% (83% by use) | |
| pa | Punjabi | GlossOnly | single_source | 90% (87% by use) | 88% (83% by use) | |
| th | Thai | GlossOnly | single_source | 90% (87% by use) | 88% (83% by use) | |
| vi | Vietnamese | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| id | Indonesian | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| ms | Malay | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| tl | Filipino | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| ru | Russian | GlossOnly | multi_source | 89% (76% by use) | 87% (73% by use) | |
| pl | Polish | GlossOnly | multi_source | 90% (82% by use) | 88% (78% by use) | |
| uk | Ukrainian | GlossOnly | multi_source | 90% (82% by use) | 88% (78% by use) | |
| ro | Romanian | GlossOnly | multi_source | 90% (82% by use) | 88% (78% by use) | |
| cs | Czech | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| sv | Swedish | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| da | Danish | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| nb | Norwegian | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| fi | Finnish | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| sw | Swahili | GlossOnly | single_source | 90% (87% by use) | 88% (83% by use) | |
| am | Amharic | GlossOnly | sparse | 90% (87% by use) | 88% (83% by use) | |
| ha | Hausa | GlossOnly | sparse | 90% (87% by use) | 88% (83% by use) | |
| yo | Yoruba | GlossOnly | sparse | 90% (87% by use) | 88% (83% by use) | |
| zu | Zulu | GlossOnly | sparse | 89% (79% by use) | 87% (75% by use) | |
| tr | Turkish | GlossOnly | multi_source | 89% (80% by use) | 88% (76% by use) | |
| el | Greek | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) | |
| hu | Hungarian | GlossOnly | multi_source | 90% (87% by use) | 88% (83% by use) |
Every one of the 44 needs native core-vocabulary work before its set is
that language's core: a list from its speakers (SPEC §4.1
StakeholderValidated or ValidatedNativeCorpus), laid out by the same rule.
Order of work:
- Korean, Chinese, Hebrew, Arabic: a published native core list exists
(cited in
vocabulary.rsCORE_COVERAGE_EVIDENCE); adopt it where its licence allows. Korean counts morphemes, not words: its core will not be a word-for-word grid. - Languages with the largest gaps by use (Japanese, Korean, Russian at 72–75% of spoken use glossed; Chinese, Hindi, Romanian, Turkish at 75–78%): the missing words are grammar the language expresses differently (particles, case, no articles).
- Kannada and Gujarati (no prediction pack), Amharic, Hausa, Yoruba, Zulu, Marathi (sparse packs): need frequency data before any core.
- Everyone: native review of the glosses (model-read only so far), and whole-phrase translations of the social messages.
5. How the app offers it
At setup ("Words to start with") and in Settings → Words and boards, the
catalogue's families sit beside the built-in sets (aac-web pagesets.rs,
components/panels/catalogue_sets.rs):
- What it is: the set's description, its sources and licence, and, when the person's language is not English, what that language gets (§4).
- The size: eleven buttons, each saying what it holds ("9 words", "18 words and 2 pages of more", …). When a size gives targets under the 10 mm a finger needs on this screen, the chooser says so with the measured size ("about 6 × 12 mm") and lets the person choose it anyway. (A browser does not say how big its screen is: the estimate takes the board's size in CSS pixels and a phone's, a tablet's or a desktop's millimetres per pixel, and says it is an estimate.)
- "Start with fewer words on a bigger board": a size and the stage whose words show first; the rest are hidden in their places, and Track B's "Show hidden words for now" (partner menu and edit bar, scanned) shows them.
- Adding downloads the package the first time only (from
/app/models/pagesets/, checked against the catalogue's size and SHA-256, then kept in IndexedDB — never Cache Storage, which iPad Safari evicts — so the set can be added again offline), imports it with fresh ids (another copy is another set), and adds its boards beside the person's as one change Undo takes away (editing::add_boards_as_page_set). At setup on a first start it replaces the unused defaults, as the built-in sets do. - Supported navigation below 3×3: the 1×1 to 2×3 boards have no pages; the partner changes size from the chooser.
- What the import says is shown, as for any import (SPEC §8): the
status line in Settings, a notice after setup. Each board's licence is
kept with it (
aac_board_licenses), so an export re-shares it with its attribution.
The chooser is the catalogue's, not these two sets': any family a
generator in generators.json writes appears in it. A family with a
package per language (the phrase sets) is resolved by
aac_core::pagesets::Family::for_person(size, variant, lang, speaker_form):
the person's language (the exact tag, then its base), and where its words
change with the speaker's gender ("cansado" / "cansada") their speaker form —
never assumed: with none it returns Pick::AskSpeakerForm, and
Family::speaker_form_matters(lang) lets the chooser ask first — else the
glossed or English package. A family with one size shows no size to choose.
6. Metrics
What the sets reach at each size (words said directly; "top N spoken" from the subtitle list; Universal Core and Banajee counted when on the core itself):
| Size | Cells | Core words (1 hit) | Pages | Words in reach | Top 25 spoken | Top 50 | Top 100 | Top 200 | Spoken tokens covered | Universal Core on the core | Banajee on the core |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1x1 | 1 | 1 | 0 | 1 | 0/25 | 0/50 | 0/100 | 1/200 | 0% | 1/36 | 1/23 |
| 1x2 | 2 | 2 | 0 | 2 | 0/25 | 0/50 | 0/100 | 2/200 | 0% | 2/36 | 1/23 |
| 2x2 | 4 | 4 | 0 | 4 | 0/25 | 1/50 | 1/100 | 4/200 | 1% | 4/36 | 3/23 |
| 2x3 | 6 | 6 | 0 | 6 | 1/25 | 3/50 | 3/100 | 6/200 | 2% | 6/36 | 3/23 |
| 3x3 | 9 | 9 | 0 | 9 | 2/25 | 4/50 | 5/100 | 8/200 | 7% | 9/36 | 6/23 |
| 3x4 | 12 | 12 | 0 | 12 | 5/25 | 7/50 | 8/100 | 11/200 | 14% | 12/36 | 9/23 |
| 4x5 | 20 | 18 | 2 | 56 | 8/25 | 11/50 | 15/100 | 21/200 | 19% | 16/36 | 13/23 |
| 5x6 | 30 | 26 | 4 | 139 | 15/25 | 22/50 | 32/100 | 44/200 | 30% | 24/36 | 14/23 |
| 6x8 | 48 | 42 | 6 | 231 | 15/25 | 26/50 | 49/100 | 71/200 | 38% | 36/36 | 18/23 |
| 7x9 | 63 | 56 | 7 | 311 | 21/25 | 32/50 | 59/100 | 84/200 | 52% | 36/36 | 22/23 |
| 8x10 | 80 | 70 | 10 | 438 | 25/25 | 44/50 | 86/100 | 136/200 | 68% | 36/36 | 22/23 |
Frequency-weighted cost of saying a word, over the words in reach (hits: 1 on
the core, 2 on a page; scan steps: row-column from the top left; touch: Fitts'
index of difficulty from a hand resting below the board; gaze: distance from
the board's centre, 0–1 — definitions in pslib/costs.py and DESIGN-motor.md):
| Size | Hits per word | Row-column scan steps | Touch (Fitts ID, bits) | Gaze (eccentricity) |
|---|---|---|---|---|
| 1x1 | 1.0 | 2.0 | 0.665 | 0.0 |
| 1x2 | 1.0 | 2.638 | 0.892 | 0.354 |
| 2x2 | 1.0 | 2.585 | 1.416 | 0.5 |
| 2x3 | 1.0 | 3.316 | 1.221 | 0.45 |
| 3x3 | 1.0 | 2.711 | 1.878 | 0.576 |
| 3x4 | 1.0 | 3.255 | 1.816 | 0.553 |
| 4x5 | 1.046 | 4.381 | 2.259 | 0.628 |
| 5x6 | 1.297 | 7.905 | 3.122 | 0.764 |
| 6x8 | 1.301 | 9.708 | 3.437 | 0.741 |
| 7x9 | 1.178 | 9.97 | 3.318 | 0.686 |
| 8x10 | 1.268 | 12.306 | 3.786 | 0.73 |
Size of a cell (millimetres, width × height) after the app's message bar, suggestion row and navigation bar, against the app's own recommended minimums (touch 10 mm, switch 15 mm, head 18 mm, gaze 20 mm):
| Size | 10.2" tablet, landscape (mm) | tablet, portrait | 6.1" phone, portrait | phone, landscape | Meets on the tablet (landscape) | Meets on the phone (portrait) |
|---|---|---|---|---|---|---|
| 1x1 | 206×121 | 154×173 | 63×97 | 123×31 | touch, switch, head, gaze | touch, switch, head, gaze |
| 1x2 | 103×121 | 77×173 | 31×97 | 61×31 | touch, switch, head, gaze | touch, switch, head, gaze |
| 2x2 | 103×60 | 77×86 | 31×48 | 61×15 | touch, switch, head, gaze | touch, switch, head, gaze |
| 2x3 | 68×60 | 51×86 | 21×48 | 40×15 | touch, switch, head, gaze | touch, switch, head, gaze |
| 3x3 | 68×40 | 51×57 | 21×32 | 40×10 | touch, switch, head, gaze | touch, switch, head, gaze |
| 3x4 | 51×40 | 38×57 | 15×32 | 30×10 | touch, switch, head, gaze | touch, switch |
| 4x5 | 41×30 | 30×43 | 12×24 | 24×7 | touch, switch, head, gaze | touch |
| 5x6 | 34×24 | 25×34 | 10×19 | 20×6 | touch, switch, head, gaze | none |
| 6x8 | 25×20 | 19×28 | 7×16 | 15×5 | touch, switch, head | none |
| 7x9 | 22×17 | 16×24 | 6×13 | 13×4 | touch, switch | none |
| 8x10 | 20×14 | 15×21 | 6×12 | 12×3 | touch | none |
A 6.1-inch phone held upright holds the core up to 4×5 for touch (5×6 is a fraction of a millimetre under the 10 mm minimum); a 10.2-inch tablet in landscape holds every size for touch, and up to 5×6 for gaze.
Stability. For every core item present at two sizes:
- Pairs of sizes compared (an item present at both): 545.
- Mean shift of a button's centre: 0.111 of the board's width or height.
- Largest shift: 0.85 cells of the smaller board (
it, 7x9 → 8x10: 0.094 across, 0.045 down). Threshold: less than one cell of the smaller board — met. - Largest shift between neighbouring sizes of the ladder: 0.250 of the board.
- Every item's buttons, at every size, share one point of the screen: yes.
- Pages: Social ok; Food ok; People ok; Feelings ok; Places ok; Actions ok; Things ok; Describe ok; Time ok; Word forms ok.
The rule makes the one-cell bound hold by construction; the test checks it again on the imported boards.
7. Decisions (2026-10-05)
Taken by the coordinator for the founder, and reversible:
- Pages keep their words in place (gaps at the larger sizes), for a motor plan that never changes.
- A word with no word in the person's language is hidden in place on these glossed sets only; Edit mode says so, and a partner can give it their own words (§4). Elsewhere it is shown in English, marked.
- Conjunctions are a word class in aac-core, with the Fitzgerald Key's "other" colour (brown, white text at 7:1), as the app's "Little words".
- The navigation words live in aac-core, so the app and the Open Board Format export share them: Back and Home cells never carry a gloss.
- "Back", the word, has its place (on the core at 8×10), and the Back control is drawn as its arrow, named "Go back" or the control's word.
- Phones are not restricted: the chooser says when a size's targets come under 10 mm on the screen, with the measured size.
Still open: a gloss review by native speakers, and native core vocabularies (§4); the UniMorph plan (§3).