Pixel-Art-Oberflächen: Textboxen, Schriften und Japanisch
Die Dialogbox von Pokémon Smaragd ist ein Rahmen aus 30 mal 6 Tiles, über die volle Bildschirmbreite von 240 Pixeln und 30 % der Höhe, um ein Textfenster aus 27 mal 4 Tiles, das zwei Zeilen einer 16-Pixel-Schrift fasst; die von Kristall misst 20 mal 6 Tiles, zwei Zeilen zu 18 Zeichen.123 Smaragd druckt je nach Tempoeinstellung alle 8, 4 oder 1 Frames ein Zeichen, bei 60 Hertz also 7,5, 15 oder 60 pro Sekunde; die schnelle Einstellung von Kristall und Final Fantasy VI drucken ebenfalls ein Zeichen pro Frame.14 Die Autoren von Smaragd haben jede Zeile von Hand umbrochen: Über 24.100 Zeilen Skripttext ist die breiteste 208 Pixel breit, bei einem Fenster von 216 Pixeln, und keine läuft über.1 Eine japanische Pixelschrift, die den Standardzeichensatz abdeckt, zeichnet rund siebentausend Zeichen: JIS X 0208 umfasst 6.879, Misaki zeichnet sie alle in einer Zelle von 8 mal 8, PixelMplus10 alle bis auf drei Codepoints auf einem 10-Pixel-Raster, und der Produzent des Final Fantasy Pixel Remaster bezifferte die neue japanische Schrift seines Teams auf „around 7,500 characters“ (rund 7.500 Zeichen).5678 Auf meinem Mac zeichnete Core Text bei ausgeschalteter Schriftglättung die Pixel-TrueType-Schriften, deren Raster auf der Grundlinie sitzt und deren Vorschübe ganze Pixel sind (Misaki, PixelMplus10 und Press Start 2P), bei ganzzahligen Vielfachen ihres Rasters ohne ein einziges Teilpixel und dazwischen mit 19,4 % bis 82,2 % verschmierten Tintenpixeln; PixelMplus12, dessen Raster neben der Grundlinie liegt, Silkscreen mit vereinzelten Konturpunkten abseits des Rasters und DotGothic16 ohne jedes Raster kamen bei jeder gemessenen Größe mit Teilpixeln heraus, k8x12 bei jeder Größe, sobald seine Glyphen exakt platziert wurden; mit der voreingestellten Glättung des Zeichenkontexts waren selbst bei PixelMplus10 in seinen eigenen 10 Pixeln 178 von 272 Tintenpixeln Teilpixel.79 Bei 3× landet ein Em von 10 Pixeln nur bei einer der zwölf Body-Größen von iOS auf ganzen Gerätepixeln, bei 40 Punkt.710 Kiradex World setzt heute jedes Wort in der monospaced Systemschrift, spricht nur Englisch und gibt VoiceOver die Koordinaten der Lauftests.11 Also habe ich Boxen, Schriften und Tempi des Kanons an den Dekompilierungen gemessen, fünf japanische und zwei lateinische Pixelschriften unter Core Text vermessen und ein Briefing geschrieben: eine lizenzierte Schrift für beide Sprachen, Dynamic Type auf das Raster der Schrift gerundet, ein von der Schmiede gezeichneter Rahmen, zwei Zeilen und Seiten und eine Bühne, die VoiceOver beschreiben kann.
Kurzfassung
- Die Box ist das untere Drittel und zwei Zeilen. Der Dialograhmen von Smaragd misst 30 mal 6 Tiles (240 mal 48 Pixel, 30 % der Bildschirmhöhe) um ein Fenster aus 27 mal 4 Tiles mit zwei 16-Pixel-Zeilen; die Box von Kristall misst 20 mal 6 Tiles, 33 % der Höhe, zwei Zeilen zu 18 Zeichen, und die von Rot ebenso 20 mal 6. Die Box von Smaragd hat kein Namensfeld, und 934 seiner 14.412 Skriptabsätze (6,5 %) nennen den Sprecher im Text.12312
- Tempo ist eine Anzahl von Frames. Smaragd und Feuerrot brauchen 8, 4 oder 1 Frames pro Zeichen (7,5, 15 oder 60 pro Sekunde bei 60 Hertz) und einen Frame, solange A oder B gehalten wird, nachdem die Taste während des Drucks gedrückt wurde; Kristall und Rot warten 5, 3 oder 1 Frame (12, 20 oder 60); Final Fantasy VI zeichnet Felddialoge mit einem Buchstaben pro Frame, ohne Einstellung dafür (sein sechsstufiges Nachrichtentempo bestimmt, wie lange eine Kampfmeldung wartet). Der Weiterpfeil von Smaragd wandert von der Ruhelage aus um 0, 1, 2, 1 Pixel, ein Schritt alle 9 Frames, ein Zyklus von 0,6 Sekunden; das ▼ von Kristall blinkt im Wechsel mit dem Rahmentile.1131415164
- Fünf freie Schriften zeichnen bereits das Japanisch, das ein Spiel braucht. Misaki zeichnet alle 6.879 Zeichen von JIS X 0208 in 8 mal 8, jedes Kanji innerhalb von 7 mal 7; k8x12 in 8 mal 12; PixelMplus12 und PixelMplus10 zeichnen alle bis auf drei Codepoints bei 12 und 10 Pixeln; DotGothic16 zeichnet alle, aber auf keinem Pixelraster. Die Lizenz aus drei Sätzen für Misaki, k8x12 und PixelMplus erlaubt Nutzung, Vervielfältigung und Weitergabe „either commercially or noncommercially“ (kommerziell wie nichtkommerziell).5671718
- Eine Pixelschrift ist nur bei ganzen Gerätepixeln pro Schriftpixel scharf, und nur wenn die Datei sauber ist. Gemessen mit Core Text unter macOS 27.0, nicht auf einem iPhone, bei ausgeschalteter Schriftglättung: 0,0 % Teilpixel bei ganzzahligen Vielfachen eines Rasters, das auf der Grundlinie sitzt und ganze Pixelvorschübe hat (Misaki, PixelMplus10, Press Start 2P), 19,4 % bis 82,2 % dazwischen.7 Mit der voreingestellten Glättung des Zeichenkontexts waren bei PixelMplus10 in seinen eigenen 10 Pixeln 178 von 272 Tintenpixeln Teilpixel; das saubere Ergebnis bei ganzzahligen Vielfachen gilt also nur bei ausgeschalteter Glättung.9 Das Raster von PixelMplus12 liegt 0,39 Pixel unter der Grundlinie, und bei ausgeschalteter Glättung verschmiert es bei jeder Größe; der Kana-Vorschub von k8x12 mit 8,01 Pixeln verschmiert, sobald Glyphen exakt platziert werden.719
- Dynamic Type muss gerundet werden, nicht befolgt. Von den zwölf Body-Größen in iOS, 14 bis 53 Punkt, ist ein Em von 10 Pixeln bei 3× nur bei 40 Punkt ganzzahlig, ein Em von 8 Pixeln bei 16 und 40, ein Em von 12 Pixeln bei 16, 28 und 40. Apple verlangt, dass eine eigene Schrift die Verhaltensweisen der Systemschriften umsetzt, Dynamic Type eingeschlossen, und dass sich der Text einer App idealerweise um mindestens 200 Prozent vergrößern lässt.71020
- Japanischer Zeilenumbruch ist ohne Sprachkennung streng und mit Kennung locker. In Core Text unter macOS brach ein Absatz von 131 Zeichen ohne Kennung bei keiner gemessenen Breite so um, dass eine Zeile mit einem Zeichen aus der Zeilenanfangsliste der Messung begann, einer unvollständigen Liste, überwiegend aus Zeichen von JLREQ, sieben davon in ihrer Vollbreitenform; mit der Kennung
jabegann in Hiragino Sans, Misaki, PixelMplus und DotGothic16 bei 6 von 7 Breiten ein kleines Kana eine Zeile, die weniger strenge Regel, die die Anforderungen des W3C an japanisches Layout beschreiben.721 - Was das Kiradex bringt. Ein Briefing, kein Build: PixelMplus10 für jedes Wort, das über der Welt gezeichnet wird (von den beiden gemessenen Schriften mit Japanisch, sauberem Raster und ganzen Pixelvorschüben, Misaki und PixelMplus10, die größere), Größen gerundet auf ganze Gerätepixel pro Schriftpixel (16,67 Punkt bei der Standardgröße auf 3×-iPhones, 15 auf 2×), ein eigener, von der Schmiede gezeichneter Rahmen, zwei Zeilen und Seiten, eine Enthüllung mit 30 Zeichen pro Sekunde und eine schrittweise wandernde Marke, einzeilige Sprechblasen, bemessen für das schmalste iPhone, das der Simulator von iOS 27.0 aufführt, wenn seine Seiten keine Einzüge haben, eine Zeile, die nicht passt, geht in die Box, japanische Zeilen prüft jemand, der Japanisch spricht, und eine Bühne, die VoiceOver in Worten statt in Koordinaten beschreibt, jeweils mit einer Prüfung, die ein Skript, eine Logzeile oder eine Aufnahme bestehen oder verfehlen kann, bis auf eine manuelle VoiceOver-Prüfung.2211
1. Smaragd und Feuerrot: ein bildschirmbreiter Rahmen, zwei Zeilen, von Hand umbrochen
Diese Reihe hat mit der Welt begonnen und sich nach innen vorgearbeitet. Pixel-Art-Welten auf dem iPhone legte das Tile-System fest, das RealityKit-Rezept und eine Richtung für Text in einer Regel, „Text is art“ (Text ist Grafik), und einem Satz Plan: „m5x7 at integer multiples in a 24-by-24 nine-slice box, two lines, typewriter reveal, a two-frame advance arrow.“ (m5x7 in ganzzahligen Vielfachen in einer Nine-Slice-Box von 24 mal 24, zwei Zeilen, Schreibmaschinen-Enthüllung, ein Weiterpfeil mit zwei Frames.)23 Die Beiträge seitdem bauten den Sammler, die Gebäude, die Bewegung, das Eigenleben der Stadt, die Räume und die Wege. Der Text blieb bei diesem einen Satz. Dieser Beitrag misst, woher seine Zahlen stammen, findet vier Stellen, an denen der Welt-Beitrag falsch oder ungenau ist, und ergänzt, was ihm fehlte: Japanisch in 8, 10 und 12 Punkten, was Core Text tatsächlich mit einer Pixel-TrueType-Schrift macht, wie Dynamic Type und ein Pixelraster zusammenfinden, japanischen Zeilenumbruch und VoiceOver über einer RealityKit-Bühne.
Der Text von Kiradex World ist heute schlicht. Jedes Wort darin ist SwiftUI in der monospaced Systemschrift des Themes. Die Sprechblasen über den Köpfen der Sammler sind eine Zeile in der Caption-Rolle des Kits, fett, auf cremefarbenem Papier mit einem 2 Punkt breiten Tintenrand, sichtbar, solange die Zeile jünger als 4 Sekunden ist. Die Zeile des Ortes steht in einer cremefarbenen Textbox am unteren Bildschirmrand. Die App gibt es nur auf Englisch, die vorgegebenen Zeilen liegen auf Englisch auf dem Server, das Schild der Schmiede ist ein Brett von 12 mal 11 mit Tintengekritzel und ohne Buchstaben, und VoiceOver liest die Bühne als ein einziges Element, dessen Wert die Schrittspur der Lauftests ist.11242526272829 Abschnitt 10 enthält die Einzelheiten; das Briefing in Abschnitt 12 ist als Differenz dazu geschrieben.
Jede Pokémon-Zahl unten wurde an flachen Klonen der Dekompilierungen von pret gemessen, pokeemerald 731ad5b (1. Oktober 2026), pokefirered 037335f, pokecrystal 5beda23 und pokered d2704a6, mit einem einzigen Python-Skript, measure_gen_text.py, dessen Ausgabe daneben gespeichert ist; die Zahlen zu Final Fantasy VI stammen von einem zweiten Skript über die Disassemblierung everything8215/ff6. Beide laufen in Sekunden erneut, und die Anmerkungen nennen die Quelldatei hinter jeder Zahl.3014
Die Schriften
Smaragd deklariert seine Schriften in einer einzigen Tabelle, sFontInfos in src/text.c, jede mit einer maximalen Buchstabenbreite und -höhe in Pixeln. Die kleine Schrift misst 5 mal 12; die normale Schrift, die die Dialogbox verwendet, 6 mal 16; die kurze Schrift 6 mal 14, viermal deklariert (sie selbst und drei Kopien); die schmale Schrift 5 mal 16; die kleine schmale Schrift 5 mal 8; die fette Schrift 8 mal 8; und die Brailleschrift 8 mal 16 mit 8 Pixeln Zeilenabstand. Jede andere Schrift hat einen Zeilenabstand von 0: Die 16-Pixel-Zelle ist die Zeile.113
Die normale lateinische Schrift ist proportional. Über die charmap.txt des Spiels in gFontNormalLatinGlyphWidths in src/fonts.c indiziert, sind die Kleinbuchstaben a bis z im Mittel 5,77 Pixel breit, von 4 bis 6; die Großbuchstaben A bis Z und die Ziffern 0 bis 9 sind alle 6; Leerzeichen und Punkt 3 und das Ausrufezeichen 4.131 In laufendem Text ergibt das im Mittel 5,25 Pixel pro Zeichen, gemessen über jede Zeile des Spielskripts weiter unten.1
Tempo ist eine Anzahl von Frames
Das Texttempo ist in Smaragd eine Verzögerung in Frames. Die drei Tempi des Optionsbildschirms werden über sTextSpeedFrameDelays in src/menu.c auf Verzögerungen von 8 (langsam), 4 (mittel) und 1 (schnell) abgebildet. AddTextPrinter in src/text.c speichert die Verzögerung minus eins als Tempo des Druckers; der Drucker setzt seinen Zähler auf dieses gespeicherte Tempo, wenn ein Zeichen gedruckt wird, und zählt ihn um eins pro Frame herunter, und das nächste Zeichen wird im Frame nach dem Erreichen von 0 gedruckt. Ein Zeichen braucht also die Verzögerung selbst: 8, 4 und 1 Frames. Bei 60 Hertz sind das 7,5, 15 und 60 Zeichen pro Sekunde.1213 Diese Zählung ist meine Lesart des Zustandsautomaten des Druckers (AddTextPrinter und der Fall RENDER_STATE_HANDLE_CHAR in src/text.c), die das Skript per Assertion prüft, nicht ausführt.1 Der Game Boy Advance läuft nicht exakt mit 60 Hertz: GBATEK gibt seinen Frame als „Total 228 lines, 16.743 ms, 280896 cycles - ca. 59.737 Hz“ an (insgesamt 228 Zeilen, 16,743 ms, 280.896 Zyklen, etwa 59,737 Hz), davon 160 Zeilen sichtbar, jede 240 Punkte breit; die schnelle Einstellung liefert auf der Hardware also etwa 59,7 Zeichen pro Sekunde.3233
Das Halten einer Taste beschleunigt die langsameren Einstellungen. Ein neuer Druck auf A oder B, während die Verzögerung eines Zeichens herunterzählt, setzt in einer Nachricht, die das erlaubt (gTextFlags.canABSpeedUpPrint), hasPrintBeenSpedUp. Von da an prüft der Drucker JOY_HELD(A_BUTTON | B_BUTTON) && subStruct->hasPrintBeenSpedUp und setzt den Zähler, wenn das zutrifft, auf 0: ein Zeichen pro Frame, 60 pro Sekunde, die Rate der schnellen Einstellung selbst.131
Automatisch scrollender Text hat eine eigene Verzögerung. Ist gTextFlags.autoScroll aktiv, setzt der Drucker den Zähler auf 3 statt auf das gespeicherte Tempo, also 4 Frames pro Zeichen, außer in aufgezeichneten Kämpfen: Die Bedingung lautet if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED) && gTextFlags.autoScroll).131 Kampfmeldungen schalten das automatische Scrollen in Link-Kämpfen und aufgezeichneten Kämpfen ein, und der Skriptbefehl messageautoscroll schaltet es ein und erzwingt das mittlere Tempo.34 Die Verzögerung von 3 kann also für andere Kampffenster in Link-Kämpfen und für geskriptete Nachrichten mit automatischem Scrollen gelten und nie in aufgezeichneten Kämpfen, deren Nachrichten in dem Tempo gedruckt werden, das der Drucker erhalten hat: bei Kampfmeldungen das mit der Aufzeichnung gespeicherte Texttempo, außer in einem aufgezeichneten Link-Kampf, dessen Nachrichtenfenster wie in einem Link-Kampf 1 erhält.341 Nach meiner Lesart läuft der Zähler nur, solange das gespeicherte Tempo des Druckers über 0 liegt, und das Nachrichtenfenster eines Link-Kampfs erhält die Verzögerung 1, womit sein Text bei aktivem automatischem Scrollen bei einem Zeichen pro Frame bleibt.1334
Die drei Umbruchcodes tun drei verschiedene Dinge. \n setzt den Drucker in die zweite Zeile; \l wartet unter dem Weiterpfeil auf einen Tastendruck und scrollt die Box dann um eine Zeile nach oben; \p wartet ebenso, leert dann die Box und beginnt wieder oben.1335 Beim Scrollen bewegt sich die 16-Pixel-Zeile je nach Tempoeinstellung um 1, 2 oder 4 Pixel pro Frame nach oben (sWindowVerticalScrollSpeeds), ein Scrollvorgang dauert also 16, 8 oder 4 Frames.113
Texttempo in jedem gemessenen Spiel und die beiden vom Briefing vorgeschlagenen Einstellungen; gezeichnet von figures/make_figures.py aus den Messausgaben.
Der Pfeil
Ist eine Seite voll, wartet die Box unter einem kleinen Pfeil. Smaragd kopiert eine Pfeilzelle von 8 mal 16 an vertikale Versätze von { 0, 1, 2, 1 } Pixeln (sDownArrowYCoords) und zeichnet sie neu, wenn ihre auf 8 zurückgesetzte Verzögerung abläuft. Das ist ein Schritt alle 9 Frames und ein Zyklus von 36 Frames, 0,60 Sekunden bei 60 Hertz.113 Der Pfeil blinkt nicht; er wippt, durch drei Positionen und zurück.
Die Box und ihr Rahmen
Die Feldtextbox von Smaragd ist durch sStandardTextBox_WindowTemplates in src/menu.c definiert. Das Textfenster sitzt in Tile-Spalte 2, Zeile 15, und misst 27 mal 4 Tiles: 216 mal 32 Pixel, zwei Zeilen der normalen 16-Pixel-Schrift. Sein Rahmen, gezeichnet von WindowFunc_DrawDialogueFrame und vom Skript für dieses Fenster ausgewertet, reicht von Spalte 0 bis 29 und Zeile 14 bis 19: 30 mal 6 Tiles, 240 mal 48 Pixel, die volle Bildschirmbreite und 30 % seiner Höhe von 160 Pixeln.12
Dieser Rahmen ist kein Nine-Slice. LoadMessageBoxGfx lädt ihn aus message_box.png, einem Streifen von 56 mal 16 Pixeln, 14 Tiles, und der Rahmen wird aus acht Tile-Positionen gezeichnet, seine untere Reihe ist die obere, mit BG_TILE_V_FLIP vertikal gespiegelt.1362 Das Skript misst die Ausdehnung des Rahmens und die Größe des PNG; die Spiegelung ist aus den Füllaufrufen gelesen.1
Die vom Spieler wählbaren Rahmen gehören zu den anderen Fenstern: den Menüs und den Ja-Nein-Boxen. WINDOW_FRAMES_COUNT ist 20, und die zwanzig Rahmen sind PNGs von 24 mal 24 Pixeln, drei mal drei Tiles zu 8, geladen von LoadUserWindowBorderGfx anhand des Rahmentyps, den der Punkt FRAME des Optionsbildschirms speichert.136
Das korrigiert den Welt-Beitrag. Seine Regel 10 lautet „Pokémon Emerald’s text-window frame is a 24-by-24 image, three by three hardware tiles, which is a nine-slice“ (der Textfensterrahmen von Pokémon Smaragd ist ein Bild von 24 mal 24, drei mal drei Hardware-Tiles, also ein Nine-Slice).23 Die zwanzig Bilder von 24 mal 24 in graphics/text_window/ sind die wählbaren Rahmen der Menüfenster. Die Dialogbox, die Textbox, an die sich Spieler erinnern, wird aus dem 56 mal 16 Pixel großen message_box.png als Rahmen von 30 mal 6 Tiles mit gespiegelter Unterkante gezeichnet, nicht als Nine-Slice eines Bildes von 24 mal 24.136 Die Idee des Nine-Slice steht, und die Menüs nutzen sie; die Zuschreibung an die Dialogbox nicht.
Die beiden Dialogboxen als Tile-Raster, ohne Spielgrafik; gezeichnet von figures/make_figures.py, das jede Ausdehnung gegen measure_gen_text.out prüft.
Der Text wurde für die Box geschrieben
Um zu sehen, wie voll die Box wird, las das Skript jede Zeile des Skripttexts von Smaragd: 504 Dateien, die 36 aus data/text/*.inc und die scripts.inc der 468 Karten, 24.100 Zeilen ohne Platzhalter und 3.000 mit einem, getrennt an den drei Umbruchcodes des Spiels, \n, \l und \p. Die Zeile im Median hat 29 Zeichen und 150 Pixel; das 95. Perzentil 38 Zeichen und 196 Pixel; die längste 53 Zeichen, die breiteste 208 Pixel. Keine ist breiter als das 216-Pixel-Fenster, und das durchschnittliche Zeichen ist 5,25 Pixel breit.137
Bei 5,25 Pixeln pro Zeichen fasst das Fenster 41; die Autoren hörten bei 95 % der Zeilen bei 38 auf.331 Jeder Umbruch ist ein von Hand gesetzter Code. Das Spiel bricht nie selbst um; es vertraut dem Autor.
Die Box hat ein Fenster und kein Namensfeld. Wollten die Autoren einen Sprecher, tippten sie den Namen und einen Doppelpunkt in die Zeile, wie in Wurzelheim (Littleroot Town) mit „MOM: {PLAYER}, we’re here, honey!“ (Mama: {PLAYER}, wir sind da, Schatz!). Von 14.412 Absätzen beginnen 934, also 6,5 %, mit einem großgeschriebenen Namen und einem Doppelpunkt.137 Dass es kein eigenes Namensfeld gibt, ist meine Lesart der Fenstervorlage, die Platz für die zwei Textzeilen hat und für nichts sonst.2
Japanisch im englischen Spiel
Das englische Smaragd trägt noch japanische Glyphen, für die Namen von Kreaturen und Trainern, die von japanischen Modulen stammen. Der Drucker wechselt den Glyphensatz beim Steuercode EXT_CTRL_CODE_JPN und zurück bei EXT_CTRL_CODE_ENG, die solche Namen tragen (international_string_util.c, contest.c und battle_tower.c fügen sie ein). In diesem Modus ist die normale Schrift für jedes Zeichen 8 Pixel breit und 15 hoch (DecompressGlyph_Normal, und GetGlyphWidth_Normal liefert 8).11338
Die Sheets, aus denen das englische ROM gebaut wird: japanese_normal.png misst 128 mal 512 Pixel in Zellen von 8 mal 16, 302 seiner 512 Zellen sind gezeichnet; japanese_small.png gleich groß, 307 gezeichnet; japanese_bold.png 128 mal 256, 246 von 256 gezeichnet; und japanese_frlg_male.png aus Feuerrot, ebenfalls im Smaragd-Quellbaum, 256 mal 512 Pixel in Zellen von 16 mal 16, 269 von 512 gezeichnet, mit einer Breitentabelle aus 512 Einträgen von 0 bis 10 Pixeln, 10 bei 408 davon.138 pret baut die englischen Spiele, das sind also die Sheets für Namen in einem englischen ROM; Box, Tempi oder Schrift eines japanischen ROMs wurden nicht gelesen (Abschnitt 11).30
In den eigenen Maßen des Kanons ist ein japanisches Zeichen in einer 16-Pixel-Zeile also 8 Pixel breit in Smaragd und meist 10 im Sheet von Feuerrot, gegenüber 4 bis 6 für einen lateinischen Buchstaben.1
Feuerrot
Feuerrot behält die Verzögerungen von Smaragd, 8, 4 und 1, die sein eigenes AddTextPrinter in src/text_printer.c wie in Smaragd minus eins speichert, und ein Standardtextfenster von 26 mal 4 Tiles ab Spalte 2 (src/new_menu_helpers.c), ein Tile schmaler als das von Smaragd.139 Auch sein Drucker kennt das Halten aus Smaragd: if (JOY_HELD(A_BUTTON | B_BUTTON) && subStruct->hasPrintBeenSpedUp) setzt den Zähler auf 0, und ein neuer Druck auf A oder B, während die Verzögerung eines Zeichens herunterzählt, setzt in einer Nachricht, die das erlaubt, hasPrintBeenSpedUp.14
2. Kristall und Rot: achtzehn Zeichen und eine blinkende Marke
Die Box des Game Boy ist der Vorfahr der Box des Game Boy Advance in kleinerer Auflösung. Der Bildschirm von Kristall misst 20 mal 18 Tiles (SCREEN_WIDTH 20, SCREEN_HEIGHT 18), 160 mal 144 Pixel. Seine Textbox ist TEXTBOX_WIDTH = SCREEN_WIDTH mal TEXTBOX_HEIGHT 6: die volle Breite und ein Drittel der Höhe, 33 %. Mit BORDER_WIDTH 2 misst das Innere 18 mal 4 Tiles, und die Schrift von 8 mal 8 ergibt 18 Zeichen pro Zeile. Der Text beginnt zwei Reihen tief in der Box, TEXTBOX_INNERY = TEXTBOX_Y + 2, und die Zeilen liegen zwei Reihen auseinander, die Box zeigt also zwei Zeilen mit einer leeren Reihe dazwischen; das zweizeilige Layout ist meine Lesart dieser Konstanten.13 Die Nachrichtenbox von Rot ist db MESSAGE_BOX, 0, 12, 19, 17: dieselben 20 mal 6 Tiles am unteren Rand.112
Auch diese beiden Spiele zählen das Tempo in Frames. Die Verzögerungen sind TEXT_DELAY_FAST 1, mittel 3 und langsam 5 Frames pro Buchstabe: 60, 20 und 12 Buchstaben pro Sekunde bei 60 Hertz. PrintLetterDelay in Kristall sagt es geradeheraus: „The text speed setting in wOptions is actually a frame count“ (die Texttempo-Einstellung in wOptions ist in Wahrheit eine Anzahl von Frames). Solange A oder B gehalten wird, wartet es einen Frame pro Buchstabe.115 Das schnelle Tempo von Kristall entspricht also dem von Smaragd, 60 pro Sekunde, und das Halten von A oder B in Smaragd ergibt dieselbe Rate; die mittlere und die langsame Einstellung von Kristall, 20 und 12, sind schneller als die 15 und 7,5 von Smaragd.1 Pan Docs gibt den Frame des Game Boy als „One frame: 70224 dots @ 59.7 fps“ an (ein Frame: 70.224 Punkte bei 59,7 fps) und merkt an, dass ein Frame „takes ~16.74 ms instead of ~16.67“ (etwa 16,74 ms statt etwa 16,67 dauert).40
Kristall lässt den Spieler unter acht Rahmen wählen, FRAME_1 bis FRAME_8, jeder TEXTBOX_FRAME_TILES, 6 Tiles zu 1 Bit, gespeichert als PNGs von 24 mal 16 Pixeln; ein neunter Rahmen liegt ungenutzt im ROM. Das Schrift-Sheet gfx/font/font.png misst 128 mal 64 Pixel, 128 Zellen von 8 mal 8, und das von Rot ist gleich groß.141
Die Marke blinkt
Die Weitermarke von Kristall ist Teil des Rahmens. WaitPressAorB_BlinkCursor wartet auf A oder B, während BlinkCursor das Tile an (18, 17), in der unteren Reihe des Rahmens selbst, zwischen '▼' und dem Rahmentile '─' wechselt.16 Die beiden Zustände sind aus dem Code gelesen; die Periode des Blinkens wurde nicht abgeleitet (Abschnitt 11).
Das ist die zweite Ungenauigkeit des Welt-Beitrags. Sein Textplan verlangt „a two-frame advance arrow“ (einen Weiterpfeil mit zwei Frames).23 Eine Marke mit zwei Zuständen ist das Blinken von Kristall. Der Pfeil von Smaragd, dem der übrige Plan folgt (die 16-Pixel-Zeile, die Box am unteren Rand), blinkt nicht: Er durchläuft drei Positionen, 0, 1, 2 und 1 Pixel von der Ruhelage, in einem Zyklus von 36 Frames (der Code versetzt die Quellzeilen der Bitmap, was den Keil nach meiner Lesart auf dem Bildschirm anhebt; ausgeführt habe ich es nicht).113 Das Briefing in Abschnitt 12 übernimmt die Schritte von Smaragd, nicht seine Richtung.
3. Final Fantasy VI: ein Fenster, das Sie umfärben, eine Schrift, die umbricht
Final Fantasy VI behandelt das Fenster als Sache des Spielers. Seine Zahlen stammen hier aus der Disassemblierung everything8215/ff6 bei 8130132 (14. September 2026), die Code und Rip-Listen enthält, nicht die Grafiken des ROMs; Größen ergeben sich also aus Bytebereichen und aus dem Code, der sie liest.304
Acht Fenster, je sieben Farben
Die englische und die japanische Rip-Liste geben die Fenstergrafiken beide als 0xED0000 bis 0xED1BFF an, 7.168 Bytes: acht Stile zu 896 Bytes, jeder 28 Tiles von 8 mal 8 mit 4 Bit pro Pixel. Ihre Paletten folgen bei 0xED1C00 bis 0xED1CFF, acht Paletten zu 16 Farben.442 Der Konfigurationsbildschirm führt 8 Fenstermuster auf (ConfigWindowNumPos).443
Die Farbe des Fensters bestimmt der Spieler. LoadWindowPal liest die Farben des Musters bei $1d57 aus dem Speicherstand, 14 Bytes pro Muster, also sieben Farben zu zwei Bytes, und der Konfigurationsbildschirm bearbeitet sie mit Reglern für R, G und B (ConfigColorBarTextList); eine weitere Farbe, die der Schrift, liegt bei $1d55.443 Die Schrittweite ist aus dem Code gelesen, die drei Kanäle aus der Reglerliste.4
Das Nachrichtentempo des Konfigurationsbildschirms hat sechs Einstellungen, 1 bis 6 (ChangeConfigOption_02 endet bei $05), und ein neuer Spielstand beginnt mit „message speed = 3, battle speed = 3“ (Nachrichtentempo = 3, Kampftempo = 3), wie es der Kommentar in menu_sram.asm formuliert.443 Es ist das Tempo der Kampfmeldungen, wie config.asm es in einem Kommentar nennt: „battle speed, battle message speed, magic order, and window pattern“ (Kampftempo, Tempo der Kampfmeldungen, Magiereihenfolge und Fenstermuster). Außerhalb des Konfigurationsbildschirms liest nur ein Stück Code seine Bits des Konfigurationsbytes $1d4d: mess_wait in src/btlgfx/gfx_cmd.asm, das die Einstellung in MsgSpeedTbl nachschlägt, „wait duration for each battle message speed“ (Wartedauer für jedes Tempo der Kampfmeldungen), und so viele Frames wartet: 32, 48, 64, 80, 96 oder 112 für die Einstellungen 1 bis 6. Keine Datei im Feldcode liest $1d4d überhaupt; Felddialoge haben also keine Tempoeinstellung, sie werden mit der einen Rate unten gedruckt.444
Ein schattiertes Fenster ohne Tile
Das Dialogfenster wird durch die Farbmathematik der Hardware über seine Höhe schattiert. DlgWindowFixedColorTbl in src/field/hdma.asm besteht aus 200 Bytes von $E0 bis $E7, einer festen Farbe auf allen drei Kanälen mit den Intensitäten 0 bis 7, und sein erster Lauf umfasst 72 Werte, die bei 7 beginnen, auf 0 fallen und wieder auf 7 steigen.445 Das Fenster öffnet sich nahe dem oberen oder dem unteren Bildschirmrand, „dialog window y position (1 or 18)“ (y-Position des Dialogfensters, 1 oder 18) im Kommentar von event.asm.45 Dass die Tabelle mit einem Wert pro Scanline verbraucht wird, ist aus Kommentaren gelesen, nicht verfolgt, und wie der Verlauf aussieht, wurde nicht gesehen, denn die Disassemblierung enthält keine Pixel (Abschnitt 11).
Die Schrift
Die Dialogschrift hat 1 Bit pro Pixel, 22 Bytes pro Buchstabe: 11 Reihen zu 16 Bit, eine Zelle von 16 Pixeln Breite und 11 Höhe. Ihr Schlagschatten ist nicht gezeichnet: LoadLetterGfx erzeugt ihn, indem es jede Reihe um ein Pixel verschiebt (lsr).446 Die englischen Breiten aus FontWidth sind proportional: die Großbuchstaben im Mittel 8,04 Pixel (5 bis 12), die Kleinbuchstaben 7,73 (4 bis 12), die Ziffern 7,80 (5 bis 9), und das Leerzeichen 5.446
Die Dialogschrift des japanischen ROMs, laut seiner Rip-Liste bei 0xC494C0 bis 0xC4FFFF, umfasst 27.456 Bytes: 1.248 Buchstaben zu 22 Bytes. Ihre Breitentabelle hat 1.280 Einträge in Läufen von 1.056 mit 12 Pixeln, 180 mit 8 und 44 mit 12, und die Zeichentabellen der Disassemblierung führen 1.010 Kanji und 173 Kana.447 Der Bereich der englischen großen Schrift, 5.120 Bytes, ist keine ganze Zahl von 22-Byte-Buchstaben (232,7), was ich aus der Disassemblierung nicht erklären kann (Abschnitt 11).4
Eine Zeile, ein Umbruch, ein Buchstabe pro Frame
Eine Dialogzeile reicht von x 4 bis zu einem maximalen x von $e0, 224: 220 Pixel, 18 japanische Buchstaben zu 12 Pixeln.446 Englischer Text wird im Code wortweise umbrochen. CalcTextWidth addiert die Breite des nächsten Wortes, und NewLine wird aufgerufen, wenn sie das Maximum überschreiten würde, das englische Skript braucht also keine von Hand gesetzten Umbrüche; das Skript prüft die Aufrufe per Assertion, und die Lesart stammt aus UpdateDlgTextOneLine.446
Der Text wird mit einem Buchstaben pro Frame gedruckt. Die Feldschleife wartet auf die vertikale Austastlücke und ruft UpdateDlgText einmal pro Durchlauf auf, und UpdateDlgTextOneLine zeichnet einen Buchstaben und kehrt zurück: 60 Buchstaben pro Sekunde bei 60 Hertz.448 Ein Durchlauf pro Frame ist meine Lesart der Schleife. Da eine Quelle beide ROMs baut, teilen sich die beiden Sprachen diese Schleife, was nach meiner Lesart dieselben Buchstaben pro Sekunde auf Englisch und Japanisch bedeutet.48
Ein Kartentitel wird zentriert, ($e0 - width) / 2, und 100 Frames lang gezeigt, 1,67 Sekunden.446
Neben Smaragd gestellt, zeigt Final Fantasy VI den anderen Weg, dieselbe Box zu bauen: Smaragd schreibt jeden Umbruch von Hand und lässt den Spieler den Rahmen der Menüs wählen, nie den der Dialogbox; Final Fantasy VI bricht im Code um, lässt den Spieler das Fenster umfärben und schattiert es in der Hardware. Die Feldbox von Smaragd sitzt unten, die von Final Fantasy VI oben oder unten, und beide drucken mit einer festen Anzahl von Frames.
Chrono Trigger
Ich wollte Chrono Trigger neben Final Fantasy VI stellen und konnte es nicht. Keine öffentliche Disassemblierung wurde geklont, und die ROM-Karte des Spiels bei Data Crystal lieferte beim Abruf HTTP 403; nichts in diesem Beitrag über Textboxen stammt also daraus (Abschnitt 11).49
4. Japanisch in 8, 10 und 12 Punkten
Kiradex ist eine App für Kartensammler, und der Dex zeigt japanische Kartennamen bereits mit dem Englischen darunter, in den Systemschriften.50 Auch der Text der Welt wird Japanisch brauchen, und eine Pixelschrift, die es nicht zeichnen kann, kommt nicht in Frage. Die Frage ist, wie klein ein Kanji sein kann und wer bereits siebentausend davon gezeichnet hat.
Der Umfang der Aufgabe
JIS X 0208, der Zeichensatz, an dem japanische Pixelschriften gemessen werden, umfasst laut der Zuordnungstabelle des Unicode-Konsortiums 6.879 Zeichen: 524 Nicht-Kanji, davon 169 die Kana in den Reihen 4 und 5; 2.965 Kanji der Stufe 1 in den Reihen 16 bis 47; und 3.390 Kanji der Stufe 2 in den Reihen 48 bis 84.576 Die Tabelle ist Version 2.0, und das Konsortium führt sie unter seinen veralteten Zuordnungen; sie ist dennoch die Liste, an der sich die Abdeckung einer Schrift am leichtesten auszählen lässt.5
Misaki: 8 mal 8
Misaki (美咲フォント) von Num Kadoma ist die kleinste. Ihre Seite nennt sie „8×8 ドットの日本語ビットマップフォント“ (eine japanische Bitmapschrift mit 8 mal 8 Punkten), die „JIS 第一・第二水準“ (JIS-Stufen 1 und 2) unterstützt, und sagt „一部の記号を除いた全ての文字は 7×7 ドットの範囲に収まっている“ (alle Zeichen außer einigen Symbolen passen in 7 mal 7 Punkte), damit, so die Seite weiter, nebeneinander gesetzte Zeichen ihren Zeilen- und Zeichenabstand behalten.51 Entstanden ist sie laut der Chronik der Seite für einen japanischen Anzeigetreiber der Taschencomputer PC-E500.51
Gemessen an den BDF-Dateien der Ausgabe vom 2021-05-05 hat Misaki Gothic 7.171 Zeichen: 168 halbbreite, 4 Pixel breit, und 7.003 vollbreite, 8 Pixel breit, in einer Zelle von 8 mal 8 mit einer Oberlänge von 6 und einer Unterlänge von 2. Von seinen 6.356 Glyphen zwischen U+4E00 und U+9FFF (ein Codebereich, daher eine andere Zahl als die 6.355 Kanji der zwei JIS-Stufen) füllt keine die 8-Punkt-Zelle in irgendeiner Richtung, während 53 vollbreite Glyphen, Symbole, das tun. Sie zeichnet alle 6.879 Zeichen von JIS X 0208.6 Misaki Mincho, laut ihrer Seite Misaki Gothic mit im Mincho-Stil neu gezeichneten Nicht-Kanji, misst in jeder Zählung gleich. Misaki Gothic 2nd, die laut ihrer Seite die vollen 3 mal 7 Pixel für halbbreite Zeichen und 7 mal 7 für vollbreite Kana nutzt, hat 7.170 Zeichen (167 halbbreite) sowie eine Oberlänge von 7 und eine Unterlänge von 1 und misst im Übrigen gleich.651
k8x12: 8 mal 12
k8x12 vom selben Autor behält die Breite von 8 Punkten und gewinnt an Höhe: „8×12 ドットの日本語ビットマップフォント“ (eine japanische Bitmapschrift mit 8 mal 12 Punkten), JIS-Stufen 1 und 2. Es gibt zwei Varianten: k8x12L, deren Kana hoch gezeichnet sind, und k8x12S, deren Nicht-Kanji 8 Punkte hoch sind, gemacht, so die Seite, mit Blick auf die Grenzen alter Spielkonsolen: „8×8 ドット単位でグラフィックを扱うような、昔のゲーム機等の制限を意識しています“ (mit Blick auf die Grenzen alter Spielgeräte, die Grafik in Einheiten von 8 mal 8 Punkten verarbeiten).52
Gemessen an der BDF ist k8x12 eine Zelle von 8 mal 12 mit einer Oberlänge von 10 und einer Unterlänge von 2: 7.170 Zeichen, 168 mit 4 Pixeln und 7.002 mit 8. Kein Kanji füllt die Zelle; 53 vollbreite Glyphen tun es in k8x12 und k8x12L und 45 in k8x12S. Alle drei zeichnen alle 6.879 Zeichen von JIS X 0208.6
PixelMplus: 10 und 12, als Konturen
PixelMplus von itouhiro (2013) ist der andere Ansatz: TrueType-Konturen, die wie eine Bitmapschrift aussehen, ohne eingebettete Bitmaps („埋め込みビットマップは なし“, keine eingebetteten Bitmaps), alle Kanji der JIS-Stufen 1 und 2 („JIS第1・第2水準のすべての漢字を収録“, enthält alle Kanji der JIS-Stufen 1 und 2) plus ISO-8859-1, in einem normalen und einem fetten Schnitt und zwei Größen, PixelMplus12 und PixelMplus10, nachgezeichnet aus den M+ BITMAP FONTS.18 Mit Core Text gemessen hat jede 7.253 Glyphen und zeichnet 6.876 der 6.879 Zeichen von JIS X 0208. Die drei, die sie nicht abbildet, sind U+301C 〜, U+2016 ‖ und U+2212 −.7 Das sind Zeichen, deren Unicode-Zuordnung zwischen der JIS0208.TXT des Konsortiums und den Tabellen anderer Hersteller abweicht; nach meiner Lesart tragen die Schriften die Glyphen also wahrscheinlich an den anderen Codepoints; geprüft wurde das nicht (Abschnitt 11).5
DotGothic16: eine Punktschrift ohne Raster
DotGothic16 von Fontworks steht bei Google Fonts unter der SIL Open Font License 1.1 ohne Reserved Font Name, aufgeführt mit den Teilmengen cyrillic, japanese, latin und latin-ext und hinzugefügt am 2020-12-15.53 Sie hat 9.362 Glyphen und zeichnet alle 6.879 Zeichen von JIS X 0208.7 Gezeichnet ist sie aber aus getrennten Punkten, nicht aus Pixeln. In ihrem A treten die x-Kanten der Kontur paarweise auf, 91 und 102, 153 und 163, 214 und 225, 276 und 287, 338 und 349, 400 und 410 Einheiten von 1.000: Punkte im Abstand von etwa 62 Einheiten mit Lücken von 10 oder 11 Einheiten dazwischen. Dazu passt kein Raster aus ganzen Pixeln, und die Messung fand zwischen 4 und 40 Pixeln pro Em keines.197 Ein Abstand von etwa 62 Einheiten liegt nahe an 16 Punkten pro Em, der Zahl im Namen der Schrift; die Messung zeichnet sie daher nominell mit 16 Punkten pro Em und Vielfachen davon, meine Wahl der Größe, kein Raster, das die Schrift angibt. Core Text unter macOS 27.0 zeichnete sie bei 16 Pixeln zu 82,3 % mit Teilpixeln und bei 64 zu 37,3 %, und bei jeder gemessenen Größe mit Teilpixeln (Abschnitt 6).7
Was die freien Schriften messen
Das Designraster in der Tabelle ist die kleinste Zahl von Pixeln pro Em, bei der 95 % der Konturpunkte einer Glyphenstichprobe innerhalb von 0,04 Pixel liegen, wobei jede Achse einen konstanten Versatz haben darf; das Skript, das es findet, measure_coretext.swift, wurde mit swiftc -O kompiliert und unter macOS 27.0 (Build 26A428) ausgeführt, es sind also die Core-Text-Zahlen eines Macs, nicht eines iPhones.7
| Schrift | Glyphen | Bitmaptabellen | Designraster (Pixel pro Em) | Vorschub Latein / Kana (Pixel) | JIS X 0208 gezeichnet |
|---|---|---|---|---|---|
| Misaki Gothic | 7.174 | EBDT, EBLC | 8, auf der Grundlinie | 4 / 8 | 6.879 |
| k8x12 | 7.173 | EBDT, EBLC | 12, auf der Grundlinie | 4 / 8,01 | 6.879 |
| PixelMplus10 Regular und Bold | je 7.253 | keine | 10, auf der Grundlinie | 5 / 10 | 6.876 |
| PixelMplus12 | 7.253 | keine | 12, 0,39 Pixel unter der Grundlinie | 6 / 12 | 6.876 |
| DotGothic16 | 9.362 | keine | keines (nominell mit 16 Punkten gezeichnet) | 8 / 16 nominelle Punkte | 6.879 |
Nach diesem Maß liegen bei PixelMplus10 Regular 0 von 1.032 erfassten Konturkoordinaten neben seinem 10-Pixel-Raster und beim Bold 0 von 1.000; bei Misaki Gothic 0 von 848; bei k8x12 0 von 988; bei PixelMplus12 0 von 1.192, sobald sein Versatz von 0,39 Pixel zugelassen ist, und bei DotGothic16 alle 1.544.7 Der Versatz von PixelMplus12 zeigt sich in seinen Rohkoordinaten: Sein H reicht von y −33 bis 717 Einheiten von 1.000, auf einem Raster von 83,3 Einheiten pro Pixel, seine Grundlinie fällt also 0,396 Pixel in eine Rasterreihe hinein; der Schätzwert der Messung, 0,39, entsteht durch Einsortieren der Nachkommaanteile der Koordinaten in Klassen von einem Fünfzigstel Pixel Breite und ist der Wert, um den die Renderings unten verschoben wurden.19733
In jeder gemessenen Schrift mit Japanisch ist ein japanisches Zeichen doppelt so breit wie ein lateinisches: 8 gegen 4 in Misaki und k8x12, 10 gegen 5 und 12 gegen 6 in PixelMplus.7 Der Kanon liegt im selben Bereich: Das Japanisch von Smaragd ist in einer 16-Pixel-Zeile 8 Pixel breit, das Sheet von Feuerrot meist 10, Final Fantasy VI 12.14
Die Lizenzen
All das ist in den schlichtesten Worten frei. Die Lizenz für Misaki und k8x12 auf der Schriftenseite des Autors besteht aus drei Sätzen: „These fonts are free software. Unlimited permission is granted to use, copy, and distribute them, with or without modification, either commercially or noncommercially. THESE FONTS ARE PROVIDED “AS IS” WITHOUT WARRANTY.“ (Diese Schriften sind freie Software. Unbeschränkt erlaubt ist, sie mit oder ohne Änderung, kommerziell wie nichtkommerziell, zu nutzen, zu vervielfältigen und weiterzugeben. Diese Schriften werden ohne Gewähr „wie besehen“ bereitgestellt.) Die Readme jedes Archivs enthält dieselben Bedingungen in leicht anderen Worten, und die Misaki-Seite nennt als ihre Lizenz die M+ FONTS-Lizenz.1751 PixelMplus steht unter der M+ FONT LICENSE, deren englischer Text, LICENSE_E, dieselben drei Sätze sind.18 DotGothic16 steht unter der SIL Open Font License 1.1, deren Bedingungen in ihrer eigenen OFL.txt stehen.53 Nach meiner Lesart verlangt die Lizenz aus drei Sätzen keine Gegenleistung; die Autoren zu nennen ist trotzdem richtig, und das Briefing tut es (Abschnitt 12). Das sind Lesarten, keine Rechtsberatung.
Was Lesbarkeit kostet
Ein Kana ist in Misaki 8 Schriftpixel breit, in PixelMplus12 zwölf. In der eigenen Dichte der Welt auf dem iPhone 18 Pro Max, wo ein Texel 8 Gerätepixel misst, fasst eine in Misaki gezeichnete Zeile der Box 36 lateinische oder 18 japanische Zeichen.11 Die japanische Zeile trägt pro Zeichen mehr, die Box muss also nicht so viele Zeichen fassen, um dasselbe zu sagen; das ist meine Lesart, keine Messung.
5. Lateinische Pixelschriften und die, die ich nicht messen konnte
Zwei lateinische Pixelschriften von Google Fonts wurden neben den japanischen gemessen.30
Press Start 2P von CodeMan38 steht unter der SIL Open Font License 1.1 „with Reserved Font Name “Press Start 2P”“ (mit dem Reserved Font Name „Press Start 2P“).54 Sie hat 658 Glyphen auf einem 8-Pixel-Raster auf der Grundlinie, jedes lateinische Zeichen 8 Pixel breit, und alle 95 druckbaren ASCII-Zeichen. Kana oder Kanji hat sie nicht: Von JIS X 0208 zeichnet sie 150 Nicht-Kanji (ihr Griechisch, Kyrillisch und ihre Symbole) und keines der 6.355 Kanji.7
Silkscreen von Jason Kottke steht unter der SIL Open Font License 1.1 ohne Reserved Font Name.55 Sie hat 228 Glyphen auf einem 8-Pixel-Raster, von dem 10 von 588 erfassten Konturkoordinaten abweichen (ihr A und ihr o haben y-Werte von 495 und 130 Einheiten auf einem 125-Einheiten-Raster), und ihr A ist 6 Pixel breit. Von JIS X 0208 zeichnet sie 21 Nicht-Kanji.719
Drei weitere Schriften, die oft für Pixelspiele empfohlen werden, wurden nicht gemessen, und ich sage das, statt sie aus dem Gedächtnis zu beschreiben.
Pixel Operator von Jayvee Enaguas: Die Notizen des Autors bei DaFont sagen „Changed licence to Creative Commons Zero (CC0) 1.0“ (Lizenz auf Creative Commons Zero (CC0) 1.0 geändert) und dass die Schrift „licensed under a Creative Commons Zero (CC0) 1.0“ ist (unter Creative Commons Zero (CC0) 1.0 lizenziert). DaFont führt sie als „Bitmap (16 px)“, in 15 Schriftdateien, mit 241 Glyphen. Das eigene Repository des Autors, das die Notizen bei NotABug angeben, lieferte HTTP 404, und die Schrift wurde weder heruntergeladen noch gemessen. Alles hier stammt von dieser einen Seite.56
m5x7 von Daniel Linssen: Seine itch.io-Seite sagt „use font size 16, 32, 48, etc“ (Schriftgröße 16, 32, 48 usw. verwenden) und „free to use but attribution appreciated“ (frei nutzbar, Namensnennung erwünscht), führt „Asset license Creative Commons Zero v1.0 Universal“ (Asset-Lizenz Creative Commons Zero v1.0 Universal) und nennt eine mittlere Breite von 5, eine Oberlänge von 7, eine Unterlänge von 2 und eine x-Höhe von 5. Ihre Zeichen beschreibt sie als „uppercase and lowercase letters, including many accented letters, numbers and most common symbols“ (Groß- und Kleinbuchstaben, darunter viele mit Akzenten, Ziffern und die gängigsten Symbole).57
m3x6 vom selben Autor: „use font size 16, 32, 48, etc“ (Schriftgröße 16, 32, 48 usw. verwenden) und „free to use with attribution“ (frei nutzbar mit Namensnennung); ihre Seite zeigt kein Feld für die Asset-Lizenz.58 Keine der beiden Dateien wurde heruntergeladen, weil beide hinter einem Download mit frei wählbarem Preis liegen; gemessen wurde also keine.5758
Das ist die dritte Ungenauigkeit des Welt-Beitrags. Sein Textplan nennt m5x7 als Schrift.23 Nach der Beschreibung auf ihrer eigenen Seite ist m5x7 eine lateinische Schrift, und nichts auf der Seite sagt, dass sie Kana oder Kanji hat; eine App, die Japanisch zeigen wird, kann ihren Welttext nicht darin setzen.57 Das Briefing wechselt die Schrift zu PixelMplus10, einer von zwei gemessenen Schriften mit Japanisch, sauberem Raster und ganzen Pixelvorschüben (Misaki ist die andere), und der größeren der beiden (Abschnitte 6 und 12). m5x7 selbst bleibt ungemessen.
6. Was Core Text mit einer Pixelschrift macht
Der Welt-Beitrag behauptete: „Bitmap fonts render at integer multiples only“ (Bitmapschriften werden nur in ganzzahligen Vielfachen gerendert).23 Das ist die Regel, die jeder Pixel-Art-Leitfaden wiederholt, und ich wollte sie mit Zahlen sehen, auf Apples eigener Text-Engine.
Die Messung
Core Text ist Apples Schicht, um „Create text layouts, optimize font handling, and access font metrics and glyph data“ (Textlayouts erstellen, die Schriftverarbeitung optimieren und auf Schriftmetriken und Glyphendaten zugreifen), verfügbar seit iOS 3.2 und macOS 10.8.59 measure_coretext.swift lädt jede in Frage kommende TrueType-Datei, zeichnet eine Beispielzeile („Nice card! Which set? 0123“ für die lateinischen Schriften, „カードを見せて! Nice card!“ für die japanischen) in eine 8-Bit-Graustufen-Bitmap, in Größen, die ganze und gebrochene Vielfache des Rasters jeder Schrift sind, und zählt die Tintenpixel, die Teilpixel sind: zwischen 8 und 247 von 255, also mehr als 3 % von voll oder leer entfernt. Jede Größe wird auf drei Arten gezeichnet: mit der Standard-Kantenglättung von Core Text, ohne Kantenglättung und mit eingeschalteter Subpixel-Positionierung bei ausgeschalteter Quantisierung, damit die Glyphen genau dort landen, wohin ihre Vorschübe sie setzen.7
Zwei Grenzen zählen vor jeder Zahl. Der Lauf erfolgte unter macOS 27.0, Build 26A428, auf meinem Mac, nicht unter iOS, und er zeichnet über Core Text in einen Bitmap-Kontext, nicht über SwiftUIs Text; was ein iPhone zeichnet, bleibt eine Vorhersage, bis die Aufnahmeprüfungen des Briefings auf einem laufen (Abschnitt 11).7 Und das Skript zeichnet bei ausgeschalteter Schriftglättung (setAllowsFontSmoothing(false)). Als ich die Abbildung unten stattdessen mit der Voreinstellung des Bitmap-Kontexts zeichnete, waren 178 der 272 Tintenpixel von „Nice card!“ in PixelMplus10 bei 10 Pixeln Teilpixel, gegenüber 0 von 94 bei ausgeschalteter Glättung.9 Schriftglättung ist eine Einstellung von macOS; ob unter iOS etwas Vergleichbares greift, müssen die Aufnahmeprüfungen entscheiden.
Ganzzahlige Vielfache sind sauber
Bei ganzzahligen Vielfachen des Rasters, mit eingeschalteter Kantenglättung (der Voreinstellung des Kontexts) und ausgeschalteter Schriftglättung, rendern Misaki bei 8, 16, 24 und 32 Pixeln, PixelMplus10 Regular und Bold bei 10, 20, 30 und 40 und Press Start 2P bei 8, 16, 24 und 32 alle mit 0,0 % Teilpixeln.7 Jedes Pixel ist Tinte oder Papier. Das hängt von der Glättungseinstellung ab: Mit der voreingestellten Glättung des Bitmap-Kontexts zeichnete PixelMplus10 in seinen eigenen 10 Pixeln 178 der 272 Tintenpixel von „Nice card!“ als Teilpixel; auf dem Mac machte ein ganzzahliges Vielfaches allein den Text also nicht scharf.9
PixelMplus10 Regular, von Core Text unter macOS 27.0 mit einem Gerätepixel pro Schriftpixel gezeichnet, dargestellt ohne Kantenglättung. Mit eingeschalteter Kantenglättung und ausgeschalteter Schriftglättung sind 0 der 94 Tintenpixel von „Nice card!“ Teilpixel; mit der voreingestellten Glättung des Bitmap-Kontexts 178 von 272. Die Schrift steht unter der M+ FONT LICENSE, die Vervielfältigung und Weitergabe erlaubt; gezeichnet von figures/dump_glyphs.swift und figures/make_figures.py.
Dazwischen verschmieren sie
Zwischen ganzzahligen Vielfachen verschmieren dieselben Schriften, wie in der gesamten Messung bei ausgeschalteter Glättung. Misaki hat bei 12 Pixeln (dem 1,5-Fachen seines Rasters) 57,7 % Teilpixel, bei 20 (dem 2,5-Fachen) 39,9 % und bei 10 (dem 1,25-Fachen) 82,2 %. PixelMplus10 hat bei 15 Pixeln 60,1 %. Press Start 2P hat bei 12 Pixeln 44,0 %, bei 20 29,1 % und bei 28 21,7 %.7 Über alle 40 Renderings beim 1,25-, 1,5-, 1,75-, 2,5- und 3,5-Fachen des Rasters der acht Schriften, deren Raster auf der Grundlinie sitzt (beide Misakis, k8x12 und k8x12S, PixelMplus10 Regular und Bold, Press Start 2P und Silkscreen), reicht der Anteil der Teilpixel von 19,4 %, PixelMplus10 Bold bei 35 Pixeln, bis 82,2 %, Misaki bei 10.7 Das Verschmieren nimmt mit der Größe nicht stetig ab: Bei allen acht verschmiert das 1,75-Fache des Rasters stärker als das 1,5-Fache (Misaki 65,7 % bei 14 Pixeln gegenüber 57,7 % bei 12). Bei gleichem Bruchteil nimmt es ab: Beim 1,5-, 2,5- und 3,5-Fachen des Rasters liegt jede der acht mit jeder Stufe niedriger (Misaki 57,7 %, 39,9 % und 30,4 %). In keinem zwischen ganzzahligen Vielfachen gemessenen Rendering erreicht es null; nach meiner Lesart sinkt es bei festem Bruchteil, weil ein Fehler von einem halben Pixel an der Kante einer Glyphe ein kleinerer Anteil einer größeren Glyphe ist.7
Schaltet man die Kantenglättung aus (setShouldAntialias(false)), ist jedes Pixel bei jeder Größe voll oder leer, aber die Formen werden ungleichmäßig neu abgetastet. Aus den 191 Tintenpixeln von Misaki bei 8 Pixeln werden bei 10 Pixeln 377; eine gleichmäßige Skalierung um 1,25 in jeder Richtung ergäbe etwa 298.733 Manche Reihen und Spalten werden verdoppelt, andere nicht, und Striche, die ein Pixel breit waren, werden ein oder zwei Pixel breit.
Teilpixel nach Größe, Core Text unter macOS 27.0 bei ausgeschalteter Schriftglättung, nicht iOS; gezeichnet von figures/make_figures.py aus measure_coretext.out.
Eine saubere Größe reicht nicht: Die Datei muss sauber sein
Zwei leisere Fehler zählen bei der Wahl einer Schrift mehr als die Vielfachen.
Ein Raster neben der Grundlinie verschmiert bei jeder Größe. Die Konturen von PixelMplus12 liegen 0,39 Pixel unter dem Grundlinienraster, und sie rendert bei ihren eigenen 12 Pixeln mit 66,6 % Teilpixeln, bei 24 mit 40,0 % und bei 36 mit 29,8 %. Verschiebt man die Grundlinie um den Versatz, über die Transformation des Kontexts bei eingeschalteter Subpixel-Positionierung, sinken 12 Pixel auf 0,0 %, aber bei 24 bleiben 14,3 % und bei 36 19,0 %, obwohl die Verschiebung mit der Größe skaliert wurde (0,78 Pixel bei 24, 1,17 bei 36).7 Warum die skalierte Verschiebung die größeren Größen nicht säubert, sagt die Ausgabe nicht, und ich habe es nicht nachverfolgt.
Ein Vorschub neben dem Raster verschmiert, sobald Glyphen exakt platziert werden. Der Kana-Vorschub von k8x12 beträgt 8,01 Pixel, nicht 8. Mit den Standardeinstellungen des Bitmap-Kontexts, die jede Glyphe auf ein ganzes Pixel setzen, rendert sie bei 12, 24 und 36 Pixeln mit 0,0 % Teilpixeln. Mit eingeschalteter Subpixel-Positionierung und ausgeschalteter Quantisierung haben dieselben Größen 62,3 %, 42,8 % und 32,6 % Teilpixel.7 Nach meiner Lesart landet dann jedes Kana ein Hundertstel Pixel weiter vom Raster entfernt als das vorige.
Vereinzelte Konturpunkte hinterlassen ein wenig. Die zehn Koordinaten von Silkscreen neben dem Raster zeigen sich als 4,5 % Teilpixel bei 8 Pixeln und 1,2 % bei 32.7
Eine Punktschrift richtet sich nie aus. DotGothic16 hat kein Raster, von dem man Vielfache nehmen könnte; die Messung zeichnet sie daher nominell mit 16 Punkten pro Em und dem 1,25- bis 4-Fachen davon (Abschnitt 4). Mit eingeschalteter Kantenglättung und ausgeschalteter Glättung hat sie bei 16 Pixeln 82,3 % Teilpixel, bei 32 52,5 %, bei 48 48,8 % und bei 64 37,3 %, und bei jeder der neun Größen von 16 bis 64 Pixeln Teilpixel, ganzzahlige Vielfache von 16 eingeschlossen; ihre Punkte sitzen auf keinem Pixelraster (Abschnitt 4).719
Misaki und k8x12 tragen eingebettete Bitmaptabellen (EBDT und EBLC, gelesen mit CTFontCopyAvailableTables). Die gemessenen Ergebnisse oben sind das, was Core Text gezeichnet hat; ob es dabei diese Bitmaps oder die Konturen zeichnete, wurde nicht ermittelt (Abschnitt 11).7
Misaki, PixelMplus10 und Press Start 2P haben keinen der beiden leisen Fehler. Die Regel, die daraus folgt, betrifft die Schriftdatei ebenso wie die Größe: ganzzahlige Vielfache, ein Raster auf der Grundlinie und Vorschübe in ganzen Pixeln.
Dynamic Type und das Raster
Apples Human Interface Guidelines geben iOS eine Standardtextgröße von 17 Punkt und ein Minimum von 11 sowie eine Tabelle für jede Dynamic-Type-Größe. Body läuft von xSmall bis AX5 durch 14, 15, 16, 17, 19, 21, 23, 28, 33, 40, 47 und 53 Punkt; Caption 1 von 11 bis 43.6010
Auf einem 3×-Display ist ein Schriftpixel nur dann eine ganze Zahl von Gerätepixeln, wenn die Punktgröße mal 3, geteilt durch das Em in Schriftpixeln, ganzzahlig ist. Von den zwölf Body-Größen landet ein Em von 12 Pixeln bei 3 davon ganzzahlig (16, 28 und 40 Punkt), ein Em von 8 Pixeln bei 2 (16 und 40) und ein Em von 10 Pixeln bei 1 (40). Von den zwölf Größen von Caption 1 landet ein Em von 12 Pixeln bei 3 ganzzahlig (12, 16 und 32).760
Welche Body-Größen bei 3× auf ganzen Gerätepixeln landen, und die Rundung des Briefings; gezeichnet von figures/make_figures.py aus measure_coretext.out und measure_kiradex_text.out.
Eine Pixelschrift kann Dynamic Type also nicht einfach folgen. Skaliert sie stufenlos mit den Größen des Systems, liegt sie bei jeder Größe außer den wenigen ganzzahligen neben ihrem Raster: bei 11 von 12 Body-Größen für ein Em von 10 Pixeln, bei 9 von 12 für ein Em von 12 Pixeln.733 Neben dem Raster verschmierte Core Text auf dem Mac mit eingeschalteter Kantenglättung jede gemessene Schrift; ob SwiftUI auf einem iPhone dasselbe tut, hängt von seinem Rendering und seiner Platzierung ab, was die Aufnahmen des Briefings entscheiden. Sie muss die vom System verlangte Größe nehmen und auf das Raster runden, was Abschnitt 10 in ein API-Rezept und Abschnitt 12 in die Regel des Briefings übersetzt.
7. Japanischer Zeilenumbruch
Eine kurze vorgegebene Zeile bricht nie um. Ein Textblock in der Box schon, und das Japanische hat Regeln dafür, wo.
Die Regeln
Die Requirements for Japanese Text Layout des W3C (eine Working Group Note vom 11. August 2020) legen in 3.1.7 die Zeilenanfangsregel fest: „In principle, no line should begin with closing brackets (cl-02), hyphens (cl-03), dividing punctuation marks (cl-04), middle dots (cl-05), full stops (cl-06), commas (cl-07), iteration marks (cl-09), a prolonged sound mark (cl-10), small kana (cl-11) or warichu closing brackets (cl-29)“ (grundsätzlich sollte keine Zeile mit schließenden Klammern, Bindestrichen, trennenden Satzzeichen, Mittelpunkten, Punkten, Kommas, Wiederholungszeichen, einem Dehnungszeichen, kleinen Kana oder schließenden Warichu-Klammern beginnen). Sie hält auch die lockerere Praxis fest: „Not a small number of books adopt a less strict set of rules which allow IDEOGRAPHIC ITERATION MARK “々” (one of the iteration marks (cl-09)), prolonged sound mark (cl-10) and small kana (cl-11) to start a line.“ (Nicht wenige Bücher verwenden weniger strenge Regeln, die das Wiederholungszeichen „々“, das Dehnungszeichen und kleine Kana am Zeilenanfang erlauben.)21
Der Zeilenumbruch-Algorithmus von Unicode, UAX #14 (Revision 57, für Unicode 18.0.0, datiert auf den 2026-09-01), ordnet die kleinen Hiragana und Katakana und das Dehnungszeichen seiner Klasse CJ zu und sagt: „Treating characters of class CJ as class NS will give CSS strict line breaking; treating them as class ID will give CSS normal breaking.“ (Werden Zeichen der Klasse CJ wie Klasse NS behandelt, ergibt das den strengen Zeilenumbruch von CSS; werden sie wie Klasse ID behandelt, den normalen.)61
Was Core Text tat
measure_coretext.swift, ausgeführt unter macOS 27.0 (nicht iOS), setzt einen japanischen Absatz von 131 Zeichen mit CTFramesetter in Breiten von 8, 10, 12, 14, 16, 18 und 20 Em und prüft das erste Zeichen jeder Zeile nach der ersten gegen eine eigene Liste von Zeichen, die keine Zeile beginnen dürfen: einige der schließenden Klammern, das japanische Komma und den japanischen Punkt, den Mittelpunkt, Doppelpunkt und Semikolon, Frage- und Ausrufezeichen, das Dehnungszeichen, die kleinen Kana und 々.7 Diese Liste ist keine Teilmenge der Klassen, die die Regel von JLREQ nennt, sondern überschneidet sich nur mit ihnen. Sieben ihrer 40 Zeichen, ,.:;?! und ), sind die Vollbreitenformen, die japanischer Text dort setzt, wo JLREQ die ASCII-Zeichen aufführt; die übrigen 33 sind die von JLREQ selbst. Von den schließenden Klammern enthält sie 」』】〉》〕 und die vollbreite ), ohne ’ ” ] } » 〟 ⦆ 〙 〗 und die ASCII-Klammer ); von den 40 kleinen Kana enthält sie 22, ohne ゕ, ゖ und ㇰ bis ㇿ; und es fehlen die Bindestriche (cl-03), darunter ‐, 〜, ゠ und der Halbgeviertstrich, ‼ ⁇ ⁈ ⁉ aus cl-04 sowie jedes Wiederholungszeichen (cl-09) außer 々, darunter ヽ, ヾ, ゝ, ゞ und 〻.721 Die Ergebnisse unten gelten für die Liste der Messung, und der Text des Testabsatzes entscheidet, welche Zeichen überhaupt an einen Zeilenanfang gelangen.
Ohne Sprachkennung begann bei keiner Breite eine Zeile mit einem Zeichen aus der Liste der Messung, weder in Hiragino Sans (der japanischen Systemschrift, als Kontrolle mitgeführt) noch in einer der acht Pixelschriften: Misaki Gothic, Misaki Gothic 2nd, k8x12, k8x12S, PixelMplus10 Regular und Bold, PixelMplus12 und DotGothic16 mit seinen nominellen 16 Punkten.7
Mit kCTLanguageAttributeName auf ja gesetzt, lockerte sich die Regel. In Hiragino Sans, beiden Misakis, beiden PixelMplus10, PixelMplus12 und DotGothic16 begann bei 6 der 7 Breiten eine Zeile mit einem kleinen Kana (っ, ョ oder ァ), bei jeder Breite außer 18 Em.7 In k8x12 und k8x12S begann bei 4 der 7 Breiten eine Zeile mit einem kleinen Kana (っ, ョ oder ょ) und bei zweien mit dem Dehnungszeichen ー, bei 10 Em (neben ョ) und bei 18 Em, einer fünften Breite.7
Nach meiner Lesart dieser Zählungen im Licht der beiden Zitate ergibt die Kennung ja die weniger strenge Regel, die JLREQ beschreibt, die, die UAX #14 den normalen Umbruch von CSS nennt, und der Lauf ohne Kennung verhält sich streng.2161 Das ist das Gegenteil dessen, was ich erwartet hatte, denn die Kennung benennt ja die Sprache, und es ist der Grund, warum das Briefing Boxtext ohne Aufnahme nicht kennzeichnet.
Zwei Anmerkungen zur Messung selbst, beide aus dem Abgleich des Skripts mit seiner Ausgabe. Die Breiten sind in Em angegeben, der vollen Größe der Schrift; bei k8x12, dessen Kana in einem Em von 12 Pixeln 8 Pixel breit sind, fasst jede Breite also anderthalbmal so viele Kana, wie ihre Zahl sagt; der Absatz in k8x12 brauchte bei 8 Em 12 Zeilen, wo die anderen 17 brauchten.7 Und DotGothic16, das kein Raster hat, wurde mit dem Doppelten seiner nominellen 16 Punkte gesetzt, 32 Pixeln pro Em; in dieser Größe brauchte es bei jeder Breite dieselbe Zahl von Zeilen wie Hiragino Sans, von 17 bei 8 Em bis 7 bei 20, und mit Kennung begannen dieselben kleinen Kana seine Zeilen.7
8. Pixelspiele seither: Boxen, Sprechblasen, Japanisch und Chinesisch
Stardew Valley: zwei Formen der Rede
Stardew Valley hat beide Formen, die Kiradex schon hat. Seine Dialogbox blättert mit einem Befehl, $b, den die Modding-Seite des Stardew Valley Wiki zu Dialogen (zuletzt bearbeitet am 20. Mai 2026) als einen beschreibt, der „Indicates pauses in dialogue, where the player will need to click for the next part to load in a new dialogue box“ (Pausen im Dialog markiert, an denen der Spieler klicken muss, damit der nächste Teil in einer neuen Dialogbox geladen wird), und Porträtbefehle, die „set the portrait shown in the dialogue box for the current line of dialogue“ (das in der Dialogbox gezeigte Porträt für die aktuelle Dialogzeile festlegen).62 Und es hat Sprechblasen, Strings\SpeechBubbles, für „dialogue spoken by NPCs through speech bubbles when the player enters a given location“ (Dialog, den NPCs über Sprechblasen sprechen, wenn der Spieler einen bestimmten Ort betritt).62 Die Box ist für Gespräche da, angeführt von einem Gesicht; die Sprechblasen sind das, was eine Stadt sagt, wenn Sie hineingehen.
Seine nichtlateinischen Sprachen nutzen Bitmapschriften. Die Wiki-Seite zu eigenen Sprachen (zuletzt bearbeitet am 3. Januar 2026) lässt eine neue Sprache UseLatinFont auf false setzen und eine .fnt-Datei liefern, nach dem Vorbild von „the Chinese, Japanese, Korean, and Russian fonts in the Fonts folder“ (den chinesischen, japanischen, koreanischen und russischen Schriften im Ordner Fonts). Ihr FontPixelZoom ist „A factor by which to multiply the font size. The recommended baseline is 1.5“ (ein Faktor, mit dem die Schriftgröße multipliziert wird; empfohlener Ausgangswert 1,5), und FontApplyYOffset legt fest, „Whether to shift the font up by four pixels“ (ob die Schrift um vier Pixel nach oben verschoben wird), um „languages with larger characters like Chinese and Japanese“ (Sprachen mit größeren Zeichen wie Chinesisch und Japanisch) auszurichten.63 Ein Zoom von 1,5 ist kein ganzzahliges Vielfaches, aber die Seite nennt ihn als Ausgangspunkt für eine Sprache, die ein Modder hinzufügt, nicht als das, was die mitgelieferten chinesischen, japanischen und koreanischen Schriften verwenden, und ob ein Zoom auf dem Bildschirm neu abtastet, hängt auch von der Skalierung des Spiels auf Gerätepixel ab; über die Art, wie Stardew sein eigenes Japanisch zeichnet, sagt das also nichts Sicheres.63
Das Final Fantasy Pixel Remaster: Die Schrift war die Arbeit
Die Konsolenfassung des Pixel Remaster brachte eine Option für eine Pixelschrift, und der Produzent Naofumi Takuma erzählte Siliconera (Jenni Lada, 2. Juni 2023), wie sie entstand. Für die westlichen Sprachen fand das Team intern erstellte Schriftdaten und nutzte sie. Für Japanisch: „We didn’t have any alternative data saved on file in-house for the Japanese language font, so we decided to create a new one.“ (Für die japanische Schrift hatten wir intern keine alternativen Daten gespeichert, also beschlossen wir, eine neue zu erstellen.) Und: „While the Western language font required us to create only a few hundred characters, with the Japanese font, we had to create around 7,500 characters.“ (Während wir für die Schrift der westlichen Sprachen nur einige hundert Zeichen erstellen mussten, waren es bei der japanischen Schrift rund 7.500 Zeichen.)8
Das ist die vierte Ungenauigkeit des Welt-Beitrags. Er nannte dieselbe Zahl, „about 7,500 Japanese characters“ (etwa 7.500 japanische Zeichen), und zitierte den Bericht von GoNintendo über die Arbeit; die Primärquelle ist das Interview des Produzenten selbst mit Siliconera, in dem es „around 7,500 characters“ (rund 7.500 Zeichen) heißt.238 Dieselbe Zahl, bessere Quelle.
Siebeneinhalbtausend entspricht ungefähr dem Umfang der 6.879 Zeichen von JIS X 0208, dem üblichen Abdeckungsziel; dieser Vergleich stammt von mir.533 Ein Spiel, dessen jede Zeile vor der Auslieferung feststeht, kann weniger zeichnen, wie es das japanische ROM von Final Fantasy VI mit 1.248 Dialogbuchstaben tat (Abschnitt 3), und dann muss jeder String gegen die Schrift geprüft werden; eine Schrift, die den ganzen Satz abdeckt, braucht diese Prüfung für keinen String, der aus ihm stammt.4 Die Lehre für eine kleine App ist dieselbe, die die freien Schriften in Abschnitt 4 von der anderen Seite erteilen: Für Text, der weiter wachsen wird, ist japanische Pixeltypografie nur dann ein gelöstes Problem, wenn jemand die siebentausend Zeichen bereits gezeichnet hat und die Lizenz die Auslieferung erlaubt.
Was die modernen Pixelspiele ausliefern
Auf Steam führte Stardew Valley am 5. Oktober 2026 12 Sprachen auf, darunter Japanisch, vereinfachtes Chinesisch und Koreanisch; Celeste 9, darunter Japanisch und vereinfachtes Chinesisch; Sea of Stars 11, darunter Japanisch, Koreanisch sowie vereinfachtes und traditionelles Chinesisch; und Eastward 7, darunter beide Formen des Chinesischen und Japanisch.64 Jedes der vier liefert Japanisch aus.
Wie Celeste, Sea of Stars und Eastward ihren japanischen und chinesischen Text zeichnen, konnte ich in keiner Entwicklerquelle finden; dieser Beitrag sagt darüber also nichts über die Sprachlisten hinaus (Abschnitt 11).
Zwei Formen der Rede in Kiradex
Kiradex hat bereits beide Formen von Stardew: die WorldHUD-Box am unteren Bildschirmrand und die Sprechblasen des Platzes über den Köpfen.2625 Was fehlt, ist die Typografie des Kanons darin und ein Weg, beide für VoiceOver hörbar zu machen. Der eigene Kommentar der Sprechblase im Code sagt, wonach sie griff: „A line said, as the old games drew it: a cream box with a dark border.“ (Eine gesprochene Zeile, so wie die alten Spiele sie zeichneten: eine cremefarbene Box mit dunklem Rand.)25
9. Das Handwerk, als Regeln mit Zahlen
Das sind die Regeln, die die Messungen stützen, jede mit ihrer Herkunft. Wo eine Regel eine gemessene Tatsache in eine Empfehlung übersetzt, ist die Empfehlung meine, und die Regel zeigt das durch ihr Verb.
| Element | Regel | Quelle |
|---|---|---|
| Box | Die Box ist das untere Drittel des Bildschirms und zwei Zeilen. Setzen Sie sie unten hin; ein Spiel, das den unteren Rand braucht, darf sie nach oben verlegen. | Der Rahmen von Smaragd mit 30 mal 6 Tiles, volle Breite und 30 % der Höhe, um ein Fenster von 27 mal 4 Tiles mit zwei 16-Pixel-Zeilen; Kristall 20 mal 6, 33 %, zwei Zeilen zu 18, und Rot ebenso 20 mal 6; das Fenster von Final Fantasy VI in Zeile 1 oder 18 |
| Lateinische Glyphen | 4 bis 12 Pixel breit in einer Zelle von 8 bis 16 Pixeln Höhe. | Die Zelle von 6 mal 16 in Smaragd mit 5,25 Pixeln pro Zeichen in echtem Text; Final Fantasy VI 4 bis 12 in einer Zelle von 16 mal 11; Kristall fest 8 mal 8 |
| Japanische Glyphen | 8 bis 12 Pixel, etwa doppelt so breit wie ein lateinischer Buchstabe derselben Schrift. | Misaki 8 mal 8 mit Tinte in 7 mal 7; Smaragd 8 breit in einer 16er-Zeile; das Sheet von Feuerrot und PixelMplus10 10; Final Fantasy VI und PixelMplus12 12; 8 gegen 4, 10 gegen 5, 12 gegen 6 in jeder gemessenen Schrift mit Japanisch |
| Zeilenlänge | 18 bis 41 Zeichen pro Zeile; auf die Breite hin schreiben, statt sie zu füllen. | Kristall 18; das 216-Pixel-Fenster von Smaragd fasst 41 bei 5,25 Pixeln, seine Autoren hörten bei 95 % der Zeilen bei 38 auf; die 220-Pixel-Zeile von Final Fantasy VI fasst 18 japanische Zeichen zu 12 Pixeln |
| Umbrüche | Entweder bricht der Autor jede Zeile um, oder der Code bricht wortweise um; nie beides. | Die 24.100 von Hand umbrochenen Zeilen von Smaragd, keine über 208 Pixel; CalcTextWidth und NewLine in Final Fantasy VI |
| Tempo | Zeichen in Zeit zählen: 60 pro Sekunde als Obergrenze (die schnelle Einstellung von Smaragd und Kristall und der eine Buchstabe pro Frame von Final Fantasy VI), 15 bis 20 für eine mittlere Einstellung, 7,5 bis 12 für langsam. | Smaragd 7,5, 15 und 60, gehalten 60; Kristall und Rot 12, 20 und 60; Final Fantasy VI 60 |
| Weitermarke | Die Marke nach einem langsamen Takt bewegen: ein Schritt alle 150 Millisekunden, ein Zyklus von etwa 0,6 Sekunden. | Die 0, 1, 2, 1 Pixel von Smaragd, ein Schritt alle 9 Frames, 36 Frames pro Zyklus; das ▼ von Kristall, im Wechsel mit dem Rahmentile blinkend |
| Rahmen | Rahmen sind Tiles, keine Zeichnungen: eine Ecke, eine Kante und eine Mitte, wiederholt. Den Spieler unter einigen wählen lassen. | Die 20 wählbaren Menürahmen von 24 mal 24 in Smaragd und sein Dialogstreifen aus 14 Tiles mit gespiegelter Unterkante; die 8 Rahmen von Kristall aus 6 Ein-Bit-Tiles; die 8 Stile von Final Fantasy VI aus 28 Tiles mit 7 bearbeitbaren Farben |
| Scharfe Schrift | Eine Pixelschrift ist nur bei ganzen Gerätepixeln pro Schriftpixel scharf und auf dem Mac nur bei ausgeschalteter Schriftglättung; nehmen Sie ein iPhone auf, um zu sehen, was dort gilt. | Core Text unter macOS 27.0 bei ausgeschalteter Schriftglättung: 0,0 % Teilpixel bei ganzzahligen Vielfachen eines Rasters auf der Grundlinie mit ganzen Pixelvorschüben (Misaki, PixelMplus10, Press Start 2P), 19,4 % bis 82,2 % dazwischen; mit der voreingestellten Glättung des Kontexts bei PixelMplus10 in seinen eigenen 10 Pixeln 178 von 272 Tintenpixeln Teilpixel |
| Saubere Dateien | Vor der Wahl einer Schrift ihr Raster, ihren Versatz zur Grundlinie und ihre Vorschübe prüfen. | Core Text unter macOS 27.0: das Raster von PixelMplus12 0,39 Pixel neben der Grundlinie, verschmiert bei jeder Größe; der Kana-Vorschub von k8x12 mit 8,01 Pixeln, verschmiert, sobald Glyphen exakt platziert werden; die 10 vereinzelten Punkte von Silkscreen, 1,2 % bis 4,5 % |
| Dynamic Type | Die Größe des Nutzers achten, indem man sie auf das Raster rundet, nie durch stufenloses Skalieren und nie unter 11 Punkt. | Ein Em von 10 Pixeln ist bei 3× bei 1 von 12 Body-Größen ganzzahlig, ein Em von 12 Pixeln bei 3, ein Em von 8 Pixeln bei 2; das Minimum von 11 Punkt der HIG |
| Japanische Umbrüche | Für Boxtext die strenge Zeilenanfangsregel beibehalten; vorgegebene Zeilen so kurz halten, dass sie nie umbrechen. | JLREQ 3.1.7; Core Text unter macOS 27.0 hielt ohne Kennung bei jeder gemessenen Breite die strenge Regel für die unvollständige Zeilenanfangsliste der Messung ein, mit der Kennung ja ließ es in den meisten Schriften bei 6 von 7 Breiten kleine Kana Zeilen beginnen (4 von 7 in k8x12 und k8x12S) |
| Sprecher | Einen Sprecher in der Zeile nennen, nicht in einem eigenen Feld oder über dem Kopf. | Die Box von Smaragd hat kein Namensfeld, und 6,5 % seiner Absätze beginnen mit einem Namen und einem Doppelpunkt |
| Abdeckung | Den Standardsatz abdecken, etwa siebentausend Zeichen, bevor japanischer Text ausgeliefert werden kann, den die Autoren nicht festgelegt haben; ein festes Skript kann mit weniger auskommen, String für String geprüft. | Die 6.879 von JIS X 0208; die „around 7,500“ (rund 7.500) des Pixel Remaster; die 1.248 Dialogbuchstaben des japanischen ROMs von Final Fantasy VI; Misaki, k8x12 und DotGothic16 zeichnen ganz JIS X 0208, PixelMplus alles bis auf drei Codepoints |
| Lizenzen | Eine Schrift nur mit ihrem Lizenztext in der Hand und gelesenen Bedingungen ausliefern. | die Lizenz aus drei Sätzen von Misaki, k8x12 und PixelMplus; die SIL Open Font License von DotGothic16, Press Start 2P und Silkscreen, mit dem Reserved Font Name von Press Start 2P |
| Zwei Formen | Beide Formen behalten, eine Box und eine Sprechblase. Was welche sagt, entscheidet ein Spiel; die Wahl von Kiradex, meine, ist die Box für das, was ein Ort sagt, und die Sprechblase für das, was eine Person sagt. | Stardew Valley hat beide: seine Box für Gespräche, seine Sprechblasen für das, was NPCs sagen, wenn der Spieler einen Ort betritt |
Jede Zahl in der Tabelle stammt aus den Abschnitten 1 bis 8 und trägt dort ihre Anmerkung.1467921862
10. Der Apple-Weg: Schrift, Größen, Zeilenumbrüche und VoiceOver
Kiradex World ist eine RealityKit-Szene, die als 2D-Renderer dient, mit einer orthografischen Kamera bei einer ganzen Zahl von Gerätepixeln pro Texel und SwiftUI darüber für alles, was ein Mensch liest.23 Der Welt-Beitrag entschied, dass Dialogtext „lives in SwiftUI at UI scale rather than in the world“ (in SwiftUI im UI-Maßstab lebt statt in der Welt), und dieser Abschnitt behält die Entscheidung bei und ergänzt die APIs: was Apple von eigener Schrift verlangt, wie eine mitgelieferte Pixelschrift hineinkommt, wie Dynamic Type durch Runden geachtet werden kann, wie Japanisch umbricht und wie VoiceOver eine Bühne lesen kann, die eine einzige RealityKit-Ansicht ist. Jede Verfügbarkeitsangabe unten stammt aus Apples Dokumentationsseiten, gespeichert am 5. Oktober 2026; keiner der Codes wurde gebaut, und jeder Aufwand in diesem Abschnitt ist auf einem Telefon ungemessen.65
Was Apple von Text verlangt
Die Seite Typography der Human Interface Guidelines gibt iOS und iPadOS eine Standardtextgröße von 17 Punkt und ein Minimum von 11 und bittet Apps: „Follow the recommended default and minimum text sizes for each platform“ (Halten Sie sich an die empfohlenen Standard- und Mindesttextgrößen jeder Plattform), für eigene wie für Systemschriften.1060 Systemschriften unterstützen Dynamic Type und Bedienungshilfen wie fetten Text von sich aus; für alle anderen sagt die Seite: „If you use a custom font, make sure it implements the same behaviors.“ (Wenn Sie eine eigene Schrift verwenden, stellen Sie sicher, dass sie dieselben Verhaltensweisen umsetzt.)10
Die Seite Accessibility legt den Umfang der Aufgabe fest: „Ideally, give people the option to enlarge text by at least 200 percent (or 140 percent in watchOS apps).“ (Geben Sie Menschen idealerweise die Möglichkeit, Text um mindestens 200 Prozent zu vergrößern, in watchOS-Apps um 140 Prozent.)20 Die Seite zu Spielen ergänzt die Lesbarkeit: „To keep text comfortably legible on each device, ensure that it contrasts well with the background and uses at least the recommended minimum text size in each platform.“ (Damit Text auf jedem Gerät bequem lesbar bleibt, achten Sie auf guten Kontrast zum Hintergrund und mindestens die empfohlene Mindesttextgröße der jeweiligen Plattform.)66
Die Spanne von Body, 14 bis 53 Punkt, reicht von etwa 82 % bis etwa 312 % seines Standards von 17; die gerundeten Größen der Box bei 3×, 13,33 bis 53,33 Punkt, liegen bei 80 % bis 320 % ihres eigenen Standards von 16,67, über den 200 %, die die Seite Accessibility verlangt.601133
Eine eigene Schrift skalieren
Apple hat drei Wege, einen Wert mit Dynamic Type zu skalieren, und einen, das zu unterbinden.
UIFontMetrics, „A utility object for obtaining custom fonts that scale to support Dynamic Type“ (ein Hilfsobjekt, um eigene Schriften zu erhalten, die zur Unterstützung von Dynamic Type skalieren), verfügbar seit iOS 11.0, mitscaledFont(for:),scaledFont(for:maximumPointSize:)undscaledValue(for:), das „Scales an arbitrary layout value based on the current Dynamic Type settings“ (einen beliebigen Layoutwert anhand der aktuellen Dynamic-Type-Einstellungen skaliert).67Font.custom(_:size:relativeTo:)in SwiftUI erzeugt eine eigene Schrift, „that scales relative to the giventextStyle“ (die relativ zum angegebenentextStyleskaliert), seit iOS 14.0.68ScaledMetric, „A dynamic property that scales a numeric value“ (eine dynamische Eigenschaft, die einen Zahlenwert skaliert), seit iOS 14.0.69Font.custom(_:fixedSize:)erzeugt eine eigene Schrift, „that does not scale with Dynamic Type“ (die nicht mit Dynamic Type skaliert), seit iOS 14.0.68
Eine Pixelschrift braucht den ersten oder dritten und den letzten Weg zusammen: die Größe lesen, die das System verwenden würde, sie auf das Raster der Schrift runden und die gerundete Größe als feste Größe setzen, damit das System sie nicht noch einmal skaliert. Die Rundung selbst ist Arithmetik, im Briefing in Abschnitt 12: Ein Schriftpixel wird zu m Gerätepixeln, m = max(m₀, ⌊size × displayScale / 10 + 0.5⌋) für ein Em von 10 Pixeln, die nächste ganze Zahl, eine Hälfte aufgerundet, wobei m₀, das kleinste m von mindestens 11 Punkt, bei 3× 4 und bei 2× 3 ist, und die Punktgröße 10 × m / displayScale. Bei 3× bildet das die zwölf Body-Größen auf m von 4, 5, 5, 5, 6, 6, 7, 8, 10, 12, 14 und 16 ab (Small, 15 Punkt, ist die einzige exakte Hälfte: 4,5 wird auf 5 aufgerundet): 16,67 Punkt bei der Standardgröße, 53,33 bei AX5.11
Um die Größe innerhalb einer Ansicht zu begrenzen, setzt oder begrenzt dynamicTypeSize(_:) (iOS 15.0) die Dynamic-Type-Größe, und seine Seite rät: „When limiting the Dynamic Type size, consider if adding a large content view with accessibilityShowsLargeContentViewer() would be appropriate.“ (Wenn Sie die Dynamic-Type-Größe begrenzen, prüfen Sie, ob eine große Inhaltsansicht mit accessibilityShowsLargeContentViewer() angebracht wäre.)70 Dieser Modifier, ebenfalls iOS 15.0, trägt seine eigene Warnung: „Don’t use the large content viewer as a replacement for proper Dynamic Type support.“ (Verwenden Sie den Large Content Viewer nicht als Ersatz für richtige Unterstützung von Dynamic Type.)71 Das Briefing begrenzt nur die Sprechblasen, die einzeilig bleiben müssen, und nie die Box.
Die Schrift mitliefern
Eine Schrift wird im App-Bundle ausgeliefert und in UIAppFonts aufgeführt, „App-specific font files located in the bundle and that the system loads at runtime“ (App-spezifische Schriftdateien im Bundle, die das System zur Laufzeit lädt) (iOS 3.2), oder im Code mit CTFontManagerRegisterFontsForURL(_:_:_:) (iOS 4.1) registriert.7273
Den Rahmen zeichnen und die Grundlinie setzen
Ein aus wenigen Tiles gezeichneter Rahmen ist ein Bild, das ohne Glättung skaliert wird. SwiftUIs Image.interpolation(_:) setzt die Interpolationsqualität, seit iOS 13.0, und Image.resizable(capInsets:resizingMode:), das „Sets the mode by which SwiftUI resizes an image to fit its space“ (den Modus festlegt, mit dem SwiftUI ein Bild an seinen Platz anpasst), dehnt oder kachelt alles außer den Ecken, ebenfalls seit iOS 13.0.7475 Das Briefing zeichnet seinen Rahmen stattdessen in einem Canvas, damit jedes Quellpixel genau m mal m Gerätepixel misst; nach meiner Lesart würde resizable(capInsets:) mit .tile ebenso gut dienen, aber nur, wenn seine Kachelung auf ganzen Gerätepixeln landet, was niemand gemessen hat.
Text.baselineOffset(_:), das „Sets the vertical offset for the text relative to its baseline“ (den vertikalen Versatz des Textes relativ zu seiner Grundlinie festlegt) (iOS 13.0), ist das Werkzeug für eine Schrift, deren Raster neben der Grundlinie liegt, wie das von PixelMplus12; Abschnitt 6 hat gemessen, dass eine Verschiebung eine solche Schrift nur bei einer Größe repariert, was ein Grund ist, warum das Briefing sie nicht verwendet.767
Japanischer Zeilenumbruch in SwiftUI und UIKit
typesettingLanguage(_:isEnabled:) (iOS 17.0) ist für Text gedacht, das „may contain text of a particular language which doesn’t match the device UI language. In that case it’s useful to specify a language so line height, line breaking and spacing will respect the script used for that language“ (Text einer bestimmten Sprache enthalten kann, die nicht zur UI-Sprache des Geräts passt; dann ist es nützlich, eine Sprache anzugeben, damit Zeilenhöhe, Zeilenumbruch und Abstände die Schrift dieser Sprache berücksichtigen). Seine Seite ergänzt: „this language does not affect text localization.“ (Diese Sprache wirkt sich nicht auf die Lokalisierung des Textes aus.)77
NSParagraphStyle.LineBreakStrategy in UIKit (iOS 9.0) hat drei benannte Strategien. standard (iOS 14.0) „uses the same configuration of line-break strategies that it uses for standard UI labels“ (verwendet dieselbe Konfiguration von Umbruchstrategien wie für Standard-UI-Labels) und „may be unsuitable for large amounts of text“ (kann für große Textmengen ungeeignet sein); pushOut (iOS 9.0) soll „an orphan word on the last line“ (ein verwaistes Wort in der letzten Zeile) vermeiden; hangulWordPriority (iOS 14.0) ist für Koreanisch.78
Abschnitt 7 hat gemessen, dass Core Text unter macOS mit der Kennung ja in den meisten Schriften bei 6 von 7 Breiten kleine Kana Zeilen beginnen ließ (4 von 7 in k8x12 und k8x12S) und ohne Kennung nicht.7 Was SwiftUIs Text mit Japanisch macht, wenn die Gerätesprache Japanisch ist, und ob typesettingLanguage dasselbe Attribut setzt wie die Messung, wurde nicht gemessen (Abschnitt 11). Das Briefing lässt Boxtext daher ohne Kennung, es sei denn, eine Aufnahme zeigt, dass die strenge Regel mit der Kennung hält.
VoiceOver über einer Bühne
SwiftUIs Bedienungshilfe-Modifier beschreiben eine Ansicht: accessibilityLabel(_:) benennt sie, und accessibilityValue(_:) fügt ihren Wert hinzu, mit einer Regel in seiner Dokumentation: „Use this method to describe the value represented by a view, but only if that’s different than the view’s label.“ (Verwenden Sie diese Methode, um den Wert zu beschreiben, den eine Ansicht darstellt, aber nur, wenn er sich vom Label der Ansicht unterscheidet.) Beide sind iOS 16.0 in der Form mit LocalizedStringResource, die die Seiten aufführen.79
Die Bühne eines Spiels braucht mehr als ein Label. accessibilityDirectTouch(_:options:) (iOS 17.0) schafft einen Bereich, in dem „Direct touch areas passthrough touch events to the app rather than being handled through an assistive technology, such as VoiceOver“ (Bereiche mit direkter Berührung Berührungsereignisse an die App durchreichen, statt sie von einer assistiven Technologie wie VoiceOver verarbeiten zu lassen), nachdem der Nutzer ihn aktiviert hat.80 AccessibilityTraits.updatesFrequently (iOS 13.0) ist für ein Element, das sich ändert: „Use this trait when you want an assistive technology to poll for changes when it needs updated information.“ (Verwenden Sie dieses Merkmal, wenn eine assistive Technologie Änderungen abfragen soll, sobald sie aktuelle Informationen braucht.)81 AccessibilityNotification.Announcement (iOS 17.0) gibt eine gesprochene Ankündigung aus, mit einem Attribut accessibilitySpeechAnnouncementPriority, das festlegt, wie sie sich gegenüber anderer Sprachausgabe einreiht.82 Und accessibilityReduceMotion (iOS 13.0) meldet die Einstellung „Bewegung reduzieren“ (Reduce Motion), die laut ihrer Seite bedeutet, dass „UI should avoid large animations“ (die UI große Animationen vermeiden sollte).83
RealityKit kann die Entitäten selbst beschreiben. AccessibilityComponent (iOS 17.0) ist „A component that stores accessibility information for an entity“ (eine Komponente, die Bedienungshilfe-Informationen für eine Entität speichert), deren Name das ist, was „VoiceOver says aloud when it describes the entity“ (VoiceOver laut sagt, wenn es die Entität beschreibt).84 Apples Artikel „Improving the Accessibility of RealityKit Apps“ rät, „set the properties on each visible Entity in your scene“ (die Eigenschaften jeder sichtbaren Entity in Ihrer Szene zu setzen): die eigenen Bedienungshilfe-Eigenschaften von Entity, isAccessibilityElement, accessibilityLabel und accessibilityDescription, die der Artikel auf iOS 14 datiert und deren Seiten inzwischen als veraltet markiert sind, alle außer isAccessibilityElement (die Seite führt auch accessibilityLabelKey auf, ein Label als lokalisierter String-Schlüssel), ein älterer Weg neben der Komponente.85 RealityView, die SwiftUI-Ansicht, die die Bühne von Kiradex nutzt, ist iOS 18.0.86 Ob eine RealityView mit einer virtuellen orthografischen Kamera, wie Kiradex sie einrichtet, diese Entitäten für VoiceOver sichtbar macht, ist auf diesen Seiten nicht dokumentiert und wurde nicht getestet (Abschnitt 11).
Das Testen lässt sich inzwischen automatisieren. XCUIVoiceOverService „Provides programmatic control of VoiceOver for UI testing“ (bietet programmatische Steuerung von VoiceOver für UI-Tests), verfügbar ab iOS 27.0, und ist über die Eigenschaft voiceOverService von XCUIDevice erreichbar.87
Kiradex heute
Am 5. Oktober 2026 aus dem Repository gelesen, bei Commit 334fbfe mit den nicht eingecheckten Änderungen dieses Tages, von mir nie ausgeführt oder verändert; die App wurde bearbeitet, während ich sie las (Abschnitt 11):11
- Eine Schrift, die des Systems. Die Schriftfamilie des Themes ist
.systemDesign(.monospaced), und die Ansichten der Welt nutzen die Rollen des Kits: Caption an 10 Aufrufstellen in vier Dateien, Label an 3, Body an 3 und Title an 3.2411 - Ein Pfad für eigene Schriften, der stufenlos skaliert.
Kit941.FontFamily.custom(named:)aus dem gemeinsamen Kit löst zuFont.custom(_:size:relativeTo:)mit 34, 22, 17, 13 und 12 Punkt für Display, Title, Body, Label und Caption auf.88 Mit einer Pixelschrift würde das durch jede Dynamic-Type-Größe skalieren, was Abschnitt 6 bei 9 von 12 Body-Größen für ein Em von 12 Pixeln und bei 11 von 12 für ein Em von 10 Pixeln als neben dem Raster zählt.7 - Die Sprechblase.
Text(text).kit941Font(.caption, weight: .bold), Tinte aufWorldInk.paper(eine Grafikfläche mit zwei festen Farben), quer mit dem kleinen Abstand des Kits gepolstert und vertikal mit dem extra kleinen, mit einem 2 Punkt breiten Tintenrand und.fixedSize(), also einzeilig. Sie sitzt eine große Abstandsstufe überrig.headPoint, ist sichtbar, solange die Zeile jünger als 4 Sekunden ist, und trägt das Label"Said: \(text)"in einem Overlay mit ausgeschalteter Trefferprüfung. Dieses Overlay sitzt in der Bühne, unter den beiden Overlays, die die Bühne über die ganze Szene legt: Scanlines, eine schwarze Linie mit 16 % Deckkraft alle 3 Punkt, und eine Vignette.2511 - Die Box.
WorldHUDsetzt den Titel des Ortes (Caption, fett, in Großbuchstaben) und den Status (Caption, halbfett) in eine cremefarbene Box mit demselben 2-Punkt-Rand am unteren Bildschirmrand; halb geöffnet, auf dem Duo, hält sie sich an die breitere Seite des Falzes. Sie nimmt keine Taps an (.allowsHitTesting(false), „Taps go through to the ground under it“, Taps gehen zum Boden darunter durch), und sie liegt über der ganzen Bühne, über den Scanlines und der Vignette.26 - Was gesagt wird. 23 vorgegebene Zeilen auf dem Server, 3 bis 40 Zeichen, Median 16; die längste ist „Anyone have a card from the first years?“ (Hat jemand eine Karte aus den ersten Jahren?). Handles sind zwei Wörter aus Listen von 20 und 20 und vier Ziffern, höchstens 20 Zeichen („Glacier Shuffle 0000“). Über dem Kopf eines Sammlers wird nichts gezeichnet außer der Sprechblase; das Handle steht in dem Panel, das ein Tap öffnet.288911 Der Beitrag dieser Reihe über das Eigenleben der Stadt zählte dieselben 23 Zeilen und ein Serverlimit von einer Zeile alle 2,0 Sekunden pro Spieler.9091
- Keine Schrift, eine Sprache. Keine Schriftdatei wird mitgeliefert (die einzige
.ttfim Repository istscripts/screenshots/MartianMono-latin.ttf, für das Screenshot-Werkzeug); dieknownRegionsdes Projekts sindBaseunden, und es gibt keine.xcstrings- oder.lproj-Datei.1127 - VoiceOver hört Koordinaten. Die Bühne ist ein Element,
.accessibilityLabel("The plaza")und.accessibilityValue(stepTrace), wobeistepTraceder letzte Schritt als „x,y facing“ (x,y Blickrichtung) ist, beibehalten, weil „the walks read it, since nothing else the simulator logs reaches them“ (die Lauftests ihn lesen, da nichts anderes, was der Simulator protokolliert, sie erreicht). KeinAccessibilityComponent,accessibilityDirectTouch,AccessibilityNotification,typesettingLanguage,UIFontMetrics,ScaledMetricoderdynamicTypeSizekommt irgendwo im Quellcode der App vor.2511 - Schilder ohne Buchstaben.
sign()der Schmiede ist „A hanging sign on a bracket, 12 × 11“ (ein hängendes Schild an einer Halterung, 12 × 11), dessen Fläche zwei Reihen Tintenstriche trägt, keine Buchstaben; die Karte des Platzes hat ein Schild-Tile,S. Ein Finger auf dem Boden lässt die Spielfigur sofort zum Tile darunter gehen und wird über Tiles hinweg verfolgt; ein Tap auf einen Sammler öffnet beim Anheben des Fingers dessen Panel, einer auf den Kiosk das Brett der Stadt; ein Schild-Tile ist Boden wie jeder andere, ohne eigenen Tap.2992 - Der Maßstab der Welt. Nach der Regel von
PlazaRig.fit, der abgerundeten Pixelhöhe der Ansicht geteilt durch 320, misst ein Texel 8 Gerätepixel auf dem iPhone 18 Pro Max (440 mal 956 Punkt) und auf dem inneren Display des Duo im Hochformat, 6 auf dem äußeren Display des Duo im Hochformat und dem inneren im Querformat und 4 auf dem äußeren im Querformat: 2,67, 2,00 oder 1,33 Punkt.9311
Warum der Text außerhalb der Welt bleibt
Die Arithmetik des Welt-Beitrags dazu stimmt: „At k = 8 on a 3× display a five-texel font is 13.3 points and at k = 6 it is 10 points, under the HIG’s 11-point minimum“ (bei k = 8 auf einem 3×-Display ist eine Schrift von fünf Texeln 13,3 Punkt groß und bei k = 6 10 Punkt, unter dem Minimum von 11 Punkt der HIG).23 Sie betrifft nur Schriften unter 5,5 Texeln bei k = 6 (11 Punkt bei 2 Punkt pro Texel); ein Em von 8 Texeln ist bei k = 6 16 Punkt groß.1133 Die Schlussfolgerung, Text im UI-Maßstab in SwiftUI, gilt aus einem anderen Grund: In Weltdichte ist ein Em von 10 Pixeln auf einem Telefon mit 8 Gerätepixeln pro Texel 26,67 Punkt groß, womit eine Zeile der Box auf dem 18 Pro Max noch 29 lateinische Zeichen fasst.11 In Tiles gemessen ist die Box des Kanons schmal. Eine Box von 16 Hardware-Tiles Breite, 128 Pixeln, fasst 16 Zeichen einer Schrift von 8 mal 8, etwa 24 lateinische Zeichen von Smaragd bei seinem Mittel von 5,25 Pixeln (21 im ungünstigsten Fall von 6), 16 japanische Zeichen von Smaragd zu 8 Pixeln und 10 japanische Zeichen von Final Fantasy VI zu 12 Pixeln. Sechzehn der 16-Texel-Tiles von Kiradex sind 256 Texel, die in der eigenen Dichte der Welt 42 lateinische Zeichen und 21 Kana von PixelMplus12 fassen, oder 64 und 32 von Misaki.11 Und eine Box, in den eigenen Tiles von Kiradex bemessen, passt in drei der fünf gemessenen Ansichten nicht: 16 Tiles zu 16 Texeln sind bei 8 Gerätepixeln pro Texel 683 Punkt, breiter als das iPhone 18 Pro Max (440 Punkt) und das innere Display des Duo im Hochformat (669), und bei 6 sind es 512 Punkt, breiter als das äußere Display des Duo im Hochformat (466). Sie passt nur in die beiden Ansichten im Querformat: 512 Punkt in die 951 des inneren Displays und 341 Punkt bei 4 Gerätepixeln pro Texel in die 678 des äußeren.11 Eine Box in Kiradex wird in Punkten bemessen, nicht in Tiles.
Dieselbe Arithmetik bei der Größe des Briefings: PixelMplus10 bei m = 5, 16,67 Punkt, fasst in der Box auf einem 18 Pro Max im Hochformat 47 lateinische oder 23 japanische Zeichen pro Zeile, nach dem heutigen Einzug von 48 Punkt, 16 Punkt Rand und 8 Polsterung pro Seite, gerechnet von der vollen Breite, ohne seitliche Einzüge (angenommen, nicht gemessen). Die Box sitzt im sicheren Bereich, auf dem äußeren Display des Duo im Hochformat hängt die Zahl also von seinem seitlichen Einzug ab: 50 oder 25 ohne Einzug und 40 oder 20 mit dem nachlaufenden Einzug von 84 Punkt, der Seitenschiene, den diese Reihe am geschlossenen Display gemessen hat (Abschnitt 11). Unter dem Rahmen des Briefings (Abschnitt 12, Punkt 3), der anstelle der Polsterung 8 Schriftpixel pro Seite belegt und die Box auf ganze Schriftpixel abrundet, fassen dieselben Zeilen 45 oder 22 auf dem 18 Pro Max und 48 oder 24, mit der Schiene 38 oder 19, auf dem Duo.119495
Aufwand
Nichts davon wurde auf einem Gerät gemessen. Eine Schrift mit 7.253 Glyphen mitzuliefern fügt der App ihre Datei hinzu;7 Text über SwiftUI in einer eigenen Schrift zu zeichnen kostet, was jedes Text kostet; und der Rahmen des Briefings ist ein Canvas, der neu zeichnet, wenn sich seine Größe ändert. Nach meiner Lesart ist nichts davon groß neben einer RealityKit-Szene, aber das ist eine Lesart, und die Aufnahmen des Briefings sind der Ort, an dem sie geprüft wird.
11. Was gemessen ist und was nicht
Alles Bezifferte in diesem Beitrag stammt aus Skripten, die gegen gespeicherte Quellen erneut laufen, aus Seiten, die am 5. Oktober 2026 gespeichert wurden, oder aus datierten Lesungen des Kiradex-Quellcodes; die Anmerkungen sagen, woraus. Dieser Abschnitt ist die Liste dessen, was das nicht abdeckt.30
Am Quellcode gemessen, erneut ausführbar. measure_gen_text.py gegen die vier Dekompilierungen von pret: die Schrifttabelle von Smaragd (zehn Einträge, sieben Schriften); Texttempo in Frames und Zeichen pro Sekunde; das Scrollen; der Weiterpfeil; das Fenster von 27 mal 4 und der Rahmen von 30 mal 6; die 20 wählbaren Rahmen; lateinische Glyphenbreiten; 24.100 Skriptzeilen in Zeichen und Pixeln; 934 von 14.412 Absätzen, die einen Sprecher nennen; die japanischen Glyphen-Sheets; Verzögerungen und Fenster von Feuerrot; Bildschirme, Boxen, Verzögerungen, Rahmen und Schrift-Sheets von Kristall und Rot.1 measure_ff6.py gegen die ff6-Disassemblierung: Fensterstile und Paletten, Zelle und Breiten der Dialogschrift, Größe und Breitenläufe der japanischen Schrift, die 220-Pixel-Zeile, ein Buchstabe pro Frame, der Titel mit 100 Frames, der Wortumbruch, der Konfigurationsbildschirm und die Verlaufstabelle des Fensters.4 measure_bdf.py gegen die BDF-Dateien von Misaki und k8x12.6 measure_coretext.swift und measure_outline_coords.swift, kompiliert und ausgeführt unter macOS 27.0, gegen zehn TrueType-Dateien und Hiragino Sans.719 measure_kiradex_text.py gegen Kiradex, wie es bei Commit 334fbfe auf der Festplatte lag (am 15. Oktober gegen den aktuellen Baum erneut ausgeführt, seine früheren Zeilen unverändert), und measure_figure_width.py gegen sein Körper-Sheet.1196 measure_hig.py, measure_steam_languages.py und measure_apple_docs.py gegen die gespeicherten Seiten.606465 measure_ios27_iphones.py gegen die iPhone-Liste der Simulator-Runtime von iOS 27.0, und probe_line_start_glyphs.swift, kompiliert und ausgeführt unter macOS 27.0, gegen die Klassentabellen von JLREQ und PixelMplus10.9798 measure_cell_masks.py gegen die gespeicherten Sheets von pret: die Zellmasken-Referenz des Briefings.99 Das sind dreizehn Skripte; ein vierzehntes, dump_glyphs.swift, bei den Abbildungen dieses Beitrags abgelegt, zeichnete PixelMplus10 in seiner eigenen Größe mit ein- und ausgeschalteter Schriftglättung.9
Nicht gemessen, oder schwächer, als es aussieht.
- Core Text unter macOS steht für iOS. Jede Rendering- und Umbruchzahl in den Abschnitten 6 und 7 stammt aus dem Core Text von macOS 27.0, das bei ausgeschalteter Schriftglättung in einen Bitmap-Kontext zeichnet, nicht aus SwiftUI auf einem iPhone. Die Aufnahmeprüfungen des Briefings sind die Messung, die zählt; bis sie laufen, ist das, was ein iPhone zeichnet, eine Vorhersage.79
- Bitmap-Strikes. Misaki und k8x12 tragen
EBDT- undEBLC-Tabellen; ob Core Text bei 8 und 12 Pixeln diese Bitmaps oder die Konturen zeichnete, wurde nicht ermittelt.7 - Die eigene Platzierung von SwiftUI. Ob SwiftUI die Ursprünge von
Textauf ganze Gerätepixel setzt und welche Umbruchregel es auf Japanisch anwendet, wenn die Gerätesprache Japanisch ist, wurde nicht gemessen. - Schnitte. PixelMplus10 Bold ist der einzige gemessene fette Schnitt; synthetisches Fett auf einer Pixelschrift wurde nicht gemessen.7
- Lesbarkeit. Raster und Abdeckung sind gemessen; ob Kanji von 10 mal 10 bei 16,67 Punkt für japanische Leser gut lesbar sind, nicht, und dafür braucht es eine japanische Leserin oder einen japanischen Leser auf einem Gerät.
- Japanische ROMs. pret baut die englischen Spiele. Box, Tempi und Schrift des japanischen Smaragd selbst wurden nicht gelesen; die japanischen Sheets in Abschnitt 1 sind die, die das englische ROM für Namen mitführt. Japanisches Kristall und Rot wurden nicht gelesen.30
- Die Grafiken von Final Fantasy VI. Die Disassemblierung enthält Bereiche und Code, keine Pixel; die Anordnung der Fenster-Tiles und das Aussehen des Verlaufs wurden nicht gesehen. Der Bereich der englischen großen Schrift, 5.120 Bytes, ist keine ganze Zahl von 22-Byte-Buchstaben, ungeklärt. Dass die Verlaufstabelle mit einem Wert pro Scanline verbraucht wird, stammt aus Kommentaren, nicht aus einer Verfolgung.4
- Die Blinkperiode von Kristall wurde nicht abgeleitet; ihre beiden Zustände wurden aus dem Code gelesen.16
- Chrono Trigger wurde überhaupt nicht gemessen. Keine öffentliche Disassemblierung wurde geklont, und die ROM-Karte bei Data Crystal lieferte HTTP 403.49
- Celeste, Sea of Stars und Eastward. Nur ihre Sprachlisten auf Steam; wie sie japanischen und chinesischen Text zeichnen, fand sich in keiner Entwicklerquelle.64
- Pixel Operator, m5x7 und m3x6 wurden weder heruntergeladen noch gemessen, und das eigene Repository von Pixel Operator lieferte HTTP 404; ihre Lizenzen sind so, wie ihre Seiten sie angeben, die von Pixel Operator allein nach DaFont.565758
- Die drei nicht abgebildeten JIS-Codepoints von PixelMplus wurden an ihren alternativen Codepoints nicht geprüft.7
- Die Größe von DotGothic16. Sie hat kein Pixelraster, sie wurde also nominell mit 16 Punkten pro Em und Vielfachen davon gezeichnet und gesetzt, meine Wahl nach ihrem Namen und ihrem Punktabstand; keine andere nominelle Größe wurde versucht, und ihre Zahlen in den Abschnitten 6 und 7 gelten nur für diese Größen.719
- Schriftglättung. Die Renderings in Abschnitt 6 schließen alle Schriftglättung aus; mit der Voreinstellung des Bitmap-Kontexts wurde nur eine Schrift in einer Größe gezeichnet, PixelMplus10 bei 10 Pixeln, 178 von 272 Tintenpixeln Teilpixel. Die anderen Schriften und Größen wurden nicht mit eingeschalteter Glättung gezeichnet.9
- Die App änderte sich, während ich sie las. Kiradex wurde am 5. Oktober bearbeitet, während dieser Beitrag entstand. Früher an diesem Tag wurde die Tap-Verarbeitung der Bühne neu geschrieben und ihre Zeilen verschoben sich um 30 bis 144, und drei der Swift-Dateien der Welt waren noch in keinem Commit; vierzehn Minuten nach meiner Lesung hatten sich Bühne und Rig erneut geändert. Der Beitrag liest Commit
334fbfemit den nicht eingecheckten Änderungen dieses Tages, so wie sie standen, als ich sie las: die Dateien der App um 12:28 Uhr pazifischer Zeit (die Sammler des Servers und die Stadtkarte um 12:33), die Skripte, die sie messen, um 12:34 und 12:36. Die Anmerkungen geben die Zeilen jeder Datei zu dieser Lesung an; das Briefing nennt Symbole statt Zeilen, und ich habe um 12:42 geprüft, dass jedes Symbol, das es nennt, noch vorhanden war.11 - Die iPhones, auf denen die App läuft. Die Liste von 33 iPhones, drei davon 2×, ist die der Simulator-Runtime von iOS 27.0, aus Xcode auf meinem Mac gelesen; Apples Seite mit den von iOS 27 unterstützten iPhones wurde nicht abgerufen.97
- Einzüge des sicheren Bereichs. Der Beitrag dieser Reihe zum iPhone-Duo-Simulator hat das geschlossene äußere Display gemessen, 466 Punkt breit, mit seinem Inhalt 382 Punkt breit innerhalb eines nachlaufenden Einzugs von 84 Punkt, der Seitenschiene, in einer Messung, die die Statusleiste, eine Symbolleiste und eine Tableiste zeigte.95 Die Welt von Kiradex blendet die Statusleiste und den Home-Indikator aus und zeigt keine Leisten; der Code legt die Bedienelemente der Welt in den sicheren Bereich und sagt, dass sie dadurch Kameras und Seitenschiene freihalten, aber weder der Code noch jene Messung sagt, wie breit der Einzug bei ausgeblendeter Statusleiste ist; die Zahlen des Duo in den Abschnitten 10 und 12 stehen daher in beiden Varianten da, ohne seitlichen Einzug und mit den gemessenen 84 Punkt. Die seitlichen Einzüge der anderen iPhones im Hochformat wurden nicht gemessen; die Zahlen des Briefings für sie nehmen keine an.94
- RealityKit-Bedienungshilfen im Aufbau von Kiradex.
AccessibilityComponentist für iOS 17.0 dokumentiert; ob eineRealityViewmit einer virtuellen orthografischen Kamera Entitätselemente für VoiceOver sichtbar macht, ist unbestätigt.84 - Die Zahlen des Briefings. Die Rundung von
m, die Sprechblase eine Stufe kleiner als die Box und unter einer Obergrenze gehalten, die jede Ansicht setzt, der Rand von 32 Punkt, die Warteschlange der Box und ihre drei Zeilen, die 8 Schriftpixel des Rahmens anstelle der Polsterung der Box, die Markenschritte von 150 Millisekunden, vier Rahmen und sechs Zellen für Ankündigungen sind Vorschläge, keine Tatsachen.
Wo dieser Beitrag vom Welt-Beitrag abweicht. Die Abschnitte 1, 2, 5 und 8 korrigieren jeweils eine Aussage darin, mit der Messung; seine Größenarithmetik stimmt (Abschnitt 10). Drei Tatsachen, die dieser Beitrag aus den anderen Beiträgen der Reihe übernimmt, wurden an der App geprüft: Die 23 vorgegebenen Zeilen der Stadt stimmen mit lines.py überein; die Anmerkung des Figuren-Beitrags, dass die Sprechblase ihren Platz noch aus der Höhe der Zelle bezieht, stimmt mit PlazaRig.headPoint überein, das zur Position der laufenden Figur die halbe Framehöhe des Sheets und 4 addiert; und die Figur unter der Sprechblase ist die, die das Update jenes Beitrags beschreibt, 30 Texel hoch in einer Zelle von 32 mal 40, was das Manifest der App, rig.py und das Körper-Sheet bestätigen. Jener Beitrag nennt eine Breite nur für seine frühere Figur von 26 Texeln, etwa 14 an den Schultern; Abschnitt 12 misst die Breite der aktuellen Figur am Sheet.90100289396
Nicht erreichte Quellen. Die ROM-Karte von Chrono Trigger bei Data Crystal (HTTP 403); das Repository von Pixel Operator bei NotABug (HTTP 404); die Schriftdateien von m5x7 und m3x6 (hinter einem Download mit frei wählbarem Preis, nicht versucht); und eine Entwicklerquelle zum japanischen und chinesischen Text von Celeste, Sea of Stars oder Eastward (nicht gefunden).49565758
12. Das Briefing: was Kiradex baut und welche Prüfungen es bestehen muss
Die App ist seitdem weitergezogen. Bei Commit fc9d4876 vom 15. Oktober werden Label und Wert der Bühne in einem View-Modifier StageAccessibility gesetzt (PlazaStage.swift, angewendet in Zeile 373, definiert ab Zeile 520), weiterhin „The plaza“ mit der Schrittspur als Wert, und das Element fehlt, solange ein Ort die Bühne verdeckt. Die Prüfungen unten lesen den Stand vom 5. Oktober, und jedes „heute“ meint diesen Stand; Punkt 8 gilt für beide.101
Synthese des Autors. Was folgt, ist mein Vorschlag, abgeleitet aus den Abschnitten 1 bis 11 und als Differenz zu Kiradex geschrieben, wie es am 5. Oktober 2026 stand, bei Commit 334fbfe mit den nicht eingecheckten Änderungen dieses Tages im Arbeitsverzeichnis (Abschnitt 11): monospaced Systemtext in jeder Weltansicht, eine einzeilige Sprechblase in Caption fett, die WorldHUD-Box am unteren Rand, eine nur englische App mit englischen vorgegebenen Zeilen auf dem Server, ein Schild-Sprite ohne Buchstaben und eine Bühne, die VoiceOver als Koordinaten liest.2211 Die Richtung des Welt-Beitrags steht: Text ist Grafik; Dialog lebt in SwiftUI im UI-Maßstab, nicht in den Texeln der Welt; eine Box aus Tiles; zwei Zeilen; eine Schreibmaschine; eine Weitermarke.23 Was sich ändert, ist die Schrift, aus dem Grund, den Abschnitt 5 nennt, und die Arithmetik, weil Dynamic Type auf das Raster der Schrift gerundet werden muss.7 Nichts hier zeichnet eine Glyphe, einen Rahmen, eine Marke oder ein Wort eines Franchise; alles wird von der Schmiede gezeichnet oder in einer Schrift gesetzt, deren Lizenz in Abschnitt 4 zitiert ist. Die rechtlichen Hinweise sind meine Lesarten, keine Rechtsberatung. Nichts davon ist gebaut.
Jede Prüfung unten kann ein Skript, eine Logzeile eines Tests oder eine Aufnahme bestehen oder verfehlen lassen, bis auf eine datierte manuelle Prüfung auf einem Gerät in Punkt 8. Wo das Ergebnis einer Prüfung vom Gerät, der Textgröße, der gewählten Zeile oder dem abhängt, was die Box sonst zeigt, nennt sie diese. Das Briefing benennt den Code der App über seine Symbole, nicht über Zeilennummern, weil sich der Code bewegte, während ich ihn las; die Anmerkungen geben die Zeilen so an, wie ich sie gelesen habe, mit Commit und Uhrzeit. Wo der Beleg hinter einem Punkt eine Messung auf meinem Mac ist und die Prüfung auf einem iPhone oder seinem Simulator läuft, entscheidet die Prüfung, nicht der Mac.
1. Eine Schrift für beide Sprachen: PixelMplus10
Was. PixelMplus10-Regular.ttf und PixelMplus10-Bold.ttf (von itouhiro, aus den M+ BITMAP FONTS des M+ FONTS PROJECT; Lizenz: M+ FONT LICENSE, https://github.com/itouhiro/PixelMplus/blob/master/misc/mplus_bitmap_fonts/LICENSE_E) über UIAppFonts mitliefern, mit LICENSE_E im Bundle, und den Einstellungen, die heute keine haben, einen Abschnitt mit Danksagungen hinzufügen, der itouhiro und das M+ FONTS PROJECT nennt.1872 Sie für jedes Wort verwenden, das über der Welt gezeichnet wird: Sprechblasen, die WorldHUD-Box, Schildtext, das Questbrett und die Schilder der Vorzeigerunde. Der Rest der App, der Dex, der Scanner und die Einstellungen, behält die Systemschrift.
Warum diese. Zwei gemessene Schriften haben alle drei Dinge, die die Regeln in Abschnitt 9 verlangen: Japanisch, ein sauberes Raster und ganze Pixelvorschübe. Misaki Gothic und Misaki Gothic 2nd zeichnen alle 6.879 Zeichen von JIS X 0208 auf einem 8-Pixel-Raster auf der Grundlinie, mit 0 von 848 und 0 von 860 erfassten Konturkoordinaten daneben und Vorschüben von 4 und 8. PixelMplus10 zeichnet 6.876 der 6.879, jedes Kanji beider Stufen, auf einem 10-Pixel-Raster auf der Grundlinie, mit 0 von 1.032 erfassten Konturkoordinaten daneben im Regular und 0 von 1.000 im Bold, mit Vorschüben von 5 für Latein und 10 für Kana.7 Das Briefing nimmt PixelMplus10, meine Wahl: Sie ist die größere der beiden, 10 Pixel gegenüber den 8 von Misaki, und die Kanji von 8 mal 8 in Misaki sind die, deren Lesbarkeit für japanische Leser am meisten in Zweifel steht (Abschnitt 11); und sie kommt mit einem gemessenen Bold, fetter Text braucht also keine Synthese. Abgelehnt, jeweils mit der Messung, die ablehnt:
- PixelMplus12 (M+ FONT LICENSE): Sein Raster liegt 0,39 Pixel unter der Grundlinie, und Core Text unter macOS 27.0 verschmierte es bei jeder Größe.7
- k8x12 (die Lizenz aus drei Sätzen auf littlelimit.net, https://littlelimit.net/font.htm#license): Sein Kana-Vorschub beträgt 8,01 Pixel, und seine lateinischen Buchstaben sind 4 Pixel breit.717
- Misaki (dieselbe Lizenz, https://littlelimit.net/font.htm#license): Sie hat alle drei Eigenschaften, aber sie hat die kleinsten gemessenen Kanji, 8 mal 8, und ist die, deren Lesbarkeit für japanische Leser am meisten in Zweifel steht (Abschnitt 11).617
- DotGothic16 (SIL Open Font License 1.1, https://github.com/google/fonts/blob/main/ofl/dotgothic16/OFL.txt): Ihre Punkte liegen auf keinem Raster, und Core Text unter macOS 27.0 zeichnete sie bei 16 bis 64 Pixeln mit 37,3 % bis 82,3 % Teilpixeln.753
- Press Start 2P (SIL Open Font License 1.1 mit Reserved Font Name, https://github.com/google/fonts/blob/main/ofl/pressstart2p/OFL.txt) und Silkscreen (SIL Open Font License 1.1, https://github.com/google/fonts/blob/main/ofl/silkscreen/OFL.txt): kein Japanisch.75455
- m5x7 (ihre Seite: „Creative Commons Zero v1.0 Universal“, https://managore.itch.io/m5x7) und m3x6 (ihre Seite: „free to use with attribution“ (frei nutzbar mit Namensnennung), kein Lizenzfeld, https://managore.itch.io/m3x6): nicht gemessen; nach den Beschreibungen ihrer eigenen Seiten lateinisch; hinter einem Download mit frei wählbarem Preis.5758
- Pixel Operator (CC0 1.0 laut den Notizen ihres Autors bei DaFont, https://www.dafont.com/pixel-operator.font): nicht gemessen; 241 Glyphen bei DaFont, viel zu wenige für Japanisch.56
Das Kit. Das gemeinsame Kit meiner Apps leitet jeden Textstil über .kit941Font(role), und sein Pfad für eigene Schriften skaliert eine Schrift stufenlos, was diese Schrift bei 11 von 12 Body-Größen neben ihr Raster legen würde, die Bedingung, unter der Core Text auf dem Mac sie verschmierte.887 Die Welt ist bereits eine erklärte Grafikfläche, WorldInk, mit ihren eigenen zwei Farben.25 Einen Kiradex-eigenen Modifier PixelText hinzufügen, mit einem Kommentar als Ausnahme dieser Grafikfläche deklariert, der eine Rolle des Kits entgegennimmt und die Rundung aus Punkt 2 anwendet; ihn erst nach der Auslieferung als Fall einer Kit-Familie upstream vorschlagen.
Keine synthetischen Schnitte. Fetter Text verwendet PixelMplus10-Bold; kein .weight(_:) auf der Pixelschrift, weil nicht gemessen wurde, was Core Text mit einem Schnitt macht, den es synthetisieren muss (Abschnitt 11).
Prüfungen.
- Ein Unit-Test, da Core Text unter iOS vorhanden ist, lädt beide mitgelieferten Dateien und prüft: Einheiten pro Em 1.000; jede Glyphe, die die Strings der Welt und die vorgegebenen Zeilen in beiden Sprachen verwenden, hat einen Vorschub, der ein Vielfaches von 100 Einheiten ist; die Konturpunkte der Beispielglyphen liegen innerhalb von 4 Einheiten des 100-Einheiten-Rasters (0,04 Schriftpixel, die Toleranz, die die Messung in Abschnitt 4 verwendete). Eine Schrift, die durchfällt, kann nicht ausgeliefert werden.
- Ein Test, dass jeder String, den die Welt zeigen kann (vorgegebene Zeilen, die Weltschlüssel des String Catalog, Schildtexte), auf Glyphen der Schrift abgebildet wird, ohne Fallback-Schrift.
- Ein Skript in einer Build-Phase, das LICENSE_E im gebauten App-Bundle findet, und ein UI-Test, der den Namen der Schrift, ihren Autor und ihre Lizenz im neuen Danksagungsabschnitt der Einstellungen findet.
2. Größen: Dynamic Type, auf das Raster gerundet
Was. Ein Schriftpixel ist immer eine ganze Zahl m von Gerätepixeln. Für eine Rolle die Dynamic-Type-Größe lesen, die das System verwenden würde (UIFontMetrics(forTextStyle:).scaledValue(for:) oder @ScaledMetric(relativeTo:) auf der Grundgröße der Rolle), diese Größe auf ein Hundertstel Punkt runden, damit ein skalierter Wert knapp unter einer Tabellengröße, 14,999… für 15, so rundet wie die Tabellengröße, dann m = max(m₀, ⌊size × displayScale / 10 + 0.5⌋) setzen, die nächste ganze Zahl, eine Hälfte aufgerundet, wobei m₀ = ⌈11 × displayScale / 10⌉ das kleinste m von mindestens 11 Punkt ist, und pointSize = 10 × m / displayScale, und das mit Font.custom(_:fixedSize:) anwenden, damit das System nicht noch einmal skaliert.676968 Titel und Text der Box wechseln von der Caption-Rolle, die sie heute nutzen, zur Body-Rolle, sodass die Box bei 3× die zwölf Body-Größen auf m = 4, 5, 5, 5, 6, 6, 7, 8, 10, 12, 14 und 16 abbildet: 16,67 Punkt bei der Standardgröße und 53,33 bei AX5.2611 Die kleinste, m₀ = 4 bei 3×, entspricht 13,33 Punkt, über dem Minimum von 11 Punkt.1033 Bei 2×, was der Simulator von iOS 27.0 für drei iPhones aufführt (Punkt 4), ist m₀ 3, 15 Punkt, und die zwölf Body-Größen ergeben 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9 und 11: 15 Punkt bei der Standardgröße.9711 Sprechblasen verwenden eine Stufe weniger, nie unter m₀ und nie über einer Obergrenze, die jede Ansicht setzt (Punkt 4).
Platzierung. Eine Pixelschrift ist nur scharf, wenn ihre Grundlinie auf einem Gerätepixel landet (Abschnitt 6). Jeden berechneten Ursprung im Overlay der Welt auf das Gerätepixelraster runden, (x × scale).rounded() / scale, einschließlich der .position von PlazaStage.bubbles, und Textansichten Breiten in ganzen Gerätepixeln geben, der Box eine Breite und Höhe in ganzen Schriftpixeln (Punkt 3).
Zeilenabstand. PixelMplus10 reicht 9 Schriftpixel nach oben und 2 nach unten; den Zeilenabstand auf 12 Schriftpixel setzen, eine leere Reihe zwischen den Zeilen, so wie die 15-Pixel-Glyphen des Japanischen und die 16-Pixel-Zelle des Lateinischen in Smaragd in einer 16-Pixel-Zeile sitzen.71 Bei m = 5 sind das 20 Punkt pro Zeile.33
Prüfungen.
- Ein Test der Rundung als reine Funktion für jede DynamicTypeSize bei den Display-Skalierungen 2 und 3: Das Ergebnis ist eine ganze Zahl von Gerätepixeln pro Schriftpixel, nie unter 11 Punkt und für eine größere Größe nie kleiner. Der Test füttert die Funktion direkt mit den Body-Größen aus der Tabelle der HIG, nicht mit aus scaledValue(for:) gelesenen Werten, dessen genaue Ausgabe ich nicht gesehen habe: Bei 3× ergeben die zwölf die zwölf Werte oben, die 4,5 von Small werden auf 5 aufgerundet, und bei 2× die zwölf 2×-Werte; jede Größe minus ein Milliardstel Punkt ergibt durch die Rundung auf ein Hundertstel dasselbe m.11
- Aufnahmen des Platzes mit einer Sprechblase und der Box bei Large, xxxLarge und AX3 im Simulator des iPhone 18 Pro Max und bei Large im Simulator des iPhone SE (3. Generation) bei 2×, mit dem Sprechblasen-Overlay über die Scanline- und Vignetten-Overlays der Bühne verlegt (Punkt 4), und ein Skript, das den Text zuschneidet und Teilpixel gegen die beiden Farben Tinte und Papier zählt: 0 innerhalb der Glyphenrahmen, in der Sprechblase und in der Box. Jede Aufnahme braucht den laufenden Platz-Server (KIRADEX_PLAZA=1) und entsteht innerhalb von 4 Sekunden, nachdem die Spielfigur die heute längste Zeile aus dem „Say“-Menü gesagt hat, da jede Zeile aus dem Raum zurückkommt102 und eine Sprechblase nur angezeigt wird, solange ihre Zeile jünger als 4 Sekunden ist.25103 Dasselbe Skript hält, auf dem aktuellen Build ausgeführt, den Ausgangswert fest, den es ersetzt. Die 0,0 % aus Abschnitt 6 sind das Core Text eines Macs bei ausgeschalteter Schriftglättung; diese Aufnahme ist die Prüfung, die entscheidet, ob ein iPhone dasselbe zeichnet.
3. Die Box: ein von der Schmiede gezeichneter Rahmen, zwei Zeilen, Seiten
Was. Die Box von WorldHUD behält ihren Platz: unten, im sicheren Bereich, und auf der breiteren Seite des Falzes, wenn das Duo halb geöffnet ist.26 Ihr gestrichenes Rechteck von 2 Punkt wird zu einem Rahmen, den die Schmiede zeichnet: frame-paper.png, 24 mal 24 Schriftpixel, drei mal drei Tiles zu 8 (eine Ecke, eine Kante und eine Mitte), in den zwei Farben von WorldInk plus einem Schatten, original für Kiradex. Eine Ansicht PixelFrame zeichnet ihn in einem Canvas, jedes Quellpixel ein Quadrat von m mal m Gerätepixeln: die Eck-Tiles an den vier Ecken und die Kanten- und Mitten-Tiles von der oberen linken Ecke aus nach außen wiederholt, das letzte Tile dort abgeschnitten, wo es auf die gegenüberliegende Seite trifft, damit die Pixel des Rahmens die Pixel des Textes sind. Damit jedes Quellpixel ein ganzes Quadrat ist, ist die Breite der Box die Breite des sicheren Bereichs, in dem WorldHUD sie heute anordnet, abzüglich 16 Punkt pro Seite, abgerundet auf ganze Schriftpixel, ein Vielfaches von m Gerätepixeln, und auch ihre Höhe besteht aus ganzen Schriftpixeln: auf dem 18 Pro Max im Hochformat bei m = 5, ohne seitliche Einzüge (angenommen, nicht gemessen), 1.224 Gerätepixel, also 244,8 Schriftpixel, abgerundet auf 1.220, 244 Schriftpixel.1194 Der Text sitzt im Rahmen, auf jeder Seite 8 Schriftpixel vom Rand der Box entfernt, anstelle der heutigen 8 Punkt Polsterung (meine Wahl), was dort 228 Schriftpixel pro Zeile lässt, 45 lateinische oder 22 vollbreite Zeichen.11 Der Titel des Ortes steht in einer eigenen Zeile oben auf jeder Seite; darunter zeigt der Text zwei Zeilen auf einmal, wie in Smaragd und Kristall.1 Text, der länger als zwei Zeilen ist, wird in Seiten aufgeteilt, und jede Seite wartet unter der Weitermarke (Punkt 6); endet eine Seite an einem Leerzeichen, entfällt das Leerzeichen. box von WorldHUD (in WorldHUD.swift) nimmt die Seiten anstelle seines einen Status-Strings entgegen.
Die Warteschlange. Meine Regeln, damit das, was die Box zeigt, nie davon abhängt, wie lang der Status ist:
- Die Seiten des Status gehören der Box selbst. Ändert sich der Status (auf dem Platz, wenn sich darin irgendetwas ändert: der Zustand der Verbindung, die Zahl der Anwesenden, die Tageszeit, die Jahreszeit, die verdienten Bänder), werden seine Seiten ersetzt, und die Box zeigt den neuen Status ab seiner ersten Seite, es sei denn, eine Seite nach der nächsten Regel wird gerade gezeigt.
- Der Text eines Schildes (Punkt 5) und eine in der Nähe gesagte Zeile bei großen Größen (Punkt 4) sind Seiten vor dem Status: sofort gezeigt, jede nach einer solchen bereits wartenden Seite, in der Reihenfolge ihres Eintreffens, und nach der letzten davon wieder der Status ab seiner ersten Seite. Die Box behält die Seiten von höchstens den drei jüngsten Zeilen; kommt eine vierte, entfällt die älteste noch wartende, die nicht vom Spieler selbst stammt (die älteste des Spielers nur dann, wenn jede wartende Zeile seine ist), sodass ein Spieler, der eine Zeile sagt, sie nie verliert. Ein neues Schild ersetzt die noch wartenden Seiten eines Schildes.
- Der Statustext behält den ganzen Status als sein Bedienungshilfe-Label, welche Seite auch gezeigt wird, wie heute, sodass VoiceOver ihn ganz liest und die bestehenden UI-Tests, die
plaza-status,room-statusundhall-statuslesen (eine einleitende Wendung, eine Zahl der Anwesenden, die ersten Worte eines Raums), lesen, was sie jetzt lesen. Die gezeigte Seite, so weit sie enthüllt ist, ist der Wert eines versteckten Elements,plaza-pageauf dem Platz (<name>-page, meine Benennung). Es enthält die Textzeilen der Seite ohne den Titel des Ortes und existiert nur unter dem Startargument der Lauftests,-worldTrace(Punkt 8); die Prüfungen unten lesen es, und jede übergibt-worldTrace.103
Rahmen als Wahl. Smaragd lässt den Spieler den Rahmen seiner Menüs unter 20 wählen (seine Dialogbox behält einen Rahmen), und Final Fantasy VI sein Fenster unter 8 mit bearbeitbaren Farben.14 Vier von der Schmiede gezeichnete Rahmen in den Einstellungen anbieten, alle kostenlos, die ersten drei von Anfang an und den vierten ab einem Level; kein Rahmen wird je verkauft. Ob ein Rahmen je eine Belohnung für Unterstützer wird, ist eine Entscheidung, die ich nicht getroffen habe.
Prüfungen. Eine Prüfung der Schmiede, dass frame-paper.png und jede Alternative 24 mal 24 misst, nur Palettenindizes verwendet und dort identische gegenüberliegende Kanten hat, wo das Design es vorsieht; im Simulator des iPhone 18 Pro Max eine Aufnahme der Box bei m = 4 (xSmall) und m = 5 (der Standardgröße), in der ein Skript Breite und Höhe der Box in Gerätepixeln als Vielfache von m vorfindet und ihren Rahmen, die äußeren 8 Schriftpixel auf jeder Seite, Pixel für Pixel mit einem Rahmen vergleicht, den es selbst aus dem PNG in der aufgenommenen Größe der Box nach derselben Regel zusammensetzt (Ecken an den Ecken, Kanten- und Mitten-Tiles von oben links wiederholt und an der gegenüberliegenden Seite abgeschnitten), jedes Quellpixel ein Quadrat von m mal m, wobei jedes Pixel ausgelassen wird, das das PNG transparent lässt und durch das die Welt scheint; und ein UI-Test im selben Simulator bei der Standardgröße, ohne den Platz-Server, damit keine Zeile gesagt wird, gestartet mit -worldTrace und -worldBoxSample und einem Status aus drei Zeilen zu 30 bis 40 Zeichen, durch Zeilenumbrüche verbunden, jede innerhalb der 45 Zeichen, die eine Zeile dort fasst, der wartet, bis plaza-page den ersten beiden Zeilen entspricht, Leerraum beiseite, und erst dann, mit vollständiger erster Seite, auf die Box tippt und die dritte findet, mit einer Aufnahme der ersten Seite, in der ein Skript die Marke unten rechts in der Box findet.11 -worldBoxSample ist ein Testargument meiner Benennung, in PlazaView gelesen wie -plazaTell (dessen tellOnArrival) und an WorldHUD als Status übergeben, anstelle des eigenen Status des Platzes.92
4. Sprechblasen: eine Zeile, kein Name, beide Sprachen
Was. Die Form der Sprechblase behalten: cremefarben, ein Tintenrand, über dem Kopf, unter 4 Sekunden.25 Sie in der Pixelschrift beim m der Sprechblase setzen, mit den Eckpixeln des Rahmens statt eines gestrichenen Rechtecks, innerhalb der 8 Punkt Polsterung pro Seite gezeichnet, damit sie wie der heutige Rand keine Breite hinzufügen. Kein Name in oder über der Sprechblase: Wer spricht, ist der Kopf, über dem sie schwebt, und VoiceOver nennt den Namen (Punkt 8). Eine vorgegebene Zeile bricht nie um; .fixedSize() bleibt.
Über den Scanlines. Heute sind die Sprechblasen ein Overlay in der Bühne, unter den Scanlines der Bühne, einer schwarzen Linie mit 16 % Deckkraft alle 3 Punkt (bei 3× ein Band von 3 Gerätepixeln in jeweils 9), und unter ihrer Vignette, während die Box über der ganzen Bühne liegt.2526 Unter diesen Ebenen wird das Papier einer Sprechblase streifenweise durch ihre Glyphen hindurch abgedunkelt, ihr Text ist also bei keiner Größe Tinte und Papier. Das Briefing verlegt das Sprechblasen-Overlay über die Scanline- und Vignetten-Overlays, wo die Box bereits sitzt, statt die Prüfung aus Punkt 2 auf die Box zu beschränken: meine Wahl, nach der Regel aus Abschnitt 6, dass eine Pixelschrift nur als ganze Gerätepixel aus Tinte und Papier scharf ist, auf beide Formen der Rede gleich angewendet. In PlazaStage.swift wandert das .overlay der Sprechblasen, der letzte Modifier im GeometryReader der Bühne, hinter das .overlay der Vignette (den RadialGradient), mit einem eigenen GeometryReader für die Größe der Ansicht.25
Auf dem Bildschirm. Eine Sprechblase ist heute über dem Kopf ihres Sprechers zentriert, ohne etwas, das sie auf dem Bildschirm hält, ein Sprecher nahe einem Rand schiebt also einen Teil davon hinaus.25 Den Rahmen der Sprechblase innerhalb des sicheren Bereichs abzüglich 16 Punkt auf jeder Seite begrenzen, des Rands, den die Breitenregel unten lässt, und sie nur so weit aus der Mitte über dem Kopf verschieben, wie die Begrenzung es verlangt. Der sichere Bereich, nicht die Ansicht: Die Bühne ignoriert den sicheren Bereich (.ignoresSafeArea()), ihre eigene Geometrie reicht also unter alles, was der sichere Bereich freihält, auf dem Duo die Kameras und die Seitenschiene, wie der Kommentar von WorldHUD über seinen eigenen Platz im sicheren Bereich sagt.94 Heute übergibt nichts der Bühne ihre Einzüge. PlazaView liest sie außerhalb der Bühne und übergibt sie, wie es CardViewer bereits für seine Karte tut (proxy.safeAreaInsets an CardStage); die Begrenzung ist eine reine Funktion, BubblePlacement.frame(head:size:view:insets:), aufgerufen aus PlazaStage.bubbles(of:in:), und dieselben Einzüge setzen die Obergrenze der Sprechblase unten (die Namen sind meine). Die Welt blendet die Statusleiste und den Home-Indikator aus (.statusBarHidden() und .persistentSystemOverlays(.hidden) auf ihrer Wurzelansicht); ob das die Einzüge verkleinert, steht nicht im Code, also liest die App sie, statt sie anzunehmen.94
Die Breitenregel. Jede Zeile passt in beiden Sprachen als einzeilige Sprechblase auf jedes iPhone, auf dem die App laufen kann, wenn der sichere Bereich keine seitlichen Einzüge hat; das garantiert die Begrenzung des Servers unten. Ein Einzug kann selbst für m₀ zu wenig Platz lassen. Für die heute längste Zeile trifft das unter allen Breiten, die der Simulator von iOS 27.0 aufführt, auf jede 3×-Breite bis 393 Punkt und beide 2×-Breiten mit dem Einzug des Duo von 84 Punkt zu sowie auf die 2×-Telefone mit 375 Punkt bei 16 Punkt pro Seite. Eine Zeile an der Grenze des Servers scheitert in mehr Fällen: eine japanische auch auf den Telefonen mit 402 Punkt mit dem Einzug des Duo (286 Punkt Platz gegen 296 bei m₀), und eine lateinische dort (302,67), auf dem 3×-Telefon mit 414 Punkt mit dem Einzug (298) und auf den Telefonen mit 360 Punkt bei 16 Punkt pro Seite (296): von den 36 Fällen aus zwölf Breiten und drei Einzügen 7 für die heutige Zeile, 8 für eine japanische Zeile an der Grenze und 10 für eine lateinische. Dort bekommt eine solche Zeile keine Sprechblase und geht in die Box, während kürzere Zeilen ihre behalten (unten).11 Die App wird nur für das iPhone gebaut, ab iOS 27.0, und die mit Xcode auf meinem Mac installierte Simulator-Runtime von iOS 27.0 führt 33 iPhones auf: das schmalste bei 3× ist 360 Punkt breit (das iPhone 12 mini und 13 mini), und drei sind 2×, das iPhone SE der 2. und 3. Generation mit 375 Punkt und das iPhone 11 mit 414.97 Das ist die Liste der Geräte, die das SDK simuliert; Apples eigene Liste der von iOS 27 unterstützten iPhones habe ich nicht abgerufen. Der Platz für eine Sprechblase ist die Breite des sicheren Bereichs abzüglich 32 Punkt, der 16 pro Seite, die die Begrenzung freihält. Auf den Telefonen im Hochformat, ohne seitliche Einzüge (angenommen; gemessen wurde keiner), sind das 408 auf dem iPhone 18 Pro Max, der schmalsten der fünf Ansichten, die diese Reihe gemessen hat, aber 328 auf einem Telefon mit 360 Punkt und 343 auf den 2×-Telefonen mit 375 Punkt. Auf dem äußeren Display des Duo im Hochformat sind es 434 ohne seitlichen Einzug und 350, wenn die Welt den nachlaufenden Einzug von 84 Punkt behält, die Seitenschiene, den diese Reihe am geschlossenen Display gemessen hat (Abschnitt 11).11979533 Die heute längste Zeile, „Anyone have a card from the first years?“ mit 40 Zeichen, misst als Sprechblase bei 3× 283 Punkt bei m = 4, 349 bei 5, 416 bei 6 und 549 bei 8, ihre Glyphen plus die heutigen 8 Punkt Polsterung pro Seite; der 2-Punkt-Rand wird innerhalb der Sprechblase gezeichnet und fügt keine Breite hinzu. Bei 2× misst dieselbe Zeile 316 Punkt bei m = 3 und 416 bei 4.1125 Das m der Sprechblase hat also auf jeder Ansicht eine Obergrenze, das größte, bei dem die längste vorgegebene Zeile, in welcher Sprache auch immer, in den Platz passt. Für die heutigen Zeilen, alle englisch, ist es 5 auf dem 18 Pro Max (349 in 408) und auf jedem aufgeführten 3×-iPhone von 390 bis 440 Punkt, 4 auf den 3×-Telefonen mit 360 und 375 Punkt und 3, das kleinste, das 2× erlaubt, auf den 2×-Telefonen; auf dem äußeren Display des Duo im Hochformat ist es 6 ohne seitlichen Einzug (416 in 434) und 5 mit der gemessenen Schiene (349,33 in 350). Eine japanische Zeile an der Grenze des Servers unten, 21 vollbreite Zeichen, 210 Schriftpixel an Vorschüben, würde die Obergrenze des Duo auf 5 und 4 und die der Telefone mit 390 und 393 Punkt auf 4 senken (sieben der aufgeführten iPhones sind 390 Punkt breit und vier 393) und die übrigen lassen, wie sie sind.1197 Die App berechnet die Obergrenze aus der sicheren Breite, die PlazaView übergibt, und den Zeilen, die der Server schickt; ein schmalerer sicherer Bereich oder eine längere Zeile, darunter eine japanische, kann sie also senken. Die Obergrenze ist ein Wert über alle Zeilen; was geschieht, wo es keine gibt, wird pro Zeile entschieden, meine Wahl: Wo nicht einmal m₀ die längste Zeile fasst, behält eine Zeile, die bei m₀ passt, ihre Sprechblase bei m₀, und eine Zeile, die nicht passt, bekommt keine Sprechblase und geht stattdessen in die Box, als eigene Seiten, wie bei großen Größen (unten). Würde die Sprechblase dieser Zeile bei m₀ behalten, bräche sie die Begrenzung: Auf einer Ansicht mit 360 Punkt und einem nachlaufenden Einzug von 84 Punkt beträgt der Platz 244 Punkt, und die heute längste Zeile misst bei m₀ 282,67.11 Der Server wiederum hält jede Zeile auf das, was bei jeder Skalierung auf das schmalste Telefon in der kleinsten Größe passt, ohne seitliche Einzüge: höchstens 218 Schriftpixel an Vorschüben, 43 lateinische oder 21 vollbreite Zeichen, das Kleinere aus (360 − 48) × 3 ÷ 4 = 234 bei 3× und (375 − 48) × 2 ÷ 3 = 218 bei 2×. Eine japanische Zeile an dieser Grenze misst als Sprechblase 296 Punkt bei m = 4 bei 3× und 331 bei m = 3 bei 2×; eine lateinische 302,67 und 338,50; beide passen in die 350 des Duo mit der Schiene.1133 Die seitlichen Einzüge der Telefone im Hochformat wurden nicht gemessen; die Aufnahmen unten, die die Sprechblase im sicheren Bereich prüfen, sind der Ort, an dem sich einer zeigen würde.
Die längste vorgegebene Zeile als Sprechblase, nach Größe, bei 3×, gegen den Platz jeder Ansicht; gezeichnet von figures/make_figures.py aus measure_kiradex_text.out.
Größerer Text. Das m der Sprechblase folgt dem der Box, eine Stufe weniger, nie unter m₀ und nie über der Obergrenze der Ansicht: Auf dem 18 Pro Max erreicht es 5, wenn die Box bei xLarge steht (m = 6), und ab xxxLarge, wo das m der Box 7 oder mehr beträgt, bleibt es bei 5. Wo immer die Obergrenze die Sprechblase zwei oder mehr Stufen unter der Box hält (auf dem 18 Pro Max ab xxxLarge, auf einem Telefon mit 360 Punkt ab xLarge), bekommt ein Leser jede Zeile, die innerhalb von sechs Zellen um die Spielfigur gesagt wird, auch in der Box, als eigene Seiten in der Größe der Box: das Handle des Sprechers, ein Doppelpunkt und die Zeile, so wie Smaragd einen Sprecher in der Zeile nennt (Punkt 3 teilt sie in Seiten; Punkt 8 kündigt sie an). PlazaView, das die Zeilen des Raums hält und heute den Status der Box zusammensetzt, setzt diese Seiten zusammen und stellt sie nach der Warteschlange aus Punkt 3 vor den Status: sofort gezeigt, nach den bereits wartenden Seiten einer Zeile, höchstens drei Zeilen behalten. Es legt die Seiten einer Zeile im selben Update in die Warteschlange der Box, das ihre Sprechblase hinzufügt, die Sprechblase einer solchen Zeile auf dem Bildschirm bedeutet also, dass ihre Seiten eingereiht sind. Es ist nicht immer eine Seite. Ein Handle hat 14 bis 20 Zeichen, „handle: line“ also 19 bis 62, und unter dem Rahmen aus Punkt 3 fasst eine Zeile der Box auf dem 18 Pro Max 31 lateinische Zeichen bei xxxLarge, 17 bei AX3 und 12 bei AX5: über jedes Handle, das names.py bilden kann, und jede vorgegebene Zeile eine oder zwei Seiten von xxxLarge bis AX3 und bis zu drei bei AX4 und AX5, sowie bis zu vier auf den Telefonen mit 360 Punkt und den 2×-Telefonen in den größten Größen und auf dem äußeren Display des Duo mit der gemessenen Schiene bei AX4 und AX5.1189 Die Box selbst wird nie begrenzt; sie bricht um und blättert. Die Seite zu dynamicTypeSize(_:) schlägt für eine begrenzte Größe eine große Inhaltsansicht vor; das Briefing verlässt sich nicht darauf, weil die eigene Seite dieses Viewers davor warnt, ihn „as a replacement for proper Dynamic Type support“ (als Ersatz für richtige Unterstützung von Dynamic Type) zu verwenden, und keine der beiden Seiten sagt, ob er sich aus einem Overlay mit ausgeschalteter Trefferprüfung öffnet, wie es das der Sprechblasen ist.707125 Meine Recherchenotizen hatten vorgeschlagen, die Sprechblase bei m = 8 anzuhalten, aber die längste Zeile ist bei 8 549 Punkt breit (die Notizen nennen 553 und zählen den Rand mit, der innerhalb der Sprechblase sitzt), breiter als das 18 Pro Max (440 Punkt) und das äußere Display des Duo im Hochformat (466), und die Notizen maßen die Grenze am äußeren Display des Duo, obwohl das 18 Pro Max mit 440 das schmalere ist; das Briefing folgt hier den Breiten.2211
Prüfungen.
- Der Schrifttest der App (Punkt 1) prüft auch, dass eine im Repository eingecheckte Tabelle der Vorschübe von PixelMplus10, ein Eintrag für jedes Zeichen, das die vorgegebenen Zeilen in einer der beiden Sprachen verwenden, mit der mitgelieferten Schrift übereinstimmt. Die Testsuite des Servers, die keinen Schriftparser hat (ihre Abhängigkeiten sind FastAPI, uvicorn, websockets, httpx und pytest), liest diese Tabelle, lehnt eine Zeile ab, die ein Zeichen enthält, das der Tabelle fehlt, und lehnt eine Zeile in beiden Sprachen ab, deren Vorschübe sich auf mehr als 218 Schriftpixel summieren, die Grenze oben.10411
- Ein Unit-Test der Obergrenze, einer reinen Funktion aus sicherer Breite, Display-Skalierung und den Vorschüben der Zeilen: Bei 3× ergibt sie mit der heute längsten Zeile 5 für jede aufgeführte Breite von 390 bis 440 Punkt, 4 für 360 und 375, 6 für 466 und 5 für 382 (das äußere Display des Duo, ohne und mit der gemessenen Schiene), und bei 2× 3 für 375 und 414; mit einer japanischen Zeile von 210 Schriftpixeln unter den Zeilen 5 für 466, 4 für 382 und 4 für 390 und 393; und keine für einen Platz von 244 Punkt (360 Punkt abzüglich des Einzugs von 84 Punkt und 32) bei 3× mit der heute längsten Zeile; und ein Test des Zusammensetzers in PlazaView, der in diesem Platz für die heute längste Zeile keine Sprechblase zeichnet und ihre Seiten in die Box legt und „Hi!“ als Sprechblase bei m₀ zeichnet (36 Punkt breit, in 244).11
- Ein Unit-Test von BubblePlacement setzt den Kopf eines Sprechers an jede Kante, jede Ecke und die Mitte von Ansichten mit 360, 375, 440 und 466 Punkt Breite, jeweils ohne Einzüge des sicheren Bereichs, mit 16 Punkt an der führenden und nachlaufenden Seite und mit dem nachlaufenden Einzug des Duo von 84 Punkt, und Sprechblasen mehrerer Breiten bis zur sicheren Breite dieses Falls abzüglich 32 (von 244 Punkt, 360 abzüglich 84 und 32, bis 434), und findet jede Sprechblase innerhalb des sicheren Bereichs abzüglich 16 Punkt auf jeder Seite und, wo immer das x des Kopfes in diesem Band liegt, über das x des Kopfes reichend.11
- In den Simulatoren von iPhone 18 Pro Max, iPhone 13 mini und iPhone SE (3. Generation) und auf dem äußeren Display des iPhone Duo in seinem Simulator jeweils vier Aufnahmen (Englisch und Japanisch, jeweils bei der Standardgröße und bei AX3), mit laufendem Platz-Server (KIRADEX_PLAZA=1) und mit -worldTrace gestarteter App, jeweils mit der längsten Zeile der Sprache, von der Spielfigur gesagt; in jeder findet ein Skript den Tintenrand der Sprechblase und prüft, dass sie eine Textzeile hoch ist, nicht breiter als die Breite des sicheren Bereichs abzüglich 32 Punkt und innerhalb des sicheren Bereichs abzüglich 16 Punkt auf jeder Seite. Das Skript nimmt die Einzüge aus dem UI-Test, der die Aufnahme macht, und der liest sie aus einem versteckten Element, das -worldTrace einschaltet (Punkt 8) und in das PlazaView die gelesenen Einzüge schreibt (meins); das Skript bestimmt außerdem das m der Sprechblase aus den Pixeln ihrer Glyphen und prüft, dass es das Kleinere aus dem m der Box minus eins (nie unter m₀) und der Obergrenze für diese sichere Breite ist, berechnet aus den Zeilen des Builds in beiden Sprachen, es entspricht der Obergrenze also nur dort, wo die Obergrenze es begrenzt. Bei der Standardgröße ist das 4 auf den 3×-Telefonen und dem Duo, unabhängig von der Obergrenze, und 3 auf dem 2×-Telefon; bei AX3 ist es die Obergrenze, und auf dem Duo entscheiden die Einzüge: mit den heutigen englischen Zeilen 6 ohne seitlichen Einzug und 5 mit der Schiene, und mit einer japanischen Zeile an der Grenze des Servers 5 und 4.119597
- Ein UI-Test im Simulator des iPhone 18 Pro Max bei AX3, wo das m der Box 12 beträgt und eine Zeile 17 lateinische Zeichen fasst, braucht den Platz-Server (KIRADEX_PLAZA=1) und keinen Mitspieler und startet mit -worldTrace und dem Texttempo Instant (Punkt 6) über den Schlüssel world.textSpeed, den Punkt 5 nennt, sodass jede Seite in dem Moment, in dem sie sich öffnet, ganz erscheint und ein Tap auf die Box genau eine Seite umblättert. Er liest das Handle der Spielfigur aus dem Tab „Me“, wählt „Hi!“ im „Say“-Menü und wartet, innerhalb der 5 Sekunden, die der bestehende Company-Test zulässt, auf die Sprechblase Said: Hi!, damit die Zeile aus dem Raum zurückgekommen ist und ihre Seiten nach der Regel aus Punkt 4 in der Warteschlange der Box liegen, vor dem Status, wie lang der Status auch ist. Eine Zeile der vier Sammler der Stadt, die jeweils höchstens alle 20 Sekunden eine sagen, kann davorstehen; die Warteschlange behält höchstens drei Zeilen und verwirft nie die eine Zeile eines Spielers (Punkt 3), es stehen also höchstens zwei Zeilen davor, dort zu je höchstens zwei Seiten, und später gesagte Zeilen warten dahinter. Der Test liest plaza-page vor jedem Tap und tippt nur dann auf die Box, wenn die Seite nicht aus dem Handle, einem Doppelpunkt, einem Leerzeichen und „Hi!“ besteht, im Abstand von einer Sekunde und höchstens viermal, und besteht, wenn ein Lesen diese Seite findet, das letzte Lesen eine Sekunde nach dem vierten Tap. Er nennt diese Zeile, weil „handle: Hi!“ dort für jedes Handle, das names.py bilden kann, eine Seite ist, während die längste Zeile zwei brauchen kann. Er protokolliert jede Seite, die er gelesen hat.11103102
5. Schilder und Namen
Schilder. Die Schildgrafik bleibt ohne Buchstaben, so wie kit.py sie zeichnet, damit ein Atlas beiden Sprachen dient.29 Ein Tap auf ein Schild-Tile öffnet die WorldHUD-Box mit dem Text des Schildes, als Seiten vor dem Status (Punkt 3), statt die Spielfigur wie heute dorthin laufen zu lassen. Die Bühne liest Berührungen heute über eine DragGesture: touched(_:in:) lässt die Spielfigur sofort zum Boden unter einem Finger laufen, außer über einem Sammler oder dem Kiosk, die auf das Anheben des Fingers warten, und lifted(_:in:) liest dieses Anheben als Tap. Ein Schild-Tile reiht sich bei beiden neben Sammler und Kiosk ein: Es wartet auf das Anheben, und lifted(_:in:) ruft dafür eine Closure onSign auf, so wie es für den Kiosk onKiosk aufruft (der Name ist meiner).92 Schildtexte leben bei der Karte: town.json erhält signs: { "7,10": { "en": ..., "ja": ... } }, nach Zelle verschlüsselt, und die Prüfungen der Schmiede lehnen eine Schildzelle ohne beide Sprachen ab.
Namen. Keine dauerhaften Namensschilder über den Köpfen. Die Box des Kanons nennt ihren Sprecher in der Zeile, Smaragd in 6,5 % seiner Absätze.1 Die Handles von Kiradex reichen bis 20 Zeichen; in der kleinsten Größe der Sprechblase, m = 4 bei 3× und 3 bei 2×, ist ein Handle mit 20 Zeichen bei 3× 133 Punkt breit und bei 2× 150; bei 3× sitzt das über einer Figur, die frontal zur Kamera 16 Texel breit ist und im Profil 13 (30 hoch, in einer Zelle von 32 mal 40), was auf dem 18 Pro Max 42,7 Punkt sind, oder 34,7.119610033 Ein Handle steht in dem Panel, das ein Tap öffnet, wie jetzt, und VoiceOver liest es (Punkt 8).
Prüfungen. Ein UI-Test kann nicht wissen, wo auf dem Bildschirm die Zelle des Schildes gezeichnet wird, da die Kamera der Spielfigur folgt; der Test startet den Platz daher mit -worldTrace und -plazaTapCell 7,10, einem Testargument meiner Benennung, im Body von PlazaStage gelesen wie -plazaFacingDemo (in einem .task), das die Zelle durch dieselbe Verarbeitung schickt, aus lifted(_:in:) in eine Methode herausgelöst. Im Simulator des iPhone 18 Pro Max bei der Standardgröße, ohne den Platz-Server, damit keine Zeile gesagt wird, übergibt der Test außerdem das -worldBoxSample aus Punkt 3 mit einem einseitigen Status, „Sample.“, und das Texttempo Instant (Punkt 6) über seinen Einstellungsschlüssel in den Startargumenten (der Schlüssel, world.textSpeed, ist meiner, neben world.stick des Sticks). Er wartet bis zu 5 Sekunden, bis plaza-page von „Sample.“ auf die erste Seite des Schildes wechselt, liest sie dann, tippt auf die Box und liest erneut, höchstens ein Tap für jedes Wort des Schildtexts (jedes Zeichen im Japanischen), plus einer, bis plaza-page „Sample.“ lautet, und findet die Seiten davor, der Reihe nach verbunden, gleich dem englischen Text des Schildes, Leerraum beiseite, sodass ein Schildtext, der lang genug zum Blättern ist, ebenso besteht wie ein kurzer; mit Japanisch als Sprache der App neu gestartet, den japanischen Text.92 Die Prüfung der Schmiede lehnt eine town.json mit einer S-Zelle ab, der eine der beiden Sprachen fehlt.
6. Texttempo und die Weitermarke
Was. Eine Schreibmaschinen-Enthüllung, deren Zählung Zeit ist, nicht Frames: shown = floor(elapsed × cps), eine reine Funktion der verstrichenen Zeit, des Tempos und zweier Einstellungen, „Bewegung reduzieren“ (Reduce Motion) und laufendes VoiceOver, sodass 60 und 120 Hertz im selben Tempo enthüllen. Die Einstellungen bieten Slow, 12 Zeichen pro Sekunde, das Langsam von Kristall; Normal, 30, die Voreinstellung, meine Wahl zwischen den mittleren Einstellungen des Kanons (15 bei Smaragd, 20 bei Kristall) und seiner schnellen Einstellung von 60; und Instant. Ein Tap während der Enthüllung vervollständigt die Seite; ein Tap auf eine fertige Seite blättert um.1 Dafür nimmt die Box Taps an, solange sie enthüllt oder nach der gezeigten Seite noch eine hat; auf ihrer letzten Seite, ganz gezeigt, lässt sie Taps zum Boden durch, wie sie es heute immer tut.26 Dasselbe Tempo in beiden Sprachen, so wie Final Fantasy VI beide mit einem Buchstaben pro Frame druckt.4 Bei eingeschaltetem „Bewegung reduzieren“ oder laufendem VoiceOver liefert die Funktion sofort die ganze Seite; das ist meine Wahl, nach dem Satz der Dokumentation, dass bei „Bewegung reduzieren“ „UI should avoid large animations“ (die UI große Animationen vermeiden sollte).83
Die Marke. Eine eigene, von der Schmiede gezeichnete Marke von Kiradex, ein nach unten zeigender Keil von 5 mal 3 Schriftpixeln, unten rechts in der Box, der alle 150 Millisekunden um 0, 1, 2 und 1 Schriftpixel nach unten wandert (die Richtung ist meine Wahl; die von Smaragd steigt nach meiner Lesart), ein Zyklus von 600 Millisekunden: der 9-Frame-Schritt von Smaragd bei 60 Hertz.133
Prüfungen. Ein Unit-Test der Enthüllungsfunktion bei 30 Zeichen pro Sekunde: 0 Zeichen bei t = 0 und 30 bei 1,000 Sekunde, wobei die verstrichene Zeit aus einer Tickzahl berechnet wird, Ticks geteilt durch die Rate, bei 60 und bei 120 simulierten Ticks pro Sekunde, nicht aus Deltas pro Tick summiert (120 Deltas von 1/120, in doppelter Genauigkeit summiert, ergeben 0,9999999999999989, was mal 30 29,999999999999968 ergibt und auf 29 abgerundet wird); dieselbe Funktion liefert bei eingeschaltetem „Bewegung reduzieren“ und getrennt davon bei laufendem VoiceOver bei t = 0 die ganze Seite; ein UI-Test im Simulator des iPhone 18 Pro Max bei der Standardgröße und Slow, ohne den Platz-Server, gestartet mit -worldTrace und dem Status -worldBoxSample aus Punkt 3, dessen erste Seite zwei Zeilen zu 30 bis 40 Zeichen hat, mindestens 60 Zeichen und damit mindestens 5 Sekunden Enthüllung bei 12 pro Sekunde, der prüft, dass ein Tap auf die Box eine Sekunde nach Beginn der Enthüllung plaza-page innerhalb einer halben Sekunde zur ganzen Seite macht, zu einem Zeitpunkt, an dem die Enthüllung allein 18 Zeichen zeigen würde (12 beim Tap); ein Unit-Test des Versatzes der Marke als Funktion der verstrichenen Zeit, 0, 1, 2, 1 und 0 Schriftpixel bei 0, 150, 300, 450 und 600 Millisekunden; und eine Bildschirmaufnahme von zwei Sekunden der Marke im Simulator, in der ihre Versätze, Wiederholungen entfernt, in zyklischer Reihenfolge 0, 1, 2, 1 laufen.33
7. Japanisch
Was. Japanisch zuerst für den Text der Welt, der Rest der App später. server/app/lines.py behält seine Indexreihenfolge, wie sein Kommentar sagt, „add at the end only“ (nur am Ende hinzufügen), und jede Zeile wird zu einem englischen und einem japanischen String; der Server sendet beide, und jeder Client zeigt die Sprache, die sein Nutzer liest, sodass eine auf einem gemischten Platz gesagte Zeile aus einem Index in zwei Sprachen gelesen wird.28 Das ist nach meiner Lesart das beste Argument für vorgegebene Zeilen in dieser App. Die Strings der Welt, die Titel und Status von WorldHUD und die Questtitel, wandern in einen String Catalog mit ja; Schildtexte bleiben bei der Karte (Punkt 5). Jeder japanische String wird von jemandem geschrieben oder geprüft, der Japanisch spricht; keiner wird maschinell übersetzt und ungeprüft ausgeliefert.
Zeilenumbruch. Vorgegebene Zeilen brechen nie um (Punkt 4). Boxtext wird so geschrieben, dass er bei der Standardgröße in zwei Zeilen pro Seite passt, so wie das Skript von Smaragd von Hand umbrochen wurde.1 Wo er umbrechen muss, gilt die strenge Regel: Boxtext nicht mit einer Satzsprache ja kennzeichnen, es sei denn, eine Aufnahme zeigt, dass die strenge Regel damit hält, denn Core Text unter macOS ließ mit der Kennung ja in den meisten Schriften bei 6 von 7 Breiten kleine Kana Zeilen beginnen (4 von 7 in k8x12 und k8x12S).777 Wendet eine Systemvoreinstellung die gelockerte Regel trotzdem an, ist die festgehaltene Abhilfe ein U+2060 WORD JOINER vor dem kleinen Kana in den wenigen Strings, die es brauchen.
Prüfungen. Ein Test, dass jede Zeile und jeder Weltschlüssel des String Catalog beide Sprachen hat; der Servertest aus Punkt 4, der eine japanische vorgegebene Zeile jenseits der Grenze von 218 Schriftpixeln ablehnt, 21 vollbreite Zeichen; und im Simulator des iPhone 18 Pro Max bei der Standardgröße mit Japanisch als Gerätesprache, ohne den Platz-Server und im Tempo Instant, gestartet mit -worldTrace, eine Aufnahme jeder Seite eines Testabsatzes in der Box, übergeben als Status -worldBoxSample aus Punkt 3 und so geschrieben, dass bei den 22 vollbreiten Zeichen, die eine Zeile dort fasst, ein Umbruch vor ein kleines Kana fiele, in der keine Zeile nach der ersten des Absatzes mit einem Zeichen aus der Zeilenanfangsliste von JLREQ oder einer Kompatibilitätsform davon beginnt.11 Diese Liste ist die vollständige, die 83 Einträge der zehn Klassen, die die Regel in 3.1.7 nennt (drei Zeichen stehen in zwei Klassen), im Testziel eingecheckt; die Messung in Abschnitt 7 verwendete eine unvollständige Liste (Abschnitt 7). Japanische Satzsoftware setzt an ihrer Stelle meist die Kompatibilitätsformen, die Unicode für den Austausch mit älteren Standards kodiert, wie JLREQ zur öffnenden Klammer anmerkt: „the compatibility counterpart U+FF08 FULLWIDTH LEFT PARENTHESIS is used in the Japanese context in most Japanese text layout software“ (in den meisten japanischen Satzprogrammen wird im japanischen Kontext das Kompatibilitätsgegenstück U+FF08 FULLWIDTH LEFT PARENTHESIS verwendet).21 Die Liste ergänzt also jedes Zeichen des Unicode-Blocks Halfwidth and Fullwidth Forms, dessen Kompatibilitätsnormalisierung (NFKC) einer der 83 ist, 24 davon, darunter ! (U+FF01), ? (U+FF1F), ) (U+FF09), :, ;, , und ., sowie die halbbreiten 。, 、, ー und die kleinen Katakana ab ァ (U+FF67); und ~ (U+FF5E), die vollbreite Tilde, neben dem Wellenstrich 〜 derselben Klasse, meine Ergänzung, da ihre Normalisierung die ASCII-Tilde ist, die die Liste nicht enthält: 25 insgesamt.98 PixelMplus10 bildet 54 der 83 Einträge und 24 der 25 Formen ab. Die übrigen 29 Einträge zeichnet sie nicht, darunter 〜 (U+301C), ゠, den Halbgeviertstrich, ‼ und die kleinen Katakana ab U+31F0, ebenso wenig die vollbreite ⦆ (U+FF60), und der Abdeckungstest aus Punkt 1 hält jedes davon aus den Strings der Welt heraus, sodass eine Aufnahme immer nur die 75 Zeichen zeigen kann, die sie zeichnet (die 54 Einträge, von denen drei, ), 〕 und ], in zwei Klassen stehen, also 51 Zeichen, und die 24 Formen).98 Ein Skript vergleicht die erste Glyphenzelle jeder Zeile Pixel für Pixel mit den Glyphen der Schrift für diese 75 beim m der Aufnahme, aus der mitgelieferten Schrift mit CTFontGetGlyphsForCharacters gezeichnet, und findet keine Übereinstimmung. Pixel können ein aufgeführtes Zeichen nur dort von den anderen des Absatzes unterscheiden, wo die Schrift sie verschieden zeichnet. Bei 10 Pixeln gezeichnet, haben zwei der 75 einen pixelgleichen Zwilling in der Schrift: ‐ (U+2010), identisch mit dem geschützten Bindestrich U+2011, und der Doppelpunkt, identisch mit dem modifizierenden Doppelpunkt U+A789; keine der 24 Formen hat einen. Der Testabsatz verwendet also keinen der beiden Zwillinge; ー (U+30FC) und das Kanji 一 (U+4E00) unterscheiden sich, 200 Tintengerätepixel gegen 250 bei m = 5, 一 darf also überall darin stehen.9821 Das Ergebnis aus Abschnitt 7 ist das Core Text eines Macs; diese Aufnahme entscheidet, was SwiftUI unter iOS tut.
8. VoiceOver über der Bühne
Heute. VoiceOver hört „The plaza“ und dann die Spur der Lauftests, etwa „12,4 down“.25 Dieser Wert ist für Tests, nicht für Menschen.
Was.
1. Das Label der Bühne bleibt „The plaza“ oder der Name des Raums, und ihr Wert wird ein Satz, mit dem ein Mensch etwas anfangen kann: wo der Sammler steht, nach Wahrzeichen, wer in der Nähe ist und was die Personen hochhalten (zum Beispiel By the pond. Three collectors nearby. Holding up a card., also: am Teich, drei Sammler in der Nähe, hält eine Karte hoch), nach der Regel von accessibilityValue, dass ein Wert sagt, was das Label nicht sagt.79 Alles, was heute über stepTrace in den Wert der Bühne gelangt, zieht um, gleich, wer es schreibt: als ich PlazaStage.swift las, die Schrittspur aus rig.onStep, die Fehlermeldung des Builds aus der Make-Closure der RealityView und der Bericht der Luftsonde aus dem .task, der -airProbe liest, und Minuten später ein vierter Schreibzugriff, aus einer an diesem Tag hinzugefügten Laufdemo. Es zieht in ein verstecktes Element, das nur existiert, wenn die App mit -worldTrace (meine Benennung) gestartet wird, das die Lauftests übergeben, neben der Seite der Box (Punkt 3) und den Einzügen, die PlazaView gelesen hat (Punkt 4), und die Tests, die den Wert der Bühne lesen, darunter testTheCollectorFacesTheWayItWalks und testTheChimneysSmoke, das auf value CONTAINS 'smoke 18 ' wartet, lesen stattdessen dieses Element.25103
2. accessibilityDirectTouch(_:options:) auf der Bühne, damit eine VoiceOver-Nutzerin oder ein VoiceOver-Nutzer nach dem Aktivieren tippen kann, um zu gehen (iOS 17.0).80
3. Die Entität jedes Sammlers erhält eine AccessibilityComponent mit dem Handle als Label und dem, was die Person hochhält, als Wert, damit VoiceOver sie beschreiben kann (iOS 17.0).84
4. Eine Zeile, die innerhalb von sechs Zellen um die Spielfigur gesagt wird, wird als AccessibilityNotification.Announcement veröffentlicht (zum Beispiel Glacier Shuffle 4471: Nice card!), mit niedriger Priorität, höchstens eine alle zwei Sekunden, die eigene Rate des Servers für eine Zeile.8291
5. Eine Seite der Box, die sich öffnet, wird ganz angekündigt, es sei denn, sie wiederholt eine Zeile, die Unterpunkt 4 bereits angekündigt hat, wie es die Seiten für großen Text aus Punkt 4 tun.
Prüfungen. Ein UI-Test, dass der Wert der Bühne ohne -worldTrace keine Koordinaten enthält; in einem Simulator von iOS 27 ein Test mit XCUIVoiceOverService, der VoiceOver einschaltet, es auf die Bühne bewegt und prüft, dass das, was currentSpeech() liefert, das Label der Bühne enthält und kein Zahlenpaar in der x,y-Form der Schrittspur;87 eine manuelle Prüfung auf einem Gerät mit eingeschaltetem VoiceOver, datiert und mit Build-Nummer, dass eine Sammler-Entität erreichbar ist und gesprochen wird, weil unbestätigt ist, ob eine RealityView mit einer virtuellen Kamera AccessibilityComponent-Elemente sichtbar macht (Abschnitt 11); und ein Unit-Test der Drosselung der Ankündigungen, in dem zwei Zeilen innerhalb von 2 Sekunden eine Ankündigung ergeben.
9. Niemals, bei Schrift und Fenstern
- Keine Glyphe, kein Rahmen, kein Pfeil und keine Fenstergrafik aus dem ROM oder der Dekompilierung eines Spiels in der App oder in der Schmiede. Die Sheets von pret und ff6 werden hier gemessen und nie kopiert. Rahmen, Marke und Schild von Kiradex zeichnet die Schmiede; seine Schrift ist eine lizenzierte Schrift.
- Keine Franchise-Zeichen oder -Ligaturen. Die Charmap von Smaragd trägt Sonderglyphen für Franchise-Wörter; nichts dergleichen wird gezeichnet, und kein String verwendet die Namen, die das Franchise für Dinge hat.31
- Keine Schrift ohne ihre Lizenzdatei in der Hand: Eine Schrift wird nur ausgeliefert, wenn ihr Lizenztext in Abschnitt 4 oder 5 zitiert und neben den Belegen gespeichert ist.
- Keine veränderte OFL-Schrift unter ihrem Reserved Font Name. Press Start 2P erklärt einen; wird je eine OFL-Schrift verändert, wird sie umbenannt.54
- Kein Text, der in Weltgrafik eingebrannt ist: Schilder, Ladenfronten und Bretter bleiben ohne Buchstaben, sodass kein Atlas je sprachspezifisch ist.
Prüfung. Ein Skript berechnet zwei SHA-256-Digests jedes Bildes, das die Schmiede schreibt und der Asset-Katalog enthält, einen über die Bytes der Datei und einen über ihre dekodierten Pixel, und vergleicht sie mit denselben zwei Digests jedes hier gemessenen PNG (graphics/fonts und graphics/text_window von pret, die Rahmen von Kristall und gfx/font/font.png von Kristall und Rot). Die Liste dieser Digests, nicht die Bilder, wird als scripts/forge/canon_digests.txt (ein Name meiner Wahl, neben kit.py der Schmiede) ins Repository eingecheckt, sodass die Prüfung ohne den Belegordner läuft, und jede Übereinstimmung lässt den Build scheitern. Ihr eigener Test ist eine Negativkontrolle, die keine Spieldatei braucht: Er fügt die Digests einer Ausgabe der Schmiede einer Kopie der Liste hinzu und prüft, dass das Skript dann scheitert. Dasselbe Skript listet zur Durchsicht, ohne zu scheitern, jede Zelle von 8 mal 8 einer Ausgabe der Schmiede auf, deren Ein-Bit-Maske oder deren Umkehrung einer Zelle dieser Sheets entspricht. Digests ganzer Bilder können diese Zellen nicht rekonstruieren, also enthält die Liste auch den SHA-256-Digest jeder eindeutigen Zellmaske der Sheets, nach einer Regel (meiner), auf die Ausgaben der Schmiede genauso angewendet: Ein Pixel ist gesetzt, wo seine Farbe vom oberen linken Pixel des Bildes abweicht; Zellen laufen in 8 mal 8 von der oberen linken Ecke, eine Teilzelle am Rand entfällt; eine leere oder volle Zelle wird auf beiden Seiten ausgelassen, da die Sheets viele davon haben (allein japanese_normal.png hat 430 leere Zellen von 1.024); und eine Maske sind ihre 64 Bit Reihe für Reihe, 8 Bytes. Über die 50 Sheets sind das 7.746 behaltene Zellen und 1.484 eindeutige Digests.99 Eine umgefärbte, umskalierte oder neu gezeichnete Kopie besteht die Digests; Regel 1 beruht darauf, dass die Schmiede jedes Asset aus Code zeichnet, und auf jener Durchsicht, nicht auf der Prüfung allein. Und die String-Prüfung, die die früheren Briefings dieser Reihe vorschlagen, wird um die Franchise-Abkürzungen aus der Charmap von Smaragd erweitert.105
Nicht in diesem Briefing
- Eine Pixelschrift für die ganze App. Der Dex, der Scanner und die Einstellungen behalten die Systemschrift; Pixelschrift ist für die Welt.
- Chinesisch und Koreanisch. Alle vier geprüften modernen Pixelspiele liefern Chinesisch aus, und zwei davon, Stardew Valley und Sea of Stars, Koreanisch, aber nichts hier hat eine Pixelschrift für eine der beiden Sprachen gemessen.64
- Misaki oder irgendeine 8-Punkt-Schrift für Lesetext. Sie hat die kleinsten gemessenen Kanji; die Lesbarkeit in dieser Größe für japanische Leser ist ungemessen.6
- Namensschilder über den Köpfen und ein Namensfeld in der Box.1
- Maschinell übersetztes Japanisch, das niemand geprüft hat.
- Synthetisches Fett oder Kursiv auf der Pixelschrift.
- Rahmen zum Verkauf. Jeder Rahmen ist kostenlos; ein Rahmen für Unterstützer wartet auf eine Entscheidung.
- In der RealityKit-Szene gezeichneter Text. Die Begründung des Welt-Beitrags und die Arithmetik aus Abschnitt 10 halten ihn beide in SwiftUI.2311
Wichtigste Erkenntnisse
Wenn Sie die Grafik zeichnen
- Bauen Sie Rahmen aus Tiles: eine Ecke, eine Kante und eine Mitte. Die Menüs von Smaragd wählen unter 20 Rahmen von 24 mal 24 Pixeln, drei mal drei Tiles; seine Dialogbox zeichnet aus einem Streifen von 14 Tiles mit gespiegelter Unterkante; die Rahmen von Kristall bestehen aus je 6 Ein-Bit-Tiles.1
- Geben Sie der Weitermarke einen langsamen Takt. Der Pfeil von Smaragd wandert von der Ruhelage um 0, 1, 2 und 1 Pixel, ein Schritt alle 9 Frames, 0,6 Sekunden pro Zyklus.1
- Halten Sie Wörter aus der Weltgrafik heraus. Ein Schild ohne Buchstaben dient jeder Sprache aus einem Atlas; die Wörter gehören in die Box.29
- Zeichnen Sie Japanisch in 8 bis 12 Pixeln und rechnen Sie damit, dass ein Kana doppelt so breit ist wie ein lateinischer Buchstabe: 8 gegen 4, 10 gegen 5, 12 gegen 6 in jeder gemessenen Pixelschrift mit Japanisch.7
Wenn Sie die Engine bauen
- Wählen Sie eine Pixelschrift nach ihrer Datei, nicht nach ihrem Namen: Prüfen Sie das Raster, den Versatz zur Grundlinie und die Vorschübe. Das Raster von PixelMplus12, 0,39 Pixel neben der Grundlinie, verschmierte in Core Text unter macOS bei jeder Größe; der Kana-Vorschub von k8x12 mit 8,01 Pixeln verschmierte, sobald Glyphen exakt platziert wurden.7
- Zeichnen Sie nur bei ganzen Gerätepixeln pro Schriftpixel: 0,0 % Teilpixel bei ganzzahligen Vielfachen eines Rasters auf der Grundlinie mit ganzen Pixelvorschüben (Misaki, PixelMplus10, Press Start 2P), 19,4 % bis 82,2 % dazwischen, im Core Text eines Macs bei ausgeschalteter Schriftglättung. Mit der voreingestellten Glättung des Kontexts hatte PixelMplus10 in seiner eigenen Größe 178 von 272 Tintenpixeln als Teilpixel, ein ganzzahliges Vielfaches ist also notwendig, nicht hinreichend; nehmen Sie ein iPhone auf, bevor Sie einem der beiden Ergebnisse dort trauen.79
- Achten Sie Dynamic Type, indem Sie auf das Raster runden. Ein Em von 10 Pixeln ist bei 3× bei 1 der 12 Body-Größen ganzzahlig; runden Sie die skalierte Größe auf ganze Gerätepixel pro Schriftpixel und setzen Sie sie als feste Größe.768
- Zählen Sie das Texttempo in Zeit, nicht in Frames, damit 60 und 120 Hertz gleich enthüllen; 60 Zeichen pro Sekunde sind die schnellste Rate in jedem gemessenen Spiel, und 15 bis 20 die mittlere Einstellung, wo ein Spiel eine hat.14
- Geben Sie VoiceOver einen Satz, keine Spur.
accessibilityValueist für das, was das Label nicht sagt,AccessibilityComponentbeschreibt eine Entität, undXCUIVoiceOverServicekann ab iOS 27.0 testen, was VoiceOver spricht.798487
Wenn Sie den Spielablauf gestalten
- Zwei Zeilen auf einmal, am unteren Rand. Die Box von Smaragd nimmt 30 % des Bildschirms ein und die von Kristall 33 %, jede zwei Zeilen.1
- Schreiben Sie auf die Breite hin. Die Autoren von Smaragd hielten 95 % von 24.100 Zeilen bei 38 Zeichen in einem Fenster, das 41 fasst, und keine über das Fenster hinaus.1
- Nennen Sie den Sprecher in der Zeile, nicht über dem Kopf; die Box von Smaragd hat kein Namensfeld.1
- Planen Sie Japanisch von Anfang an ein: Vier von vier geprüften modernen Pixelspielen liefern es aus. Eine Schrift, die JIS X 0208 abdeckt, zeichnet rund siebentausend Zeichen; ein Spiel mit festem Skript kann mit weniger auskommen, wie das japanische ROM von Final Fantasy VI mit 1.248 Buchstaben, und dann muss jeder neue String gegen die Schrift geprüft werden.64584
Häufige Fragen
Wie groß sollte eine Textbox in einem Pixel-Art-Spiel sein?
In den Pokémon-Spielen für Handhelds das untere Drittel des Bildschirms und zwei Zeilen. Der Dialograhmen von Smaragd misst 30 mal 6 Tiles, 240 mal 48 Pixel, 30 % der Bildschirmhöhe des Game Boy Advance, um ein Textfenster von 27 mal 4 Tiles, das zwei Zeilen einer 16-Pixel-Schrift fasst. Die Box von Kristall misst 20 mal 6 Tiles, 33 % des Game-Boy-Bildschirms, zwei Zeilen zu 18 Zeichen, und die von Rot ebenso 20 mal 6. Final Fantasy VI öffnet sein Fenster am oberen oder unteren Bildschirmrand.12345
Wie schnell sollte ein Schreibmaschineneffekt für Text sein?
Der Kanon zählt Frames. Smaragd und Feuerrot drucken alle 8, 4 oder 1 Frames ein Zeichen, 7,5, 15 oder 60 pro Sekunde bei 60 Hertz, und eines pro Frame, solange A oder B nach einem Druck während des Drucks gehalten wird; Kristall und Rot drucken 12, 20 oder 60 pro Sekunde; Final Fantasy VI druckt Felddialoge mit einem Buchstaben pro Frame, 60 pro Sekunde, ohne Einstellung dafür (sein sechsstufiges Nachrichtentempo bestimmt, wie lange eine Kampfmeldung wartet). Zählen Sie auf einem modernen Telefon Zeichen in Zeit statt in Frames, damit sich das Tempo bei 120 Hertz nicht ändert. Jedes gemessene Spiel endet bei 60 pro Sekunde, und die mittleren Einstellungen von Smaragd und Kristall liegen bei 15 und 20; das Briefing unten schlägt 30 als Voreinstellung vor, was meine Wahl zwischen diesen mittleren Einstellungen und den schnellen 60 ist, keine gemessene Einstellung.1144
Welche Pixelschriften unterstützen Japanisch?
Von den gemessenen zeichnen Misaki (8 mal 8 Punkte), k8x12 (8 mal 12) und DotGothic16 alle 6.879 Zeichen von JIS X 0208, und PixelMplus10 und PixelMplus12 alle bis auf drei Codepoints. Misaki, k8x12 und PixelMplus stehen unter einer freien Lizenz aus drei Sätzen, die Nutzung, Vervielfältigung und Weitergabe „either commercially or noncommercially“ (kommerziell wie nichtkommerziell) erlaubt; DotGothic16 steht unter der SIL Open Font License 1.1. Mit Core Text unter macOS 27.0 gemessen, sind Misaki und PixelMplus10 die beiden mit einem sauberen Raster auf der Grundlinie und ganzen Pixelvorschüben, bei 8 und 10 Pixeln; das Raster von PixelMplus12 liegt 0,39 Pixel unter der Grundlinie, der Kana-Vorschub von k8x12 beträgt 8,01 Pixel, und die Punkte von DotGothic16 liegen auf überhaupt keinem Pixelraster.67171853
Warum sieht meine Pixelschrift auf dem iPhone unscharf aus?
Meist, weil ein Schriftpixel keine ganze Zahl von Gerätepixeln ist. In Core Text unter macOS 27.0 bei ausgeschalteter Schriftglättung zeichneten die Pixel-TrueType-Schriften mit sauberem Raster auf der Grundlinie und ganzen Pixelvorschüben (Misaki, PixelMplus10 und Press Start 2P) bei ganzzahligen Vielfachen ihres Rasters ohne Teilpixel und dazwischen mit 19,4 % bis 82,2 % verschmierten Tintenpixeln. Mit der voreingestellten Glättung des Zeichenkontexts verschwamm sogar ein ganzzahliges Vielfaches: PixelMplus10 kam in seinen eigenen 10 Pixeln mit 178 von 272 Tintenpixeln als Teilpixel heraus.9 Zwei Fehler in der Schriftdatei verursachen Unschärfe bei jeder Größe: ein Raster neben der Grundlinie, wie bei PixelMplus12 um 0,39 Pixel, und ein Vorschub, der nicht ganzzahlig ist, wie der Kana-Vorschub von k8x12 mit 8,01 Pixeln, sobald Glyphen exakt platziert werden. Die Messung entstand auf einem Mac; eine Aufnahme auf dem iPhone ist die Prüfung, die es dort klärt.7
Kann eine Pixelschrift Dynamic Type unterstützen?
Nur durch Runden. Von den zwölf Body-Größen von iOS, 14 bis 53 Punkt, landet ein Em von 10 Pixeln bei 3× nur bei 40 Punkt auf ganzen Gerätepixeln; eine Pixelschrift, die mit Font.custom(_:size:relativeTo:) stufenlos skaliert, liegt also bei den anderen elf neben ihrem Raster; im Core Text des Macs bedeutete neben dem Raster verschmiert, und eine Aufnahme auf dem iPhone entscheidet, was SwiftUI dort zeichnet. Lesen Sie die skalierte Größe mit UIFontMetrics oder ScaledMetric, runden Sie sie auf eine ganze Zahl von Gerätepixeln pro Schriftpixel und setzen Sie sie mit Font.custom(_:fixedSize:). Apple verlangt, dass eine eigene Schrift die Verhaltensweisen der Systemschriften umsetzt, Dynamic Type eingeschlossen, und dass eine App Menschen ihren Text idealerweise um mindestens 200 Prozent vergrößern lässt.710206768
Hält sich Core Text an die japanischen Zeilenumbruchregeln?
In meiner Messung unter macOS 27.0 ja, streng, wenn der Text nicht mit einer Sprache gekennzeichnet war: Ein Absatz von 131 Zeichen brach bei sieben Breiten um, ohne dass eine Zeile mit einem Zeichen aus der Zeilenanfangsliste der Messung begann, einer unvollständigen Liste, überwiegend aus Zeichen von JLREQ, sieben davon in ihrer Vollbreitenform, in Hiragino Sans und acht Pixelschriften. Mit der Kennung ja lockerte es sich zur weniger strengen Regel, die die Anforderungen des W3C an japanisches Layout beschreiben, und in den meisten Schriften begann bei 6 von 7 Breiten ein kleines Kana eine Zeile. Was SwiftUI auf einem iPhone mit Japanisch als Gerätesprache tut, wurde nicht gemessen.721
Wie viele Zeichen braucht eine japanische Pixelschrift?
JIS X 0208, das übliche Abdeckungsziel, umfasst 6.879: 524 Nicht-Kanji, 2.965 Kanji der Stufe 1 und 3.390 Kanji der Stufe 2. Der Produzent des Final Fantasy Pixel Remaster sagte Siliconera, dass seine japanische Pixelschrift „around 7,500 characters“ (rund 7.500 Zeichen) brauchte, gegenüber „a few hundred“ (einigen hundert) für die westlichen Sprachen. Ein Spiel mit festem Skript kann mit weniger auskommen: Das japanische ROM von Final Fantasy VI hat 1.248 Buchstaben in seiner Dialogschrift.584
Jede Zahl in diesem Beitrag stammt aus einem Skript, das gegen gespeicherte Quellen erneut läuft, aus einer am 5. Oktober 2026 gespeicherten Seite oder aus einer datierten Lesung des Kiradex-Quellcodes, und die Anmerkungen sagen, woraus; die Core-Text-Zahlen stammen von macOS 27.0, nicht von iOS. Das Briefing in Abschnitt 12 ist mein Vorschlag und als solcher gekennzeichnet; nichts davon ist gebaut.
Verwandt auf dieser Website: Pixel-Art-Welten auf dem iPhone ist der erste Beitrag dieser Reihe, mit dem RealityKit-Rezept und der Textrichtung, die dieser Beitrag misst; Pixel-Art-Figuren: Charaktere und ein Editor auf dem iPhone ist der Sammler, über dem die Sprechblasen schweben; Pixel-Art-Bauten: Häuser, Hallen und Innenräume auf dem iPhone hat die Schmiede, deren Schild ohne Buchstaben bleibt; Pixel-Art-Bewegung: Laufen, Kameras und Türen auf dem iPhone hat die Takte von 60 und 120 Hertz, an denen die Enthüllung gemessen wird; Eine Pixelstadt, die lebt, wenn niemand online ist hat die vorgegebenen Zeilen und ihre Rate; Pixel-Art-Räume und Pixel-Art-Routen sind die Briefings, deren Prüfungen dieses erweitert; Die alten Pokémon-Spiele ehren, ohne sie zu kopieren erklärt, warum der Kanon gemessen und nie kopiert wird; und Xcode 27.1 Beta: Ihre App im iPhone-Duo-Simulator behandelt den Simulator, auf dem die Aufnahme der Sprechblase läuft.
Quellen
-
Messung des Autors, 5. Oktober 2026:
measure_gen_text.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_gen_text.out. Eingaben aus pret pokeemerald bei731ad5b:src/text.c(sFontInfos, der FallRENDER_STATE_HANDLE_CHAR,sWindowVerticalScrollSpeeds,sDownArrowYCoords, die Funktionen für japanische Glyphen),src/menu.c(sTextSpeedFrameDelays,sStandardTextBox_WindowTemplates,WindowFunc_DrawDialogueFrame, für das Standardfenster ausgewertet),src/fonts.cundcharmap.txt(Glyphenbreiten),graphics/text_window/*.png(Größen),include/text_window.h, jede Zeile vondata/text/*.incunddata/maps/*/scripts.inc, an\n,\lund\pgetrennt und über die Breitentabelle gemessen (504 Dateien, 24.100 Zeilen ohne Platzhalter, 3.000 mit, 0 übersprungen), undgraphics/fonts/japanese_*.png(nicht leere Zellen). Aus pokefirered bei037335f:src/new_menu_helpers.c. Aus pokecrystal bei5beda23:constants/hardware.inc,constants/text_constants.asm,home/print_text.asm,gfx/font.asm, die Rahmen-PNGs undgfx/font/font.png. Aus pokered beid2704a6:data/text_boxes.asm,constants/ram_constants.asm,gfx/font/font.png. Zeichen pro Sekunde sind 60 geteilt durch Frames pro Zeichen. Die Lesart des Druckers von Smaragd (die Verzögerung vonAddTextPrinterminus eins gespeichert, dann heruntergezählt, sodass ein Zeichen die Verzögerung in Frames braucht), die Bedingungen der Verzögerung beim automatischen Scrollen aussrc/battle_message.cundsrc/scrcmd.cund die zweizeilige Lesart der Konstanten von Kristall prüft das Skript per Assertion, ohne sie auszuführen. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
pret,
pokeemerald/src/menu.cbei Commit731ad5b(sTextSpeedFrameDelaysin Zeile 77;sStandardTextBox_WindowTemplatesin Zeile 84;LoadMessageBoxGfxundLoadUserWindowBorderGfxin den Zeilen 212 und 213;WindowFunc_DrawDialogueFramein Zeile 218 aufgerufen, seine Füllungen verwenden ab Zeile 378BG_TILE_V_FLIP), gelesen am 5. Oktober 2026, https://github.com/pret/pokeemerald/blob/master/src/menu.c. ↩↩↩↩↩↩↩ -
pret,
pokecrystal/constants/text_constants.asmbei Commit5beda23(Zeilen 24 bis 32:BORDER_WIDTH EQU 2,TEXTBOX_WIDTH EQU SCREEN_WIDTH,TEXTBOX_HEIGHT EQU 6,TEXTBOX_Y EQU SCREEN_HEIGHT - TEXTBOX_HEIGHT,TEXTBOX_INNERY EQU TEXTBOX_Y + 2) undconstants/hardware.inc(Zeilen 922 und 923,SCREEN_WIDTH20 undSCREEN_HEIGHT18), gelesen am 5. Oktober 2026, https://github.com/pret/pokecrystal/blob/master/constants/text_constants.asm. ↩↩↩↩ -
Messung des Autors, 5. Oktober 2026:
measure_ff6.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_ff6.out. Eingaben aus everything8215/ff6 bei8130132:tools/rip_list_en.jsonundtools/rip_list_jp.json(Bytebereiche der Fenstergrafiken, Paletten und Schriften),src/menu/config.asm(ConfigWindowNumPos,LoadWindowPal,ConfigColorBarTextList,ChangeConfigOption_02),src/menu/menu_sram.asm,src/btlgfx/gfx_cmd.asm(MsgSpeedTbl,mess_wait), jede Datei untersrc/, die$1d4dliest,src/field/text.asm(LoadLetterGfx, die x-Grenzen der Zeile,CalcTextWidth,NewLine,UpdateDlgTextOneLine, der Kartentitel),src/gfx/font_gfx.asm(FontWidth),src/field/reset.asm(die Feldschleife),src/field/hdma.asm(DlgWindowFixedColorTbl) undtools/char_table/(kanji.json,kana.json). Ein Buchstabe pro Frame und ein Wert des Verlaufs pro Scanline sind Lesarten des Codes, per Assertion geprüft, nicht ausgeführt. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Unicode Consortium,
JIS0208.TXT, die Zuordnungstabelle von JIS X 0208 zu Unicode, Version 2.0, abgelegt unter OBSOLETE/EASTASIA, abgerufen und gespeichert am 5. Oktober 2026, https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/JIS0208.TXT. Gezählt vonmeasure_coretext.swiftundmeasure_bdf.py: 6.879 Zeichen; 524 Nicht-Kanji, davon 169 Kana in den Reihen 4 und 5; 2.965 Kanji der Stufe 1 in den Reihen 16 bis 47; 3.390 Kanji der Stufe 2 in den Reihen 48 bis 84. ↩↩↩↩↩↩↩↩ -
Messung des Autors, 5. Oktober 2026:
measure_bdf.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_bdf.out. Eingaben: die BDF-Dateien von Misaki Gothic, Misaki Gothic 2nd und Misaki Mincho sowie von k8x12, k8x12L und k8x12S (Ausgaben vom 2021-05-05) und die gespeicherteJIS0208.TXT; es meldet für jede Schrift Pixelgröße, Begrenzungsrahmen, Ober- und Unterlänge, Zeichenzahl, Vorschubbreiten, die vollbreiten Glyphen, deren Tinte die Zelle in einer Richtung füllt, dasselbe für Kanji (U+4E00 bis U+9FFF) und die gezeichneten Zeichen von JIS X 0208. ↩↩↩↩↩↩↩↩↩↩↩ -
Messung des Autors, 5. Oktober 2026:
measure_coretext.swiftim Belegordner des Autors zu diesem Beitrag, kompiliert mitswiftc -Ound ausgeführt unter macOS 27.0 (Build 26A428), Ausgabemeasure_coretext.out, nicht unter iOS. Eingaben: Misaki Gothic, Misaki Gothic 2nd, k8x12 und k8x12S (die TTF-Ausgaben vom 2021-05-05), PixelMplus10 Regular und Bold sowie PixelMplus12 Regular (PixelMplus beid89b95f), DotGothic16, Press Start 2P und Silkscreen (google/fonts bei9710da1), Hiragino Sans W3 als Systemkontrolle und die gespeicherteJIS0208.TXT. Es meldet für jede Schrift Glyphenzahl und Bitmaptabellen (CTFontCopyAvailableTables); ihr Designraster (die kleinste Zahl von Pixeln pro Em zwischen 4 und 40, bei der 95 % der Konturpunkte der Beispielglyphen innerhalb von 0,04 Pixel liegen, jede Achse mit einem erlaubten konstanten Versatz); ihre lateinischen und Kana-Vorschübe; ihre Abdeckung von ASCII und von JIS X 0208; den Anteil der Teilpixel an den Tintenpixeln (8 bis 247 von 255), wenn eine Beispielzeile beim 1- bis 4-Fachen des Rasters in eine 8-Bit-Graustufen-Bitmap gezeichnet wird, mit eingeschalteter Kantenglättung, ohne Kantenglättung und mit Kantenglättung bei eingeschalteter Subpixel-Positionierung und ausgeschalteter Quantisierung, Schriftglättung nicht erlaubt; für PixelMplus12 dasselbe mit um den Versatz verschobener Grundlinie; die Body- und Caption-1-Größen aus den Human Interface Guidelines, bei denen ein Schriftpixel bei 3× ganzzahlig ist; und das erste Zeichen jeder Zeile eines japanischen Absatzes von 131 Zeichen, vonCTFramesetterbei 8 bis 20 Em gesetzt, ohne Kennung und mitkCTLanguageAttributeName“ja”, gegen eine Liste von Zeichen, die keine Zeile beginnen dürfen. DotGothic16 hat kein Designraster; es wird daher nominell mit 16 Punkten pro Em (62,5 Einheiten pro Punkt) und dem 1,25- bis 4-Fachen davon gezeichnet und mit 32 Pixeln pro Em gesetzt, einer Größe, gewählt nach seinem Namen und dem Punktabstand inmeasure_outline_coords.out, die die Ausgabe ausgibt. Jedes Rendering schließt Schriftglättung aus (setAllowsFontSmoothing(false)). ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Jenni Lada, „Interview: Preparing Final Fantasy Pixel Remaster for the Switch and PS4“, Siliconera, 2. Juni 2023, der Produzent Naofumi Takuma über die neue Schriftoption („We didn’t have any alternative data saved on file in-house for the Japanese language font, so we decided to create a new one“ (für die japanische Schrift hatten wir intern keine alternativen Daten gespeichert, also beschlossen wir, eine neue zu erstellen); „around 7,500 characters“ (rund 7.500 Zeichen) gegenüber „a few hundred“ (einigen hundert)), abgerufen am 5. Oktober 2026, https://www.siliconera.com/interview-preparing-final-fantasy-pixel-remaster-for-the-switch-and-ps4/. ↩↩↩↩↩↩
-
Messung des Autors, 5. Oktober 2026:
figures/dump_glyphs.swiftim Entwurfsordner zu diesem Beitrag, kompiliert mitswiftc -Ound ausgeführt unter macOS 27.0 (26A428), Ausgabefigures/glyphs.txt: PixelMplus10 Regular bei 10 Pixeln, von Core Text gezeichnet, „Nice card!“ mit 0 von 94 Tintenpixeln als Teilpixel, wenn Schriftglättung nicht erlaubt ist (wiemeasure_coretext.swiftzeichnet), und 178 von 272 mit der Voreinstellung des Bitmap-Kontexts; die japanische Beispielzeile 0 von 164 und 287 von 451. ↩↩↩↩↩↩↩↩↩↩ -
Apple, Human Interface Guidelines, „Typography“ (die Standard- und Mindesttextgrößen, 17 und 11 Punkt unter iOS und iPadOS; „Follow the recommended default and minimum text sizes for each platform“ (Halten Sie sich an die empfohlenen Standard- und Mindesttextgrößen jeder Plattform); „If you use a custom font, make sure it implements the same behaviors“ (Wenn Sie eine eigene Schrift verwenden, stellen Sie sicher, dass sie dieselben Verhaltensweisen umsetzt); die Dynamic-Type-Tabellen von iOS), abgerufen am 5. Oktober 2026, https://developer.apple.com/design/human-interface-guidelines/typography. ↩↩↩↩↩↩↩
-
Messung des Autors, 5. Oktober 2026:
measure_kiradex_text.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_kiradex_text.out, ausgeführt um 12:34 Uhr pazifischer Zeit gegen Kiradex bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, ein Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde; das Skript liest die Dateien vollständig, nach Symbol, nicht nach Zeile. Eingaben, nur aus dem Kiradex-Repository gelesen, wie es auf der Festplatte lag:server/app/lines.py(23 Zeilen, 3 bis 40 Zeichen, Median 16),server/app/names.py(Handles aus zwei Wörtern aus Listen von 20 und vier Ziffern, höchstens 20 Zeichen), jeder Aufruf von.kit941FontinKiradex/World/*.swift(Caption 10, Label 3, Body 3, Title 3, in vier Dateien), die Schriftfamilie des Themes, die Modifier der Sprechblase, die Bedienungshilfe-Modifier der Bühne, eine Suche im Quellcode der App nachAccessibilityComponent,accessibilityDirectTouch,updatesFrequently,AccessibilityNotification,typesettingLanguage,UIFontMetrics,ScaledMetricunddynamicTypeSize(je 0),knownRegions(Base, en) und die Zahl der.xcstrings- und.lproj-Dateien (0); der Maßstab der Welt nach der Regel vonPlazaRig.fitfür die Gerätegrößen, die diese Reihe aus den Simulatorprofilen von Xcode 27 gemessen hat (iPhone 18 Pro Max 440 mal 956 Punkt, iPhone Duo außen 466 mal 678, innen 669 mal 951, alle bei 3×); und ausmeasure_coretext.outEm und Vorschübe jeder in Frage kommenden Schrift, woraus sich ergeben: Zeichen pro Zeile der Box nach einem Einzug von 48 Punkt, Breiten der Sprechblase für die längste vorgegebene Zeile beim= 4, 5, 6 und 8 (283, 349, 416 und 549 Punkt: ihre Vorschübe in dieser Größe plus die 8 Punkt Polsterung der Sprechblase pro Seite, wobei der Rand innerhalb der Sprechblase gezeichnet wird) und die aufmgerundeten Body-Größen für ein Em von 10 Pixeln, eine Hälfte aufgerundet. Später am 5. Oktober ergänzt, mit dem früheren Skript und der früheren Ausgabe daneben: die Rundung bei 2× mit dem kleinstenmvon mindestens 11 Punkt (4 bei 3×, 3 bei 2×); die Box unter dem Rahmen des Briefings (die Breite abzüglich 32 Punkt, abgerundet auf ganze Schriftpixel, 8 Schriftpixel Rahmen pro Seite; auf dem 18 Pro Max beim= 5 von 1.224 auf 1.220 Gerätepixel, 45 lateinische oder 22 vollbreite Zeichen pro Zeile); die Seiten von „handle: line“ für alle 400 Wortpaare ausnames.pyund alle 23 Zeilen bei den zwölf Body-Größen auf fünf Ansichten (zwei Zeilen pro Seite, gierige Umbrüche an Leerzeichen, jedes druckbare ASCII-Zeichen 5 Schriftpixel breit nachprobe_line_start_glyphs.out); die Obergrenze der Sprechblase auf jedem iPhone ausmeasure_ios27_iphones.out; die Grenze des Servers von 218 Schriftpixeln; und die Summe aus 120 Additionen von 1/120. Später an diesem Tag ergänzt, mit dem früheren Skript und der früheren Ausgabe daneben und jeder früheren Zeile der Ausgabe unverändert: der Platz und die Obergrenze auf der sicheren Breite, ohne seitliche Einzüge auf den Telefonen und, auf dem äußeren Display des Duo im Hochformat, sowohl ohne als auch mit dem nachlaufenden Einzug von 84 Punkt, den der Duo-Beitrag dieser Reihe gemessen hat, aus jenem Beitrag ausgelesen (sichere Breite 382, Platz 350, Obergrenze 5 bei 349,33 Punkt; die Box bei der Standardgröße 38 lateinische oder 19 vollbreite Zeichen unter dem Rahmen, 40 oder 20 nach dem heutigen Einzug); die Seiten von „handle: line“ auf dieser sicheren Breite; die Breiten für den Platzierungstest; die Grenze des Servers in diesem Platz (296 und 302,67 Punkt beim= 4, in 350); und ausserver/app/npcs.pydie vier Sammler der Stadt, ihre Handles, die Seiten ihrer Zeilen bei AX3 auf dem 18 Pro Max (höchstens 2) und die Tap-Grenze für den Test aus Punkt 4, (3 − 1) Zeilen × 2 Seiten, ein Tap pro Seite bei Instant: 4. Am 15. Oktober wurde diese letzte Zeile für den Test in seiner jetzigen Form neu berechnet, aus denselben Eingaben, soweit die Ausgabe es zeigt (die Bühnendatei aus der um 12:28 gelesenen Kopie vom 5. Oktober;lines.py,names.pyundnpcs.pyseit dem 2. und 3. Oktober unverändert; die übrigen Eingaben aus dem aktuellen Baum bei Commitfc9d4876gelesen, der dieselben Zeilen ausgab), mit dem früheren Skript und der früheren Ausgabe daneben; jede andere Zeile der Ausgabe erscheint wie zuvor. Später am 15. Oktober ergänzt, mit dem früheren Skript und der früheren Ausgabe daneben und jeder früheren Zeile unverändert: die Fälle des Platzierungstests, in denen die heute längste Zeile bei keinem erlaubtenmpasst (360 und 375 Punkt bei 3× und 375 bei 2× mit dem Einzug von 84 Punkt, und 375 bei 2× mit 16 pro Seite: beim ersten ein Platz von 244 Punkt gegen 282,67 Punkt beim₀); die Obergrenze mit einer japanischen Zeile an der Grenze des Servers, 21 × 10 = 210 Schriftpixel (5 auf dem 18 Pro Max, 5 und 4 auf dem Duo ohne und mit der Schiene, 4 bei 360 Punkt bei 3×, 3 bei 2×); und dasmder Sprechblase, das die Aufnahmen finden sollen, das Kleinere aus demmder Box minus eins, nie unterm₀, und der Obergrenze über beide Sprachen (4 bei der Standardgröße auf den 3×-Ansichten, 3 auf den 2×; bei AX3 die Obergrenze). Am selben Abend ebenso ergänzt: jede Breite, diemeasure_ios27_iphones.outaufführt, ohne seitliche Einzüge, mit 16 Punkt pro Seite und mit dem nachlaufenden Einzug von 84 Punkt, mit der heutigen englischen Obergrenze, der Obergrenze mit einer japanischen Zeile an der Grenze und beiden (ohne Einzüge: 4 bei 360 und 375, 4 bei 390 und 393 mit der japanischen Zeile, 5 von 402 bis 440, 3 bei 2×); wo die heute längste Zeile bei keinem erlaubtenmpasst (mit dem Einzug von 84 Punkt bei 360, 375, 390 und 393 Punkt bei 3× und bei 375 und 414 bei 2×; mit 16 pro Seite bei 375 bei 2×); und „Hi!“ beim₀, 36 Punkt bei 3× und 38,50 bei 2×, was in jeden Fall passt. Danach ergänzt: dieselbe Tabelle mit einer lateinischen Zeile an der Grenze, 43 × 5 = 215 Schriftpixel, neben der heutigen Zeile und der japanischen, und die Fälle, in denen jede bei keinem erlaubtenmpasst: 7, 8 und 10 der 36. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
pret,
pokered/data/text_boxes.asmbei Commitd2704a6, Zeile 10 (db MESSAGE_BOX, 0, 12, 19, 17), gelesen am 5. Oktober 2026, https://github.com/pret/pokered/blob/master/data/text_boxes.asm. ↩↩ -
pret,
pokeemerald/src/text.cbei Commit731ad5b(sFontInfosab Zeile 119;sDownArrowYCoords{ 0, 1, 2, 1 }in Zeile 75 undsWindowVerticalScrollSpeedsin Zeile 76;AddTextPrintersetzttextSpeed = speedin Zeile 281 und--sTempTextPrinter.textSpeed;in Zeile 296; dasdownArrowDelay = 8des Pfeils in Zeile 832; im FallRENDER_STATE_HANDLE_CHARif (JOY_HELD(A_BUTTON | B_BUTTON) && subStruct->hasPrintBeenSpedUp)in Zeile 944, das Herunterzählenif (textPrinter->delayCounter && textPrinter->textSpeed)in Zeile 947,canABSpeedUpPrintund ein neuer Druck auf A oder B, derhasPrintBeenSpedUpsetzt, in den Zeilen 950 bis 953, undif (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED) && gTextFlags.autoScroll), das den Zähler auf 3 setzt, sonst auftextSpeed, in den Zeilen 958 bis 961;EXT_CTRL_CODE_JPNin Zeile 1094;DecompressGlyph_Normalab Zeile 1853 undGetGlyphWidth_Normalab Zeile 1887), gelesen am 5. Oktober 2026, https://github.com/pret/pokeemerald/blob/master/src/text.c. ↩↩↩↩↩↩↩↩↩↩↩ -
pret,
pokefirered/src/text.cbei Commit037335f, Zeilen 639 bis 647 (im FallRENDER_STATE_HANDLE_CHARsetztif (JOY_HELD(A_BUTTON | B_BUTTON) && subStruct->hasPrintBeenSpedUp)den Zähler auf 0, undgTextFlags.canABSpeedUpPrint && JOY_NEW(A_BUTTON | B_BUTTON)setzthasPrintBeenSpedUp, während eine Verzögerung herunterzählt), gelesen am 5. Oktober 2026, https://github.com/pret/pokefirered/blob/master/src/text.c. ↩↩↩ -
pret,
pokecrystal/home/print_text.asmbei Commit5beda23(Zeile 4, „The text speed setting in wOptions is actually a frame count“ (die Texttempo-Einstellung in wOptions ist in Wahrheit eine Anzahl von Frames), undPrintLetterDelay, das einen Frame pro Buchstabe wartet, solange A oder B gehalten wird) undpokered/constants/ram_constants.asmbeid2704a6(Zeilen 38 bis 40:TEXT_DELAY_FAST1,TEXT_DELAY_MEDIUM3,TEXT_DELAY_SLOW5), gelesen am 5. Oktober 2026, https://github.com/pret/pokecrystal/blob/master/home/print_text.asm. ↩↩ -
pret,
pokecrystal/home/joypad.asmbei Commit5beda23(WaitPressAorB_BlinkCursorin Zeile 342;BlinkCursorin Zeile 442, das das Tile beihlcoord 18, 17zwischen'▼'und'─'wechselt), gelesen am 5. Oktober 2026, https://github.com/pret/pokecrystal/blob/master/home/joypad.asm. Die Periode des Blinkens wurde nicht abgeleitet. ↩↩↩ -
Num Kadoma, littlelimit.net, „font“, der Lizenzabschnitt für Misaki, k8x12 und die anderen Schriften des Autors („These fonts are free software. Unlimited permission is granted to use, copy, and distribute them, with or without modification, either commercially or noncommercially.“ (Diese Schriften sind freie Software. Unbeschränkt erlaubt ist, sie mit oder ohne Änderung, kommerziell wie nichtkommerziell, zu nutzen, zu vervielfältigen und weiterzugeben.)), abgerufen am 5. Oktober 2026, https://littlelimit.net/font.htm#license. ↩↩↩↩↩
-
itouhiro, PixelMplus,
README.md(TrueType nur mit Konturen, „埋め込みビットマップは なし“ (keine eingebetteten Bitmaps); „JIS第1・第2水準のすべての漢字を収録“ (enthält alle Kanji der JIS-Stufen 1 und 2) und ISO-8859-1; PixelMplus12 und PixelMplus10; aus den M+ BITMAP FONTS gebaut; Lizenz M+ FONT LICENSE) undmisc/mplus_bitmap_fonts/LICENSE_E(die drei Sätze der M+ FONT LICENSE), bei Commitd89b95f, gelesen am 5. Oktober 2026, https://github.com/itouhiro/PixelMplus/blob/master/misc/mplus_bitmap_fonts/LICENSE_E. ↩↩↩↩↩ -
Messung des Autors, 5. Oktober 2026:
measure_outline_coords.swiftim Belegordner des Autors zu diesem Beitrag, kompiliert und ausgeführt unter macOS 27.0, Ausgabemeasure_outline_coords.out: die rohen x- und y-Konturkoordinaten vonH,A,oundあin PixelMplus12 Regular und DotGothic16 sowie vonH,Aundoin Silkscreen, in Einheiten von 1.000 pro Em. ↩↩↩↩↩↩↩ -
Apple, Human Interface Guidelines, „Accessibility“ („Ideally, give people the option to enlarge text by at least 200 percent (or 140 percent in watchOS apps).“ (Geben Sie Menschen idealerweise die Möglichkeit, Text um mindestens 200 Prozent zu vergrößern, in watchOS-Apps um 140 Prozent.)), abgerufen am 5. Oktober 2026, https://developer.apple.com/design/human-interface-guidelines/accessibility. ↩↩↩
-
W3C, „Requirements for Japanese Text Layout“, Working Group Note, 11. August 2020, Abschnitt 3.1.7 (die Zeilenanfangsregel und die Anmerkung zu den weniger strengen Regeln), abgerufen am 5. Oktober 2026, https://www.w3.org/TR/jlreq/. ↩↩↩↩↩↩↩↩
-
Recherchedossier des Autors zu diesem Beitrag, 5. Oktober 2026 (privat): die Messungen oben, die Fallstudien und ein erster Entwurf des Briefings für Kiradex. ↩↩↩
-
Blake Crosley, „Pixel-Art Worlds on iPhone: What the 16-Bit Masters Knew“, blakecrosley.com, 3. Oktober 2026: Regel 10 („Text is art“ (Text ist Grafik), das „use font size 16, 32, 48, etc“ (Schriftgröße 16, 32, 48 usw. verwenden) der m5x7-Seite und der Satz über den Textfensterrahmen von Smaragd mit 24 mal 24), die Größenarithmetik zu Text bei k = 8 und k = 6, der Absatz zum Pixel Remaster, der GoNintendo für etwa 7.500 japanische Zeichen zitiert, und der Textplan („m5x7 at integer multiples in a 24-by-24 nine-slice box, two lines, typewriter reveal, a two-frame advance arrow“ (m5x7 in ganzzahligen Vielfachen in einer Nine-Slice-Box von 24 mal 24, zwei Zeilen, Schreibmaschinen-Enthüllung, ein Weiterpfeil mit zwei Frames)), gelesen am 5. Oktober 2026, https://blakecrosley.com/blog/pixel-art-world-on-iphone. Jener Beitrag wird hier zitiert und nicht verändert. ↩↩↩↩↩↩↩↩↩↩
-
Kiradex-Quellcode,
Kiradex/KiradexTheme.swift, Zeile 12 (let fontFamily: Kit941.FontFamily = .systemDesign(.monospaced)), gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository). ↩↩ -
Kiradex-Quellcode,
Kiradex/World/PlazaStage.swift, gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository): Zeilen 146, 155 und 189 (stepTracewird in der Make-Closure derRealityViewauf einen Build-Fehler gesetzt, inrig.onStepauf jeden Schritt und unter-airProbein einem.taskauf den Bericht der Luft; eine Lesung derselben Datei um 12:42 zeigte eine vierte,stepTrace = "lap done"unter einem neuen-plazaLapDemo), Zeilen 58 bis 61 (stepTrace, „The player’s last step, “x,y facing”, as the stage’s accessibility value: the walks read it, since nothing else the simulator logs reaches them.“ (der letzte Schritt der Spielfigur, „x,y Blickrichtung“, als Bedienungshilfe-Wert der Bühne: die Lauftests lesen ihn, da nichts anderes, was der Simulator protokolliert, sie erreicht.)), Zeilen 313 bis 315 (.accessibilityElement(),.accessibilityLabel("The plaza"),.accessibilityValue(stepTrace)), Zeilen 289 bis 293 (die Sprechblasen, das letzte.overlayimGeometryReaderder Bühne in den Zeilen 121 bis 294), Zeilen 295 bis 309 (die beiden Overlays der Bühne darüber: Scanlines,.black.opacity(0.16)einen Punkt hoch alle 3 Punkt, und eine Vignette alsRadialGradient), Zeilen 402 bis 418 (bubbles(of:in:): eine Zeile, angezeigt, solangetimeline.date.timeIntervalSince(said.at) < 4, positioniert am Ansichtspunkt des Kopfes abzüglichKit941.Spacing.lgohne Begrenzung, Trefferprüfung aus) und Zeilen 444 bis 459 (die AnsichtBubble,.padding(.horizontal, Kit941.Spacing.sm), dann.overlay(Rectangle().strokeBorder(...)), ihr Kommentar „A line said, as the old games drew it: a cream box with a dark border.“ (Eine gesprochene Zeile, so wie die alten Spiele sie zeichneten: eine cremefarbene Box mit dunklem Rand.), Caption fett,WorldInk.paper, ein Tintenrand vonKit941.Spacing.xxs,.fixedSize(),.accessibilityLabel("Said: \(text)")). ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Kiradex-Quellcode,
Kiradex/World/WorldHUD.swift, gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository); die Datei trug das Datum des 4. Oktober und änderte sich während der Lesung nicht: Zeilen 31 bis 38 (WorldInk, „The world’s own colours, as the old games drew a text box: cream paper“ (die eigenen Farben der Welt, so wie die alten Spiele eine Textbox zeichneten: cremefarbenes Papier), und seine Papierfarbe), Zeilen 40 bis 44 (die Zeile des Ortes „in a text box at the bottom. Half open, the box keeps to the wider side of the fold.“ (in einer Textbox unten. Halb geöffnet hält sich die Box an die breitere Seite des Falzes.)), Zeilen 61 bis 79 (die Bedienelemente in einemGeometryReader, eingerückt um.padding(Kit941.Spacing.md), die Box über diese Breite oder, halb geöffnet, über die Breite der breiteren Fläche abzüglichKit941.Spacing.mdpro Seite) und Zeilen 84 bis 101 (die Box: Titel in Caption fett, in Großbuchstaben; Status in Caption halbfett, Kennung<name>-status,plaza-statusauf dem Platz; Papierhintergrund; ein Tintenrand vonKit941.Spacing.xxs;.allowsHitTesting(false)unter dem Kommentar „Taps go through to the ground under it.“ (Taps gehen zum Boden darunter durch.)); sowieKiradex/World/PlazaStage.swiftZeilen 581 und 582, woPlazaViewdasWorldHUDmitwordsals Status über die ganze Bühne legt, und Zeilen 725 bis 736 (words: die Wendung der Tageszeit, die Zahl der Anwesenden und ein Ratschlag, die verdienten Bänder und die Wendung der Jahreszeit). Die Abstände des Kits,Sources/Kit941/Tokens/Spacing.swiftin 941Kit:xxs2,xs4,sm8,md16,lg24 Punkt auf dem iPhone. ↩↩↩↩↩↩↩ -
Kiradex-Quellcode,
Kiradex.xcodeproj/project.pbxproj, Zeilen 1138 bis 1141 (knownRegions = (Base, en)), gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository); die Datei hatte bis 12:42 Zeilen hinzugewonnen. ↩↩ -
Kiradex-Quellcode,
server/app/lines.py, gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository): der Docstring „The preset lines: everything anyone can say in the plaza.“ (Die vorgegebenen Zeilen: alles, was irgendwer auf dem Platz sagen kann.), die 23 Einträge vonLINES(ab Zeile 5) und der Kommentar in Zeile 20, vor Index 14, „Indices are fixed; add at the end only, the app shows them by number.“ (Die Indizes sind fest; nur am Ende hinzufügen, die App zeigt sie nach Nummer.) ↩↩↩↩ -
Kiradex-Quellcode, gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit
334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository):scripts/forge/kit.py, Zeilen 529 und 530 (def sign():, „A hanging sign on a bracket, 12 × 11.“ (ein hängendes Schild an einer Halterung, 12 × 11.)),Kiradex/World/TileMap.swift, Zeile 52 (der Kartenbuchstabe"S": .sign), undKiradex/Resources/World/town.json(eineS-Zelle, bei x 7, Reihe 10, um 12:33 mit dem Python-Moduljsongelesen). ↩↩↩↩ -
Methode. Dekompilierungen von pret, flache Klone, gelesen bei pokeemerald
731ad5b(1. Oktober 2026), pokefirered037335f(26. September 2026), pokecrystal5beda23(29. September 2026) und pokeredd2704a6(22. September 2026), https://github.com/pret. Final Fantasy VI aus der Disassemblierung everything8215/ff6 bei813013276c952fdd27edcf7b8b86f17291542cbf(14. September 2026), die Code und Rip-Listen enthält, nicht die Grafiken des ROMs, https://github.com/everything8215/ff6. PixelMplus flach geklont beid89b95f04eeb95bf98bb09cb9234a2f99d186df5(2. Juni 2013); Misaki und k8x12, die Ausgaben vom 2021-05-05 in TTF und BDF, von der Website des Autors heruntergeladen; Press Start 2P, Silkscreen und DotGothic16 (Schriftdateien,OFL.txtundMETADATA.pb) ausgoogle/fontsbei9710da1(30. September 2026). Webseiten abgerufen und gespeichert am 5. Oktober 2026. Dreizehn Skripte im Belegordner des Autors zu diesem Beitrag, zehn in Python und drei in Swift, und ein weiteres Swift-Skript bei den Abbildungen dieses Beitrags,dump_glyphs.swift, erzeugen jede gemessene Zahl, jedes mit seiner Ausgabe daneben gespeichert. pret baut die englischen Spiele; kein japanisches ROM wurde gelesen. ↩↩↩↩↩↩ -
pret,
pokeemerald/src/fonts.c(gFontNormalLatinGlyphWidthsab Zeile 148) undpokeemerald/charmap.txt(Zeilen 50 bis 52, Sonderglyphen für Franchise-Wörter) bei Commit731ad5b, gelesen am 5. Oktober 2026, https://github.com/pret/pokeemerald/blob/master/src/fonts.c. ↩↩ -
Martin Korth, GBATEK, „LCD Dimensions and Timings“ („Total 228 lines, 16.743 ms, 280896 cycles - ca. 59.737 Hz“ (insgesamt 228 Zeilen, 16,743 ms, 280.896 Zyklen, etwa 59,737 Hz); 160 sichtbare Zeilen; 240 Punkte pro sichtbarer Zeile), abgerufen am 5. Oktober 2026, https://problemkaputt.de/gbatek-lcd-dimensions-and-timings.htm. ↩
-
Arithmetik des Autors auf Grundlage der gemessenen Zahlen: 216 ÷ 5,25 = 41 Zeichen; 59,737 ÷ 1 = 59,7 Zeichen pro Sekunde; 191 × 1,25² = 298 Pixel; die −33 Einheiten von PixelMplus12 ÷ 83,33 Einheiten pro Pixel = −0,396 Pixel (die Messung meldet −0,39, die Mitte ihrer Klasse); 7.500 gegenüber 6.879; 11 von 12 und 9 von 12 Body-Größen neben dem Raster, als Komplement von 1 und 3 ganzzahligen; 14 ÷ 17 = 82 % und 53 ÷ 17 = 312 %; 13,33 ÷ 16,67 = 80 % und 53,33 ÷ 16,67 = 320 %; 11 Punkt ÷ 2 Punkt pro Texel = 5,5 Texel; 4 × 10 ÷ 3 = 13,33 Punkt; 12 Schriftpixel × 5 ÷ 3 = 20 Punkt; 440 − 32 = 408, 360 − 32 = 328 und 375 − 32 = 343 Punkt; 40 × 5 × 3 ÷ 2 + 16 = 316 Punkt bei 2×; ⌈11 × 3 ÷ 10⌉ = 4 und ⌈11 × 2 ÷ 10⌉ = 3, und 10 × 3 ÷ 2 = 15 Punkt; (360 − 48) × 3 ÷ 4 = 234 und (375 − 48) × 2 ÷ 3 = 218 Schriftpixel, und 218 ÷ 5 = 43 lateinische und 218 ÷ 10 = 21 vollbreite Zeichen; 21 × 10 × 4 ÷ 3 + 16 = 296 und 21 × 10 × 3 ÷ 2 + 16 = 331 Punkt; (440 − 32) × 3 = 1.224 Gerätepixel, ÷ 5 = 244,8, also 244 Schriftpixel (1.220 Gerätepixel), abzüglich 2 × 8 = 228, ÷ 5 = 45 lateinische und ÷ 10 = 22 vollbreite Zeichen; 15 × 3 ÷ 10 = 4,5, aufgerundet auf 5; 120 Additionen von 1/120 in doppelter Genauigkeit = 0,9999999999999989, × 30 = 29,999999999999968, abgerundet auf 29; 1,5 Sekunden × 12 = 18 Zeichen; 20 × 5 × 4 ÷ 3 = 133 Punkt und 20 × 5 × 3 ÷ 2 = 150 Punkt bei 2×; 466 − 84 = 382 und 382 − 32 = 350 Punkt, 466 − 32 = 434; 40 × 5 × 5 ÷ 3 + 16 = 349,33 Punkt; (382 − 32) × 3 ÷ 5 = 210 Schriftpixel, abzüglich 2 × 8 = 194, ÷ 5 = 38 lateinische und ÷ 10 = 19 vollbreite Zeichen; (382 − 48) ÷ (5 × 5 ÷ 3) = 40,08 und ÷ (10 × 5 ÷ 3) = 20,04; 43 × 5 × 4 ÷ 3 + 16 = 302,67 Punkt; 360 − 84 − 32 = 244 Punkt; (3 − 1) × 2 × 1 = 4 Taps; 16 Texel × 2,67 Punkt = 42,7 Punkt und 13 × 2,67 = 34,7; 9 Frames ÷ 60 = 150 Millisekunden, vier Schritte 600 Millisekunden; 3 Punkt × 3 = 9 Gerätepixel zwischen den Scanlines, jede 1 Punkt × 3 = 3 Gerätepixel hoch. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
pret,
pokeemerald/src/battle_message.cbei Commit731ad5b(Zeilen 3002 und 3003: automatisches Scrollen an beigBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED); Zeile 3010,speed = 1für das Nachrichtenfenster in Link-Kämpfen; Zeile 3012,speed = sRecordedBattleTextSpeeds[GetTextSpeedInRecordedBattle()]eines aufgezeichneten Kampfs, die Tabelle{8, 4, 1, 0}in Zeile 1957) undpokeemerald/src/scrcmd.c(ScrCmd_messageautoscrollab Zeile 1286, das in den Zeilen 1292 und 1293autoScrollundforceMidTextSpeedsetzt), gelesen am 5. Oktober 2026, https://github.com/pret/pokeemerald/blob/master/src/battle_message.c. ↩↩↩ -
pret,
pokeemerald/charmap.txtbei Commit731ad5b, Zeilen 1087 bis 1089 ('\l' = FA @ scroll up window text,'\p' = FB @ new paragraph,'\n' = FE @ new line), undinclude/constants/characters.h, Zeilen 175 und 176 (CHAR_PROMPT_SCROLL, „waits for button press and scrolls dialog“ (wartet auf einen Tastendruck und scrollt den Dialog);CHAR_PROMPT_CLEAR, „waits for button press and clears dialog“ (wartet auf einen Tastendruck und leert den Dialog)), mitsrc/text.cZeilen 968 bis 971 (CHAR_NEWLINEsetztcurrentYeine Zeile tiefer) und 1102 bis 1109 (die beiden Eingabeaufforderungen gehen inRENDER_STATE_CLEARundRENDER_STATE_SCROLL_START), gelesen am 5. Oktober 2026, https://github.com/pret/pokeemerald/blob/master/charmap.txt. ↩ -
pret,
pokeemerald/src/text_window.c(message_box.pngin Zeile 53;LoadMessageBoxGfxin Zeile 93;LoadUserWindowBorderGfxin Zeile 110),pokeemerald/include/text_window.h(#define WINDOW_FRAMES_COUNT 20in Zeile 4),pokeemerald/src/option_menu.c(die Option FRAME) undpokeemerald/graphics/text_window/bei Commit731ad5b, gelesen am 5. Oktober 2026, https://github.com/pret/pokeemerald/blob/master/src/text_window.c. ↩↩↩ -
pret,
pokeemerald/data/text/und diescripts.incjeder Karte bei Commit731ad5b, darunterdata/maps/LittlerootTown/scripts.inc, Zeile 854 (.string "MOM: {PLAYER}, we're here, honey!\p"), gelesen am 5. Oktober 2026, https://github.com/pret/pokeemerald/blob/master/data/maps/LittlerootTown/scripts.inc. ↩↩ -
pret,
pokeemerald/src/international_string_util.c,src/contest.cundsrc/battle_tower.c(die CodesEXT_CTRL_CODE_JPNundEXT_CTRL_CODE_ENGin Namen) undgraphics/fonts/(japanese_normal.png,japanese_small.png,japanese_bold.png,japanese_frlg_male.png) bei Commit731ad5b, gelesen am 5. Oktober 2026, https://github.com/pret/pokeemerald/blob/master/src/international_string_util.c. ↩↩ -
pret,
pokefirered/src/new_menu_helpers.cbei Commit037335f(sStandardTextBox_WindowTemplatesab Zeile 34,.width = 26in Zeile 40, und die Verzögerungen des Texttempos) undpokefirered/src/text_printer.c(AddTextPrinter,textSpeed = speedin Zeile 78 und--sTempTextPrinter.textSpeed;in Zeile 93) bei Commit037335f, gelesen am 5. Oktober 2026, https://github.com/pret/pokefirered/blob/master/src/new_menu_helpers.c. ↩ -
Pan Docs, „Rendering“ („One frame: 70224 dots @ 59.7 fps“ (ein Frame: 70.224 Punkte bei 59,7 fps); ein Frame „takes ~16.74 ms instead of ~16.67“ (dauert etwa 16,74 ms statt etwa 16,67)), gbdev.io, abgerufen am 5. Oktober 2026, https://gbdev.io/pandocs/Rendering.html. ↩
-
pret,
pokecrystal/gfx/font.asmbei Commit5beda23(die RahmenFRAME_1bisFRAME_8,TEXTBOX_FRAME_TILESje 6 Tiles zu 1 Bit, ein neunter Rahmen ungenutzt) undgfx/font/font.png, gelesen am 5. Oktober 2026, https://github.com/pret/pokecrystal/blob/master/gfx/font.asm. ↩ -
everything8215, ff6,
tools/rip_list_en.jsonundtools/rip_list_jp.jsonbei Commit8130132(assets/gfx/window/window_%s.4bppbei0xED0000bis0xED1BFF;window_%s.palbei0xED1C00bis0xED1CFF), gelesen am 5. Oktober 2026, https://github.com/everything8215/ff6/blob/master/tools/rip_list_en.json. ↩ -
everything8215, ff6,
src/menu/config.asm(ConfigWindowNumPos,LoadWindowPal, das aus$1d57liest, die Schriftfarbe bei$1d55,ConfigColorBarTextList,ChangeConfigOption_02) undsrc/menu/menu_sram.asm(Zeile 102, „message speed = 3, battle speed = 3“ (Nachrichtentempo = 3, Kampftempo = 3)) bei Commit8130132, gelesen am 5. Oktober 2026, https://github.com/everything8215/ff6/blob/master/src/menu/config.asm. ↩↩↩ -
everything8215, ff6, bei Commit
8130132:src/btlgfx/gfx_cmd.asmZeilen 1101 bis 1103 (MsgSpeedTbl, „wait duration for each battle message speed“ (Wartedauer für jedes Tempo der Kampfmeldungen),$20,$30,$40,$50,$60,$70,$80,$90) und Zeilen 1151 bis 1165 (mess_wait, das die Bits 4 bis 6 von$1d4dals Index liest undWaitFrameso oft aufruft);src/menu/config.asmZeile 1499 („battle speed, battle message speed, magic order, and window pattern“ (Kampftempo, Tempo der Kampfmeldungen, Magiereihenfolge und Fenstermuster)) undChangeConfigOption_02ab Zeile 933;src/menu/menu_text.en.incZeile 346 (die Einstellungen als 1 bis 6 gezeichnet). Dateien, deren Code$1d4dberührt:src/battle/init.asm(die Befehlseinstellung, der Kampfmodus und das Kampftempo),src/btlgfx/gfx_cmd.asm,src/menu/config.asm,src/menu/field_menu.asmundsrc/menu/menu_sram.asm; keine untersrc/field/. Gelesen am 5. Oktober 2026, https://github.com/everything8215/ff6/blob/master/src/btlgfx/gfx_cmd.asm. ↩ -
everything8215, ff6,
src/field/hdma.asm(DlgWindowFixedColorTbl) undsrc/field/event.asm(Zeile 1591, „dialog window y position (1 or 18)“ (y-Position des Dialogfensters, 1 oder 18)) bei Commit8130132, gelesen am 5. Oktober 2026, https://github.com/everything8215/ff6/blob/master/src/field/hdma.asm. ↩↩↩ -
everything8215, ff6,
src/field/text.asm(LoadLetterGfx, die Dialogzeile von x 4 bis$e0,CalcTextWidth,NewLine,UpdateDlgTextOneLine, der zentrierte Kartentitel, 100 Frames lang gezeigt) undsrc/gfx/font_gfx.asm(FontWidth) bei Commit8130132, gelesen am 5. Oktober 2026, https://github.com/everything8215/ff6/blob/master/src/field/text.asm. ↩↩↩↩↩ -
everything8215, ff6,
tools/rip_list_jp.json(large_font.jp.1bppbei0xC494C0bis0xC4FFFF) undtools/char_table/bei Commit8130132, gelesen am 5. Oktober 2026, https://github.com/everything8215/ff6/tree/master/tools/char_table. ↩ -
everything8215, ff6,
src/field/reset.asm(die Feldschleife: Warten auf die vertikale Austastlücke,UpdateDlgTexteinmal pro Durchlauf aufrufen) bei Commit8130132, gelesen am 5. Oktober 2026, https://github.com/everything8215/ff6/blob/master/src/field/reset.asm. Die Disassemblierung baut das englische und das japanische ROM aus einer Quelle. ↩↩ -
Data Crystal, „Chrono Trigger/ROM map“, datacrystal.tcrf.net, abgerufen am 5. Oktober 2026: HTTP 403, nicht gelesen, https://datacrystal.tcrf.net/wiki/Chrono_Trigger/ROM_map. ↩↩↩
-
Kiradex,
docs/TestFlight.md, Schritt 5 (Zeilen 192 bis 194: Wählt man im Dex Japanisch, erscheinen Sets und Karten mit ihren japanischen Namen und dem Englischen darunter), gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository). ↩ -
Num Kadoma, littlelimit.net, „8×8ドット日本語フォント「美咲フォント」“ (die Zelle von 8 mal 8 der Übersicht, JIS-Stufen 1 und 2 und Tinte in 7 mal 7; die Beschreibungen von Misaki Mincho und Misaki Gothic 2nd; der Hinweis auf die M+ FONTS-Lizenz; der Bericht über ihre Entstehung für den japanischen Anzeigetreiber des PC-E500), abgerufen am 5. Oktober 2026, https://littlelimit.net/misaki.htm. ↩↩↩↩
-
Num Kadoma, littlelimit.net, „8×12ドット日本語フォント「k8x12」“ (die Zelle von 8 mal 12, JIS-Stufen 1 und 2, die Varianten L und S, die Anmerkung der Variante S zur 8-mal-8-Grafik alter Konsolen), abgerufen am 5. Oktober 2026, https://littlelimit.net/k8x12.htm. ↩
-
Google Fonts,
ofl/dotgothic16/OFL.txt(SIL Open Font License 1.1, Copyright 2020 The DotGothic16 Project Authors, kein Reserved Font Name) undMETADATA.pb(Designer Fontworks Inc.; Teilmengen cyrillic, japanese, latin, latin-ext; hinzugefügt 2020-12-15) bei9710da1, gelesen am 5. Oktober 2026, https://github.com/google/fonts/blob/main/ofl/dotgothic16/OFL.txt. ↩↩↩↩ -
Google Fonts,
ofl/pressstart2p/OFL.txt(SIL Open Font License 1.1, „with Reserved Font Name “Press Start 2P”“ (mit dem Reserved Font Name „Press Start 2P“)) undMETADATA.pb(Designer CodeMan38) bei9710da1, gelesen am 5. Oktober 2026, https://github.com/google/fonts/blob/main/ofl/pressstart2p/OFL.txt. ↩↩↩ -
Google Fonts,
ofl/silkscreen/OFL.txt(SIL Open Font License 1.1, kein Reserved Font Name) undMETADATA.pb(Designer Jason Kottke) bei9710da1, gelesen am 5. Oktober 2026, https://github.com/google/fonts/blob/main/ofl/silkscreen/OFL.txt. ↩↩ -
DaFont, „Pixel Operator Font“ (von Jayvee Enaguas; „Bitmap (16 px)“; 15 Schriftdateien; 241 Glyphen; die Notizen des Autors, „Changed licence to Creative Commons Zero (CC0) 1.0“ (Lizenz auf Creative Commons Zero (CC0) 1.0 geändert) und „licensed under a Creative Commons Zero (CC0) 1.0“ (unter Creative Commons Zero (CC0) 1.0 lizenziert)), abgerufen am 5. Oktober 2026, https://www.dafont.com/pixel-operator.font. Das Repository, das die Notizen nennen, https://notabug.org/HarvettFox96/ttf-pixeloperator, lieferte am 5. Oktober 2026 HTTP 404. Einzelne Quelle. ↩↩↩↩
-
Daniel Linssen, „m5x7“, itch.io („use font size 16, 32, 48, etc“ (Schriftgröße 16, 32, 48 usw. verwenden); „free to use but attribution appreciated“ (frei nutzbar, Namensnennung erwünscht); „Asset license Creative Commons Zero v1.0 Universal“ (Asset-Lizenz Creative Commons Zero v1.0 Universal); mittlere Breite 5, Oberlänge 7, Unterlänge 2, x-Höhe 5; ihre Zeichen beschrieben als „uppercase and lowercase letters, including many accented letters, numbers and most common symbols“ (Groß- und Kleinbuchstaben, darunter viele mit Akzenten, Ziffern und die gängigsten Symbole); ein Download mit frei wählbarem Preis), abgerufen am 5. Oktober 2026, https://managore.itch.io/m5x7. Die Schriftdatei wurde nicht heruntergeladen. ↩↩↩↩↩↩
-
Daniel Linssen, „m3x6“, itch.io („use font size 16, 32, 48, etc“ (Schriftgröße 16, 32, 48 usw. verwenden); „free to use with attribution“ (frei nutzbar mit Namensnennung); kein Feld für die Asset-Lizenz; ein Download mit frei wählbarem Preis), abgerufen am 5. Oktober 2026, https://managore.itch.io/m3x6. Die Schriftdatei wurde nicht heruntergeladen. ↩↩↩↩↩
-
Apple Developer Documentation, „Core Text“ („Create text layouts, optimize font handling, and access font metrics and glyph data“ (Textlayouts erstellen, die Schriftverarbeitung optimieren und auf Schriftmetriken und Glyphendaten zugreifen); iOS 3.2, macOS 10.8), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/coretext. ↩
-
Messung des Autors, 5. Oktober 2026:
measure_hig.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_hig.out: die Tabellen der gespeicherten Seite Typography, die Standard- und Mindestgrößen und jede Dynamic-Type-Tabelle von iOS von xSmall bis AX5 (Body 14, 15, 16, 17, 19, 21, 23, 28, 33, 40, 47 und 53 Punkt; Caption 1 11, 11, 11, 12, 14, 16, 18, 22, 26, 32, 37 und 43). ↩↩↩↩↩ -
Unicode Consortium, „Unicode Standard Annex #14: Unicode Line Breaking Algorithm“, Revision 57, Unicode 18.0.0, 2026-09-01 (die Klasse CJ und „Treating characters of class CJ as class NS will give CSS strict line breaking; treating them as class ID will give CSS normal breaking.“ (Werden Zeichen der Klasse CJ wie Klasse NS behandelt, ergibt das den strengen Zeilenumbruch von CSS; werden sie wie Klasse ID behandelt, den normalen.)), abgerufen am 5. Oktober 2026, https://www.unicode.org/reports/tr14/. ↩↩
-
Stardew Valley Wiki, „Modding:Dialogue“, zuletzt bearbeitet am 20. Mai 2026 (
$b; Porträtbefehle;Strings\SpeechBubbles), abgerufen am 5. Oktober 2026, https://stardewvalleywiki.com/Modding:Dialogue. ↩↩↩ -
Stardew Valley Wiki, „Modding:Custom languages“, zuletzt bearbeitet am 3. Januar 2026 (
UseLatinFont, die.fnt-Datei,FontPixelZoommit einem empfohlenen Ausgangswert von 1,5,FontApplyYOffset), abgerufen am 5. Oktober 2026, https://stardewvalleywiki.com/Modding:Custom_languages. ↩↩ -
Messung des Autors, 5. Oktober 2026:
measure_steam_languages.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_steam_languages.out, liest die Sprachtabellen der gespeicherten Steam-Shopseiten von Stardew Valley (https://store.steampowered.com/app/413150/), Celeste (https://store.steampowered.com/app/504230/), Sea of Stars (https://store.steampowered.com/app/1244090/) und Eastward (https://store.steampowered.com/app/977880/), abgerufen am 5. Oktober 2026. ↩↩↩↩↩ -
Messung des Autors, 5. Oktober 2026:
measure_apple_docs.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_apple_docs.out: Titel, Deklaration, Kurzbeschreibung, Plattformen und erste Absätze jeder gespeicherten Seite der Apple-Dokumentation, die in Abschnitt 10 zitiert wird. ↩↩ -
Apple, Human Interface Guidelines, „Designing for games“ („To keep text comfortably legible on each device, ensure that it contrasts well with the background and uses at least the recommended minimum text size in each platform.“ (Damit Text auf jedem Gerät bequem lesbar bleibt, achten Sie auf guten Kontrast zum Hintergrund und mindestens die empfohlene Mindesttextgröße der jeweiligen Plattform.)), abgerufen am 5. Oktober 2026, https://developer.apple.com/design/human-interface-guidelines/designing-for-games. ↩
-
Apple Developer Documentation, „UIFontMetrics“ („A utility object for obtaining custom fonts that scale to support Dynamic Type“ (ein Hilfsobjekt, um eigene Schriften zu erhalten, die zur Unterstützung von Dynamic Type skalieren); iOS 11.0), „scaledFont(for:)“, „scaledFont(for:maximumPointSize:)“ und „scaledValue(for:)“ („Scales an arbitrary layout value based on the current Dynamic Type settings“ (skaliert einen beliebigen Layoutwert anhand der aktuellen Dynamic-Type-Einstellungen); iOS 11.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/uikit/uifontmetrics. ↩↩↩
-
Apple Developer Documentation, „custom(:size:relativeTo:)“ (eine eigene Schrift, „that scales relative to the given
textStyle“ (die relativ zum angegebenentextStyleskaliert); iOS 14.0), https://developer.apple.com/documentation/swiftui/font/custom(:size:relativeto:), und „custom(:fixedSize:)“ (eine eigene Schrift, „that does not scale with Dynamic Type“ (die nicht mit Dynamic Type skaliert); iOS 14.0), https://developer.apple.com/documentation/swiftui/font/custom(:fixedsize:), abgerufen am 5. Oktober 2026. ↩↩↩↩↩ -
Apple Developer Documentation, „ScaledMetric“ („A dynamic property that scales a numeric value“ (eine dynamische Eigenschaft, die einen Zahlenwert skaliert); iOS 14.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/scaledmetric. ↩↩
-
Apple Developer Documentation, „dynamicTypeSize(:)“ (iOS 15.0; „When limiting the Dynamic Type size, consider if adding a large content view with
accessibilityShowsLargeContentViewer()would be appropriate.“ (Wenn Sie die Dynamic-Type-Größe begrenzen, prüfen Sie, ob eine große Inhaltsansicht mitaccessibilityShowsLargeContentViewer()angebracht wäre.)), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/view/dynamictypesize(:). ↩↩ -
Apple Developer Documentation, „accessibilityShowsLargeContentViewer()“ (iOS 15.0; „Don’t use the large content viewer as a replacement for proper Dynamic Type support.“ (Verwenden Sie den Large Content Viewer nicht als Ersatz für richtige Unterstützung von Dynamic Type.)), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/view/accessibilityshowslargecontentviewer(). ↩↩
-
Apple Developer Documentation, „UIAppFonts“ („App-specific font files located in the bundle and that the system loads at runtime“ (App-spezifische Schriftdateien im Bundle, die das System zur Laufzeit lädt); iOS 3.2), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/bundleresources/information-property-list/uiappfonts. ↩↩
-
Apple Developer Documentation, „CTFontManagerRegisterFontsForURL(:::)“ (iOS 4.1), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/coretext/ctfontmanagerregisterfontsforurl(:::). ↩
-
Apple Developer Documentation, „interpolation(:)“ (Image; iOS 13.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/image/interpolation(:). ↩
-
Apple Developer Documentation, „resizable(capInsets:resizingMode:)“ („Sets the mode by which SwiftUI resizes an image to fit its space“ (legt den Modus fest, mit dem SwiftUI ein Bild an seinen Platz anpasst); iOS 13.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/image/resizable(capinsets:resizingmode:). ↩
-
Apple Developer Documentation, „baselineOffset(:)“ (Text; „Sets the vertical offset for the text relative to its baseline“ (legt den vertikalen Versatz des Textes relativ zu seiner Grundlinie fest); iOS 13.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/text/baselineoffset(:). ↩
-
Apple Developer Documentation, „typesettingLanguage(:isEnabled:)“ (iOS 17.0; der Absatz über Text in einer Sprache, die nicht zur UI-Sprache des Geräts passt; „this language does not affect text localization.“ (Diese Sprache wirkt sich nicht auf die Lokalisierung des Textes aus.)), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/view/typesettinglanguage(:isenabled:). ↩↩
-
Apple Developer Documentation, „NSParagraphStyle.LineBreakStrategy“ (iOS 9.0) und seine Eigenschaften
standard(iOS 14.0),pushOut(iOS 9.0) undhangulWordPriority(iOS 14.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/uikit/nsparagraphstyle/linebreakstrategy-swift.struct. ↩ -
Apple Developer Documentation, „accessibilityValue(:)“ („Use this method to describe the value represented by a view, but only if that’s different than the view’s label.“ (Verwenden Sie diese Methode, um den Wert zu beschreiben, den eine Ansicht darstellt, aber nur, wenn er sich vom Label der Ansicht unterscheidet.); iOS 16.0 in der Form mit
LocalizedStringResource), https://developer.apple.com/documentation/swiftui/view/accessibilityvalue(:), und „accessibilityLabel(:)“ (iOS 16.0), https://developer.apple.com/documentation/swiftui/view/accessibilitylabel(:), abgerufen am 5. Oktober 2026. ↩↩↩ -
Apple Developer Documentation, „accessibilityDirectTouch(:options:)“ (iOS 17.0; „Direct touch areas passthrough touch events to the app rather than being handled through an assistive technology, such as VoiceOver.“ (Bereiche mit direkter Berührung reichen Berührungsereignisse an die App durch, statt sie von einer assistiven Technologie wie VoiceOver verarbeiten zu lassen.); der Bereich muss zuerst aktiviert werden), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/view/accessibilitydirecttouch(:options:). ↩↩
-
Apple Developer Documentation, „updatesFrequently“ (AccessibilityTraits; iOS 13.0; „Use this trait when you want an assistive technology to poll for changes when it needs updated information.“ (Verwenden Sie dieses Merkmal, wenn eine assistive Technologie Änderungen abfragen soll, sobald sie aktuelle Informationen braucht.)), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/accessibilitytraits/updatesfrequently. ↩
-
Apple Developer Documentation, „AccessibilityNotification.Announcement“ (iOS 17.0; das Attribut
accessibilitySpeechAnnouncementPriority), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/accessibility/accessibilitynotification/announcement. ↩↩ -
Apple Developer Documentation, „accessibilityReduceMotion“ (iOS 13.0; „If this property’s value is true, UI should avoid large animations“ (ist der Wert dieser Eigenschaft true, sollte die UI große Animationen vermeiden)), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/swiftui/environmentvalues/accessibilityreducemotion. ↩↩
-
Apple Developer Documentation, „AccessibilityComponent“ (RealityKit; „A component that stores accessibility information for an entity“ (eine Komponente, die Bedienungshilfe-Informationen für eine Entität speichert); der Name, den „VoiceOver says aloud when it describes the entity“ (VoiceOver laut sagt, wenn es die Entität beschreibt); iOS 17.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/realitykit/accessibilitycomponent. ↩↩↩↩
-
Apple Developer Documentation, „Improving the Accessibility of RealityKit Apps“ („set the properties on each visible
Entityin your scene“ (die Eigenschaften jeder sichtbarenEntityin Ihrer Szene setzen)), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/realitykit/improving-the-accessibility-of-realitykit-apps. ↩ -
Apple Developer Documentation, „RealityView“ (iOS 18.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/realitykit/realityview. ↩
-
Apple Developer Documentation, „XCUIVoiceOverService“ („Provides programmatic control of VoiceOver for UI testing“ (bietet programmatische Steuerung von VoiceOver für UI-Tests); iOS 27.0), abgerufen am 5. Oktober 2026, https://developer.apple.com/documentation/xcuiautomation/xcuivoiceoverservice. ↩↩↩
-
941Kit-Quellcode,
Sources/Kit941/Tokens/Typography/FontFamily.swiftbei Commit50bc657(28. September 2026), Zeilen 21 bis 63 (case custom(named: String), gerendert überFont.custom(_:size:relativeTo:)mit Eigengrößen von 34, 22, 17, 13 und 12 Punkt für Display, Title, Body, Label und Caption), gelesen am 5. Oktober 2026; privates Repository. ↩↩ -
Kiradex-Quellcode,
server/app/names.py(Zeilen 7 bis 14,FIRSTSundSECONDS, je 20 Wörter, und das Handle-Muster aus zwei großgeschriebenen Wörtern und vier Ziffern), gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository). ↩↩ -
Blake Crosley, „A Pixel Town Alive When Nobody Is Online: NPCs and Ghosts“, blakecrosley.com, 5. Oktober 2026 (die 23 vorgegebenen Zeilen, 14 für Spieler und 9 für die eigenen Sammler der Stadt, und eine Zeile alle 2,0 Sekunden pro Spieler), https://blakecrosley.com/blog/pixel-art-town-alive-when-nobody-is-online. ↩↩
-
Kiradex,
docs/WORLD.md, Abschnitt 5, „The stack“, Zeilen 524 und 525 (Ratenlimits: „eight moves a second, a line every two seconds“ (acht Bewegungen pro Sekunde, eine Zeile alle zwei Sekunden)), gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository). ↩↩ -
Kiradex-Quellcode, gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit
334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository):Kiradex/World/PlazaStage.swift, Zeilen 199 bis 203 (die.gesture(DragGesture(minimumDistance: 0))der Bühne, die bei Änderungtouchedund am Endeliftedaufruft), Zeilen 329 bis 359 (touched(_:in:): ohne den Stick wird der Boden unter dem Finger sofort angelaufen und über Tiles hinweg verfolgt, während eine Berührung auf einem Sammler oder auf den Tiles des Kiosks zurückkehrt und auf das Anheben wartet), Zeilen 364 bis 380 (lifted(_:in:): eine Berührung, die weder lief noch lenkte, ist ein Tap; auf einem anderen Sammler setzt sietapped, auf den Tiles des Kiosks ruft sieonKioskauf, und sonst führt sierig.walk(to: tile)aus), Zeilen 31 und 32 (onKiosk, „The kiosk tapped: the town’s board.“ (Der Kiosk angetippt: das Brett der Stadt.)), Zeile 82 (stickKey,"world.stick"), das Test-Startargument-plazaFacingDemo(der.taskin den Zeilen 255 bis 270) undtellOnArrivalvonPlazaView, das-plazaTellliest (Zeilen 515 bis 522);KiradexUITests/KiradexUITests.swift, Zeilen 384 und 387, wo der Lauftest die Bühne an Bruchteilen ihres Rahmens antippt. ↩↩↩↩ -
Kiradex-Quellcode,
Kiradex/World/PlazaRig.swift, gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository):fit(viewSize:displayScale:tilesTall:fitsWhole:)in Zeile 432 (pixelScaledie abgerundete Pixelhöhe der Ansicht geteilt durchtilesTall × TileMap.tileSize, 20 × 16 = 320, Zeile 439;TileMap.tileSizeist 16 inTileMap.swiftZeile 60) undheadPoint(of:)in Zeile 479 (die Position der laufenden Figur plus die halbe Framehöhe des Sheets, plus 4, Zeilen 482 und 483). Die Datei änderte sich bis 12:42 erneut; beide Funktionen waren da unverändert. ↩↩ -
Kiradex-Quellcode, gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit
334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository):Kiradex/World/PlazaStage.swiftZeile 311 (.ignoresSafeArea()auf der Bühne, derenGeometryReader, Zeilen 121 bis 294, das Overlay der Sprechblasen enthält), und nirgends in der Datei ein Lesen der Einzüge des sicheren Bereichs;Kiradex/World/WorldHUD.swiftZeilen 26 und 27 (.statusBarHidden()und.persistentSystemOverlays(.hidden)aufWorldView, der Wurzel der Welt) und Zeilen 40 bis 42 (die Bedienelemente liegen „over its stage and inside the safe area, which on the Duo keeps it clear of the cameras and the side rail“ (über ihrer Bühne und im sicheren Bereich, was sie auf dem Duo von den Kameras und der Seitenschiene fernhält)); undKiradex/Views/Card/CardViewer.swiftZeilen 19 bis 24, wo einGeometryReaderaußerhalb der Bühne der Karteproxy.safeAreaInsetsanCardStageübergibt, das den sicheren Bereich ignoriert, sodass „the card rests inside the safe area, clear of the Duo’s outer camera and side rail“ (die Karte im sicheren Bereich ruht, frei von der äußeren Kamera und der Seitenschiene des Duo), mit denselben beiden Modifiern in den Zeilen 56 und 57. Eine Suche inKiradex/nachsafeAreaInsetsfand nur die Zeile inCardViewer. ↩↩↩↩↩ -
Blake Crosley, „Xcode 27.1 Beta: Your App in the iPhone Duo Simulator“, blakecrosley.com, 21. September 2026, aktualisiert am 2. Oktober 2026 (eine App im Simulator des iPhone Duo ausführen, äußeres und inneres Display; geschlossen, gegen das 27.1 SDK gelinkt, ein Fenster von 466 mal 678 Punkt, dessen Inhalt in einem Navigation Stack 382 mal 562 Punkt maß, mit Einzügen des sicheren Bereichs von 82 oben, 34 unten und 84 an der nachlaufenden Seite, der Schiene, in einer Messung mit einer Symbolleiste und einer Tableiste an dieser Kante und sichtbarer Statusleiste), https://blakecrosley.com/blog/xcode-27-1-beta-iphone-duo-simulator. ↩↩↩↩
-
Messung des Autors, 5. Oktober 2026:
measure_figure_width.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_figure_width.out, erneut ausgeführt um 12:36 Uhr pazifischer Zeit gegen Kiradex bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, Ausgabe unverändert. Eingaben, nur aus Kiradex gelesen:Kiradex/Resources/World/characters.json("cell": [32, 40], die Frames und Blickrichtungen),scripts/forge/rig.py(Zeile 53,CELL_W, CELL_H = 32, 40) und das Körper-Sheetfig-body.png(1.376 mal 160 Pixel, 43 Frames mal 4 Blickrichtungen). Im Standframeidle_aist die Figur in jeder Blickrichtung 30 Texel hoch, nach unten oder oben blickend an ihrer breitesten Reihe 16 breit und nach links oder rechts blickend 13. ↩↩↩ -
Messung des Autors, 5. Oktober 2026:
measure_ios27_iphones.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_ios27_iphones.out, erneut ausgeführt um 12:36 Uhr pazifischer Zeit, Ausgabe unverändert. Es liestxcrun simctl list runtimes -jfür die mit Xcode 27.0 auf dem Mac des Autors installierte Simulator-Runtime von iOS 27.0 (24A434) und diecapabilities.plistjedes iPhone-Gerätetyps (main-screen-width,main-screen-height,main-screen-scale): 33 iPhones, vom iPhone 12 mini und 13 mini (1.080 mal 2.340 Pixel bei 3×, 360 mal 780 Punkt) bis zum iPhone 16, 17 und 18 Pro Max (440 mal 956 Punkt), drei davon bei 2×, das iPhone SE (2. und 3. Generation, 375 mal 667 Punkt) und das iPhone 11 (414 mal 896). Das ist die Geräteliste des Simulators, nicht Apples Kompatibilitätsseite, die nicht abgerufen wurde. Außerdem aus der Projektdatei von Kiradex bei Commit334fbfe, nur gelesen:TARGETED_DEVICE_FAMILY = 1(iPhone) des App-Targets in beiden Konfigurationen (Zeilen 1559 und 1705 bei der Lesung um 12:28) undIPHONEOS_DEPLOYMENT_TARGET = 27.0in den beiden Konfigurationen des Projekts (Zeilen 1608 und 1670), das das App-Target nicht überschreibt. ↩↩↩↩↩↩↩ -
Messung des Autors, 5. Oktober 2026:
probe_line_start_glyphs.swiftim Belegordner des Autors zu diesem Beitrag, kompiliert mitswiftc -Ound ausgeführt unter macOS 27.0 (Build 26A428), nicht iOS, Ausgabeprobe_line_start_glyphs.out. Es liest die zehn Zeilenanfangsklassen von JLREQ 3.1.7 aus den Anhangstabellen der gespeicherten Spezifikation (83 Einträge: cl-02 16, cl-03 4, cl-04 6, cl-05 3, cl-06 2, cl-07 2, cl-09 6, cl-10 1, cl-11 40, cl-29 3), fragt Core Text, welche PixelMplus10 Regular abbildet (CTFontGetGlyphsForCharacters, kein Fallback): 54, wobei 〜 U+301C, ゠ U+30A0 und der Halbgeviertstrich aus cl-03, ⦆, 〙 und 〗 aus cl-02, ‼ ⁇ ⁈ ⁉ aus cl-04, 〻 aus cl-09 und 18 kleine Kana aus cl-11 (ゕ, ゖ und U+31F0 bis U+31FF) nicht abgebildet sind. Es zeichnet alle 7.223 Codepoints, die die Schrift abbildet, bei 10 Pixeln, ohne Kantenglättung und Schriftglättung, und gruppiert pixelgleiche Zellen: Von den 54 stimmt ‐ U+2010 mit U+2011 überein und : U+003A mit U+A789, und kein anderes hat einen Zwilling. Bei 50 Pixeln (m= 5), mit Kantenglättung und ohne Glättung, zeichnet ー U+30FC 200 Tintengerätepixel mit einem Haken am linken Ende und 一 U+4E00 250, nicht identisch, beide mit 0 Teilpixeln. Jedes druckbare ASCII-Zeichen hat einen Vorschub von 5 Schriftpixeln. Später am 5. Oktober erweitert, mit dem früheren Skript und der früheren Ausgabe daneben und jeder früheren Zeile der Ausgabe unverändert: die 24 Zeichen des Blocks Halfwidth and Fullwidth Forms, U+FF01 bis U+FFEF, deren Kompatibilitätsnormalisierung (NFKC) eines der aufgeführten Zeichen ist (! ) , . : ; ? ] } ⦆ 。 」 、 ・ ァ ィ ゥ ェ ォ ャ ュ ョ ッ ー), und ~ U+FF5E, vom Autor ergänzt: Die Schrift bildet 24 der 25 ab, alle außer ⦆ U+FF60, die vollbreiten 10 Pixel breit und die halbbreiten 5, und keine der 24 hat unter den Codepoints der Schrift einen pixelgleichen Zwilling, die Vergleichsmenge umfasst also 75 Zeichen: Die 54 Einträge enthalten 51 Zeichen, da ), 〕 und ] sowohl in cl-02 als auch in cl-29 stehen, und die 24 Formen ergeben 75 (die eigene letzte Zeile der Messung, 54 + 24 = 78, zählt Einträge). ↩↩↩↩ -
Messung des Autors, 15. Oktober 2026:
measure_cell_masks.pyim Belegordner des Autors zu diesem Beitrag, Ausgabemeasure_cell_masks.outund die Digest-Listecanon_cell_masks.txt, ausgeführt auf den für diesen Beitrag gespeicherten Dateien von pret (pokeemeraldgraphics/fonts, 17 Sheets, undgraphics/text_window, 21; pokecrystalgfx/frames, 10;gfx/font/font.pngvon pokecrystal und pokered). Jedes Sheet wird zu RGBA dekodiert; ein Pixel ist gesetzt, wo es vom oberen linken Pixel des Sheets abweicht; Zellen messen 8 mal 8 ab der oberen linken Ecke; leere und volle Zellen werden ausgelassen; der Digest einer Maske ist der SHA-256 ihrer 8 Reihenbytes, das linke Pixel das höchste Bit.japanese_normal.png, 128 mal 512 Pixel: 1.024 Zellen, 430 leer, 594 behalten, 478 eindeutig. Alle 50 Sheets: 7.746 Zellen behalten, 1.484 eindeutige Digests. ↩↩ -
Blake Crosley, „Pixel-Art People: Characters and a Creator on iPhone“, blakecrosley.com, 3. Oktober 2026, gelesen am 5. Oktober 2026: zur Figur der Builds 21 bis 33 „The cell is 32 by 32; the figure is 26 tall to the crown of the head, 27 with most hair (28 with buns, spikes or the puff), and about 14 wide at the shoulders“ (Die Zelle misst 32 mal 32; die Figur ist bis zum Scheitel 26 hoch, mit den meisten Frisuren 27 (28 mit Dutt, Stacheln oder dem Puff) und an den Schultern etwa 14 breit); im Update für Build 34 „The cell is 32 by 40 now, with eight rows of headroom and two under the feet, and the figure 30 pixels“ (Die Zelle misst jetzt 32 mal 40, mit acht Reihen Kopffreiheit und zwei unter den Füßen, und die Figur 30 Pixel); und die Kopf- und Handanker des Manifests für die Sprechblase und die 3D-Karte, „though both still take their place from the cell’s height for now“ (auch wenn beide ihren Platz vorerst noch aus der Höhe der Zelle beziehen), https://blakecrosley.com/blog/pixel-art-characters-on-iphone. ↩↩
-
Lesung des Kiradex-Arbeitsverzeichnisses bei Commit
fc9d4876(refs/heads/main) durch den Autor, 15. Oktober 2026 um 22:29 Uhr pazifischer Zeit:Kiradex/World/PlazaStage.swift(an diesem Tag um 17:13 geändert), Zeile 373 (.modifier(StageAccessibility(covered: covered, trace: stepTrace))), Zeile 520 (private struct StageAccessibility: ViewModifier), Zeilen 511 bis 513 (der Kommentar: Die Bühne ist ein Bedienungshilfe-Element, „The plaza“ mit dem letzten Schritt der Spielfigur als Wert, oder keines, solange ein Ort darübergelegt ist), Zeile 525 (content.accessibilityRepresentation {), Zeile 526 (if !covered {), Zeile 533 (.accessibilityLabel("The plaza")) und Zeile 534 (.accessibilityValue(trace)). Die übrigen Kiradex-Lesungen des Beitrags stammen vom 5. Oktober und sind datiert. ↩ -
Kiradex-Quellcode,
server/app/npcs.py, gelesen um 12:33 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfe(die Datei datiert vom 3. Oktober; privates Repository): die vier Sammler der Stadt ausDEFINITIONS(Zeilen 36 bis 58), Moss Keeper 1999, Prism Scout 2024, Comet Pocket 3030 und Dawn Sprout 4040, deren Zeilen Indizes inLINESsind; jeder sagt seine erste Zeile nach 8 bis 20 Sekunden (Zeile 77) und danach alle 20 bis 40 Sekunden eine (Zeile 108).server/app/main.pyZeile 231 sendet die Zeile eines Spielers an den ganzen Raum, den Spieler eingeschlossen (except_idvonbroadcastist nicht gesetzt;rooms.pyZeile 182), gelesen um 12:33. ↩↩ -
Kiradex-Quellcode,
KiradexUITests/KiradexUITests.swift, gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository); die Datei trug die Uhrzeit 10:32 und änderte sich während der Lesung nicht: Zeile 228 (dasme-handledes Tabs „Me“ enthält das Handle, zwei Wörter und eine Zahl),testTheCollectorFacesTheWayItWalksab Zeile 432 (liest den Wert der Bühne für jede Blickrichtung),testThePlazaKeepsTimeab Zeile 502 (liestplaza-statusund prüft sein Präfix, Zeile 509),testTheChimneysSmokeab Zeile 523 (mit-airProbegestartet, wartet aufvalue CONTAINS 'smoke 18 'der Bühne, Zeile 531),testVisitingARoomIsAVisit(Zeilen 469 bis 472) undtestYourRoomHasYourBinders(Zeilen 604 bis 607), die auf die ersten Worte vonroom-statuswarten,testTheShowHallHasEveryonesCards(Zeilen 490 bis 494), das aufhall-statuswartet,testTheTownHasCollectors(Zeilen 672 bis 676), das aufplaza-statusmit einer Zahl von fünf oder mehr „here“ wartet, undtestThePlazaHasCompanyab Zeile 689 (übersprungen, sofern nichtKIRADEX_PLAZA=1, der Server, und laut seiner Meldung beim Überspringen braucht er auch einen Mitspieler, Zeilen 690 und 691; wartet aufplaza-statusfür die Zahl, wählt „Hi!“ im „Say“-Menü und wartet 5 Sekunden auf die SprechblaseSaid: Hi!, Zeile 714). ↩↩↩↩ -
Kiradex-Quellcode,
server/requirements.txt(fastapi,uvicorn[standard],websockets,httpxundpytest, keine Schriftbibliothek) undserver/tests/(test_rooms.py), gelesen um 12:28 Uhr pazifischer Zeit am 5. Oktober 2026, bei Commit334fbfemit den nicht eingecheckten Änderungen dieses Tages, aus einem Arbeitsverzeichnis, das an diesem Tag bearbeitet wurde (privates Repository). ↩ -
Blake Crosley, „Pixel-Art Routes: Map Connections and Districts on iPhone“, blakecrosley.com, 5. Oktober 2026, Abschnitt 7, Prüfung 13 (eine Sperrliste im Repository, mit ihrem Test, die jeder Gebietsname, jedes Schild und jeder String passieren muss), https://blakecrosley.com/blog/pixel-art-world-beyond-the-plaza. ↩