Speaker ID ranges
The dialog system identifies every speaker by a numeric ID. The ID determines whether the game renders a full 3D character model or displays text without a portrait.
| Range | Type | Count | Rendering |
|---|---|---|---|
| 1000--1251 | Named villager NPCs | 252 | Full 3D scene (face mesh + texture + body) |
| 2000+ | System speakers | ~42 in DB | No portrait (narrator, crowd, announcements) |
NPC data files
All NPC data lives under data/npc/ (29 files total).
The files below are the ones most relevant to modding and translation.
NpcData.lzs
The master NPC database. LZS-compressed, contains NPC names as binary strings. This is where the translation patch writes English NPC names. The ROM ships with Japanese names; the patch overwrites them in the decompressed binary.
NpcDataOfs.ofs
252 SZL-packed personality records, one per named NPC (IDs 1000--1251). Each record decompresses to 88--200 bytes.
| Offset | Type | Field |
|---|---|---|
+0x00 | u8 | constant 0x00 |
+0x01 | u8 | personality_template (0--10, 11 distinct types) |
+0x02 | u16 | face_or_age (0--30, 31 distinct values; not a direct index into the face texture file) |
+0x04--+0x07 | 4 x u8 | body parameters (height, build, etc.) |
+0x08--+0x0b | 4 x u8 | clothing-layer IDs |
+0x0c onward | UTF-16 LE | JP NPC name (null-terminated) |
| after null | UTF-16 LE | greeting / quote |
Other NPC files
| File | Role |
|---|---|
NpcCstm.ofs | 140 customization parameter sets (1:1 with face textures). Controls per-NPC visual variations. |
NpcFas.npfs | NPC fashion / clothing data. |
NpcClothInfo.nci | NPC clothing info table. |
NpcSchedule.init | NPC daily schedule data. |
Personality types
The personality_template byte at offset +0x01
in each NpcDataOfs record determines an NPC's behavioral archetype.
There are 11 distinct personality types (values 0--10). The personality
type controls:
- Which dialog files the NPC draws from (
msg20--msg31each correspond to a personality grouping). - Whether the NPC's dialog renders as a bubble or a window (the personality type feeds into the
bubble_selselector in the dialog renderer). - Talk topic preferences and conversation style.
The personality system is what gives each NPC their characteristic way of speaking, even though many NPCs share the same underlying dialog templates.
Face textures and visual identity
Named NPCs are rendered in full 3D. There are no 2D portrait sprites. The face rendering pipeline uses three texture files:
| Path | Contents |
|---|---|
model/npc/tex/face/tfnpc.ofs | 140 face textures (base face meshes). 252 NPCs share 140 faces; individual identity comes from body parameters, clothing layers, and hair. |
model/npc/tex/face/tfnpccmn.ofs | 33 common face overlay textures (eyes, mouth positions, blush states). Composited at runtime to create expressions. |
model/npc/tex/face/tfnpcguest.ofs | 13 guest NPC face textures for special or temporary characters. |
The NpcCstm.ofs customization records (140 entries, 1:1 with
tfnpc.ofs) hold the per-NPC parameters that differentiate
NPCs who share the same base face.
NPC stamps
data/npcstamp/npcstamp.ofs contains 140 SZL-packed RGCN
entries. Despite the name, these are not NPC portrait images. They are
small personality stamp icons used on the rumor board and trend ranking
system. The shared palette and cell layout come from the sibling file
npcstpcmn.lzs, an RESC container with NCER at offset
0xa0 and NCLR at offset 0x110.
Special character paths
Not all characters go through the villager personality system. Special
characters like the principal, teachers, and shopkeepers use separate
dialog paths that bypass the personality-based bubble/window selector.
Their dialog routing is hardcoded in the ARM9 binary rather than driven
by the NpcDataOfs personality_template byte.
NPC names in the translation
The translation patch updates NPC names in two places:
- NpcData.lzs -- the master binary that the game reads at runtime for display names.
- The
npc_namestable in the translation database -- the source of truth for canonical English names, which feeds the NpcData.lzs binary writer during ROM rebuild.
82 rows still have drift between the database canonical name and the binary. This is tracked internally but has not been fully reconciled.
Source
data/npc/-- 29 NPC data files in the ROM filesystemdata/npcstamp/-- stamp icon containermodel/npc/tex/face/-- face texture containers- NpcDataOfs record layout from binary analysis of decompressed SZL records