Compare commits

...

29 Commits

Author SHA1 Message Date
Homer b4359c0458 Documentation out, and a version that says it is finished
The working notes, the roadmap, the glossary and the review notes are on the
wiki; README points there. assets/Translation.xml stays -- it is the mod.

1.0.0: both the base game and Echoes of the Eye are translated, which was the
whole goal. manifest.json said 0.1.0 because nothing had ever changed it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 18:36:59 +02:00
Jaroslav Beneš 4dabcaa13c Strip the font bundle to 59 KB and replace the polling sweep with a hook
The bundle was built by rewriting the Korean translation mod's asset bundle, so
it still carried everything that mod needed and we did not: three unused font
assets, their materials and textures, and a .resS stream holding two 2048x2048
atlases. Deleted those, dropped the stream, and rewrote m_Container and
m_PreloadTable to reference only the four surviving objects. 862 KB -> 59 KB,
verified by reloading: the embedded font still round-trips as Cabin with full
Slovak coverage and the Gill Sans MT metrics.

The 2s sweep existed to catch labels whose font the game reassigns without any
text change, which happens on a language switch. A postfix on the Text.font
setter catches exactly that, at the moment it happens rather than up to two
seconds later, and costs nothing when idle. Re-entry is safe: our own assignment
fires the hook once, which finds the state already correct and returns.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 21:46:47 +02:00
Jaroslav Beneš 2268334c30 Draw menu carons with the game's own typeface, per font rather than per label
The previous commit claimed this was fixed; it was not. It hooked
UIStyleManager.GetMenuFont, GetTranslatorFont, GetShipLogFont and
GetShipLogCardFont — all four of which are dead code with no callers anywhere in
Assembly-CSharp. Fonts are assigned straight onto the Text components in the
scene data, so nothing the mod did was ever consulted.

Three further things were wrong and are fixed here:

- The language check reflected into the Localization Utility for TryGetLanguage,
  which the installed version does not have, so it could only ever fail. It now
  uses the utility's own definition instead: custom languages are numbered past
  Language.TOTAL. No reflection, nothing to fail silently.
- The substitution was decided per label, from whether that label's own string
  needed a glyph, which left menus mixing two typefaces line by line. It is now
  decided per font: a face that cannot draw Slovak is replaced everywhere it is
  used. Faces that can — Futura PT for dialogue, Space Mono for the translator —
  are still never touched.
- The menu font was assumed to be Gill Sans MT. Logging the fonts actually in
  use showed the menus are Adobe - SerifGothicStd, which had been listed as a
  stylised face to leave alone. Gill Sans is the HUD prompts.

The replacement now prefers the game's own dynamic cut of the same typeface
(Adobe - SerifGothicStd_Dynamic and friends), matched by name prefix so bold
variants resolve too, which keeps the menu looking like vanilla. Bundled Cabin
is the fallback where the game ships no dynamic sibling, and the new
preferGameTypeface setting forces Cabin everywhere.

Hooks are Text.OnEnable, the Text.text setter, TextTranslation.SetLanguage and
scene load, plus a 2s sweep for menus built lazily after all of those.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 21:39:19 +02:00
Jaroslav Beneš 645b8b070b Render Slovak carons in menus and HUD without disturbing the other text
The stock menu font (Gill Sans MT Menu) is a static 243-glyph atlas with no
Latin Extended-A, so "Pokračovať" rendered as "Pokra ova" and "Podrž" as
"Podr". Dialogue, the Nomai translator and the ship log were always fine —
they use Futura PT (663) and Space Mono (612), both of which cover Slovak.

Registering a language font via AddLanguageFont fixes the menus but flips
TextTranslation.IsLanguageLatin() to false, and the game uses that flag to
decide whether dialogue, the translator and the ship log keep their own fonts
or fall back to the language font. So the blanket fix dragged all three onto
the wrong font, oversized and clipping.

Instead: register no language font at all, and postfix only the font getters
(UIStyleManager, PromptManager, GameOverController). Each result goes through
SlovakFont.Fix, which probes the font with Font.HasCharacter and returns it
untouched unless it genuinely cannot draw Slovak — so nothing that already
renders correctly is ever replaced, and the patches are inert in every other
language.

The substitute is Cabin (SIL OFL 1.1), a humanist sans in the Gill Sans
lineage, shipped as a dynamic font with its vertical metrics rewritten to Gill
Sans MT's exact ratios so line height matches and text does not clip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:02:56 +02:00
Jaroslav Beneš adb306604c Fix untranslated strings found by diffing against the game's own table
The English template from the Localization Utility repo is out of date versus
the shipped game, so some strings never matched and silently fell back to
English. Extracted the game's own TranslationTable_XML from resources.assets
and diffed all three tables against ours.

Left in English (now translated):
- the Vessel district signs (Stepping Stone / Anglerfish Overlook / Eye Shrine),
  which had also lost their <color=orange> markup
- "Black Hole Forge controls"
- Marl's "Sigh... I suppose it's my duty as mayor" (lost its <Color=#808080ff>)
- Gneiss's "maybe someone needs a new porch"
- "High Energy Lab Trailhead" had lost its colour markup

Keys the game has that we lacked (17 total):
- ship log "...a conscious observer..." — the template misspells it "concious"
- 6 UI strings: Invert Look (Horizontal) options and their tooltips
- two Sun Station lines where the template writes <pause>, the game <Pause>
- the divergence-meter easter egg and the ASCII-art loading screens

Both spellings are shipped where the template and the game disagree, so either
build matches. Audit now reports 0 missing keys and 0 unintentional English
leaks across 2434 dialogue + 484 ship log + 820 UI entries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:02:42 +02:00
Jaroslav Beneš 2e4d074bfc Review fixes: reword flags, gender cross-check vs Czech mod, catch 12 more leaks
- Reword per review: "an eye or four" -> Maj oko, aj štyri; fishing rhyme 1567
  -> ...návnadička (keeps rhyme + "bait is wrong").
- Gender: cross-checked every gendered self-reference against shippy/
  outer-wilds-czech. Only 3 disagreements file-wide -> Arkose (feminine),
  Porphy (feminine), and the hide-and-seek kid at 1627 (feminine) corrected;
  Filix kept feminine (EN "her note" beats Czech's masculine). All other
  Hearthians confirmed masculine.
- Definitive leak detection: quote-normalized suffix-of-key test caught 12 more
  untranslated values the heuristics missed (curly/straight-quote drift) -
  duplicate Eye-shrine walls (1167-1170), Nomai locator, traveler arrival,
  hide-and-seek + ghost-matter kid lines. Now 0 English leaks in the flat list.
- Consistency: "The Good Stuff" standardized to Tá Dobrota.
- glossary.md + review-notes.md updated with the gender findings. Build OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 21:05:23 +02:00
Jaroslav Beneš 025db00c6a Translate dialogue batches 19-22: finish the flat list (villagers, Chert/Esker, signs, stragglers)
Completes the machine-assisted first pass of the entire flat dialogue list,
produced in parallel (three translator subagents each emitting a JSON of
translations, applied race-free in the main thread) plus a large main-thread
block:

- Batch 19 - Hearthian village kids/villagers (271): Marl, Tephra, Galena,
  Rutile, Tuff, Spinel, Arkose, Gneiss, Porphy, Mica, model-rocket kid,
  hide-and-seek, ghost-matter kids. Player as mláďa.
- Batch 20 - Chert + Esker + Feldspar's jellyfish journal + Gabbro extras
  (359): Chert the astronomer's supernova breakdown, Esker's Mesačná základňa
  on the Skalka, Ember-Twin research signs, Gneiss the instrument-maker.
- Batch 21 - Giant's Deep signs, Signalscope-kid endgame, credits/epitaph
  signs (backer names kept), museum Nomai-writing signs. ASCII-art left as art.
- Batch 22 - straggler sweep (22): lines the suffix-of-key detector missed due
  to curly/straight-quote drift, found via an English-word heuristic (Gabbro
  bright-flash variants, sap-wine labels, ghost-matter Signáloskop game, ATP
  masks readout at 1964, Tektite's scout note).

Consistency: Hollow's Lantern -> Lampáš (glossary note added), ghost matter ->
prízračná hmota, Hanging City -> Visuté mesto. Whole-file English-leak scan: 0
across flat list, ship log, and UI. dotnet build -c Release succeeds and stages
the loadable mod folder. The entire Translation.xml first pass is now complete;
only the Slovak human review pass remains.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 19:20:46 +02:00
Jaroslav Beneš 92f964920a Translate dialogue batch 18: the "two of you" duplicate conversation
The 125-line conversation between the two copies of the player created by the
black-hole/white-hole jump inside the Ash Twin Project: confused-memory banter,
the dating jokes (Gossan/Slate), the "figment of my imagination" bit, the "we
are the Feldspar of weird time stuff" line, the panic-scream sequence, and the
post-intro bragging menu. Both speakers are the player -> masculine, mutual ty.
The 15 pure-scream onomatopoeia lines left verbatim as language-neutral.
<i>/<b>/<Pause/>/<pause> markup and \\n\\n preserved; XML re-verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 18:44:26 +02:00
Jaroslav Beneš 58c2e76603 Translate dialogue batch 17: Gabbro (travelers)
Gabbro's full Giant's Deep campsite conversation (204 lines): the laid-back
"time buddy" surfer-philosopher — time-loop musings, memory statues, Statue
Island (Ostrov sôch), the Orbital Probe Cannon, his quantum poem/art, the
meditation mini-lesson, and the deep-space-satellite ("Ol' Spacey" ->
Vesmírko) inspection log. Masculine voice; player as ty; Hornfels masculine
per existing SK. <i>/<Pause> markup and repeated menu blocks preserved.

Also corrects PLAN.md's scope estimate: a suffix-of-key scan shows ~1090
dialogue lines still untranslated (ID-prefixed keys hid them from the earlier
key==value check), not the ~730 previously assumed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 18:39:20 +02:00
Jaroslav Beneš 1f8d003f7b Translate dialogue batch 16: Nomai shrines + system text & location signs
Sweep of the player-facing/system and Nomai-shrine text interleaved through
the flat dialogue list that earlier speaker-based batches skipped (98 lines):
Eye Shrine + Quantum Shrine signal-philosophy walls, Tower of Quantum
Knowledge trial/pilgrimage lines, Brittle Hollow location/direction signs,
Escape Pod 2/3 flightlogs, cannon/probe/Sun-tower system readouts, and
scattered UI labels. Glossary terms applied; template tokens, markup, \\n
direction markers and multiline whitespace preserved; XML re-verified.

The entire flat dialogue list is now translated apart from the 22 character
names (kept in English) and 2 language-neutral ASCII-art easter eggs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 18:28:24 +02:00
Jaroslav Beneš 5660fabb1a Translate dialogue batch 15: Riebeck (travelers)
69 lines: Riebeck, the anxious, stammering archaeologist camped on
Brittle Hollow -- passionate about the Nomai ruins (dreamed of seeing
the Hanging City since a hatchling) but terrified of space and of the
"you-know-what" (the black hole below). His reactions to each Nomai
discovery, building to the giddy panic of "you talked to a LIVING Nomai".

Masculine (genderless default); timid ehm/uf voice; Hearthian ->
Kozubčan; "Stars above" -> Hviezdy nad nami; "on my own four eyes"
kept. Preserved <size=20> shrinking-text asides and
<Pause>/<Pause />/<Pause/>/<i> markup.

Scoped to Riebeck's character dialogue; the interleaved Brittle Hollow
HUD labels, museum star/skeleton exhibits, and system logs are deferred.

Verified: XML well-formed; keys identical; markup/token parity; ship log/
UI/rest byte-unchanged; mod builds. (1753 "Riebeck" label kept.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 15:52:04 +02:00
Jaroslav Beneš 3bc1759c0e Translate dialogue batch 14: Feldspar (travelers)
Start the travelers. 120 lines: Feldspar, the boastful "greatest pilot
in Hearthian history," camped in Dark Bramble after crashing -- his
(reluctantly admitted) crash story, the anglerfish-skeleton camp, and
his theory that space expands inside the Dark Bramble seeds. Warm,
folksy, cocky voice.

Masculine (genderless default); heavy use of mláďa (Hatchling);
Hearthian -> Kozubčan; "Stars above" -> Hviezdy nad nami; kept his vanity
("my very handsome head"). Preserved <Pause>/<Pause=3>/<color=grey> and
<i> markup.

Verified: XML well-formed; keys identical; markup/token parity; ship log/
UI/rest byte-unchanged; mod builds. (680 "Feldspar" and 753 "Hm..." kept.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 15:24:48 +02:00
Jaroslav Beneš 83f9e5519f Translate dialogue batch 13: Hal + Gossan + Hornfels (villagers)
204 lines finishing launch day on Timber Hearth: Hal (translator
co-inventor, gushing over the new Nomai statue), Gossan (the tough-but-
caring flight coach, zero-g training on the "satellite"), and Hornfels
(curator/ground control -- launch codes, where the travelers are,
Feldspar's story, and the redshift "Observations" exhibit deducing the
expanding universe).

All genderless Hearthians -> masculine default; travelers masculine.
"Stars above" -> Hviezdy nad nami; "hatchlings" -> mláďatá; translator
tool -> prekladač. Preserved <Pause>/<Pause/>/<color=grey>/<color=orange>
markup and the \n\n signature in 1419.

Verified: XML well-formed; keys identical; markup/token parity; ship log/
UI/rest byte-unchanged; mod builds. (3 name labels intentionally kept.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 15:04:01 +02:00
Jaroslav Beneš 50befc68f2 Translate dialogue batch 12: Museum + Slate (Hearthian villagers)
Start the Hearthian villager category. 100 lines: the museum signs and
exhibits (radio tower, deep space satellite, museum expansion) and Slate
the shipbuilder's entire launch-day conversation -- the ship, launch
codes, ship-log destination markers, marshmallows, and Slate's gruff,
sarcastic jabs.

First use of "mláďa" (Hatchling, 673). Player addressed informally (ty);
"Stars above" -> "Hviezdy nad nami"; Hearthian names kept (Slate,
Hornfels, Gossan, Hal, Mica). Preserved <i> emphases and \n / \n\n tokens.

Verified: XML well-formed; keys identical; markup/token parity; ship log/
UI/rest byte-unchanged; mod builds. (588 "Slate" intentionally unchanged.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 14:52:59 +02:00
Jaroslav Beneš a1bef582f8 Translate final Nomai batch — all Nomai dialogue complete (Phase 5)
113 Nomai lines: warp-window details, mining-sites/native-life
(Coleus/Cycad/Oeno), the new-Vessel debate (Ilex), the memory-statue
philosophy (Phlox/Daz/Cassava), the probe-cannon-origin / Eye-search
debate (Avens/Cassava/Plume), Sun Station "mission" humor (Idaea), the
anglerfish-fossil study (Melorae/Coleus), and scroll-wall leftovers.

Privet revealed feminine ("her brother") -- corrected her one masculine
line in batch 3. Kept the Nomai anatomical jokes ("pulling my locomotive
limb", "going gelatinous", "a-core-dingly" pun) and the neutron-star
density gag. Every speaker-prefixed Nomai line is now translated.

Verified: XML well-formed; keys identical; markup parity on all 114
changed values; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 14:34:05 +02:00
Jaroslav Beneš fdd0a7c6a7 Translate dialogue batch 10: Bells scrolls + kids' game + Escall myth
87 Nomai lines: the Tower of Quantum Knowledge pilgrimage scrolls (Bells),
the Fossil Fish Cave anglerfish blindfold game and short "who was it"
answers (Laevi, Taget, Ilex, Lami), and the ancient "Disappearance of
Escall" myth told among distant clans + the Escape Pod 3 / Secca-Din
thread (Canna, Bromi, Clem, Hyssop, Neem, Escall, Filix, Din).

Bells masc; Taget masc; Filix feminine (same crew member). "Aunt Pye"
reconfirms Pye feminine. Distant place names translated and flagged for
review (Gloaming Galaxy -> Súmračná galaxia, Blackrock -> Čierna skala,
Bright Spark -> Jasná iskra).

Verified: XML well-formed; keys identical; only these 87 values changed;
markup parity; ship log/UI/rest byte-unchanged; no stray chars; builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 14:23:29 +02:00
Jaroslav Beneš 28f85f5809 Translate dialogue batch 9: Brittle Hollow clan saga (Phase 5)
94 Nomai lines: the Escape Pod 1 clan's story on Brittle Hollow -- the
crash, the volcanic-moon danger, the quantum-grove wandering trees and
shard, the Eye-signal locator, the migration to the northern glacier,
and the grief for lost loved ones (Plume, Thatch, Filix, Lami, Annona,
Rhus, Ilex, Spire, Coleus, Cassava, Kousa).

Gender cues resolved: Filix feminine ("her note"), Melorae feminine
("Aunt Melorae") -- retroactively corrected batch 7's 7 Melorae lines
from masculine to feminine. Recorded in glossary. Poems (Ilex's
gravity-hole rhyme) flagged for review.

Verified: XML well-formed; keys identical; markup parity on all changed
values; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:58:29 +02:00
Jaroslav Beneš 163f4479a2 Translate dialogue batch 8: Interloper shuttle + scroll-wall (Phase 5)
25 Interloper lines: the comet crew (Pye, Poke, Clary) descending into
the ice, finding the spherical stone casing of volatile exotic/ghost
matter under immense pressure, and Pye ordering Poke to flee and warn
the clan. All three feminine (Poke & Clary are sisters). Plus 18
leftover White Hole Station / warp-tower scroll-wall lines that finish
the batch-4 conversations (Clary/Poke/Root/Yarrow, incl. the
Clary-Yarrow romance and Clary's "core is finished / she'll be finished"
pun). Uses renamed Kováreň čiernych dier.

Verified: XML well-formed; keys identical; only these 43 values changed;
markup parity; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:48:56 +02:00
Jaroslav Beneš 92fcd08c8a Translate dialogue batch 7: Quantum caves (Phase 5)
48 Nomai lines: the quantum shard, the Quantum Moon locator, the
wandering-rock / quantum-travel experiments, Coleus's disappearance and
the search for him, and the Ember Twin shelter-path directions (Coleus,
Melorae, Bur, Annona, Thatch, Plume).

Coleus & Melorae masculine (no English gender cue). Kept the
pre-discovery moon names (putujúci / prízračný mesiac), the potulný
kameň / Jaskyňa na dne jazera glossary terms, and Melorae's "my
sedimentary friend" geologist humor. Picked up the deferred line 1224.

Verified: XML well-formed; keys identical; only these 48 values changed;
markup parity; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:43:29 +02:00
Jaroslav Beneš 73008ca1d9 Translate dialogue batch 6: High Energy Lab (Phase 5)
42 Nomai lines: the negative-time-interval experiments (Pye & Ramie),
the white/black-hole-core setup mimicking the White Hole Station, the
22-minute-interval hypothesis and its exponential energy cost, plus the
High Energy Lab / Sunless City labels and HUD distance markers.

Pye & Ramie feminine, Conoy/Root/Bur masculine. Kept the "gas/aeriform"
state-of-matter puns (flagged for review) and Conoy's "lose his own
head" Nomai joke. Preserved <i> emphases and the \n in the distance
markers (1884-1892). Deferred line 1224 to the Coleus/Melorae batch.

Verified: XML well-formed; keys identical; only these 42 values changed;
markup/token parity; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:34:23 +02:00
Jaroslav Beneš 80e2b55887 Translate dialogue batch 5: Sun Station + memory statues (Phase 5)
61 Nomai lines: the Sun Station build debate (Idaea, Pye, Ramie, Poke),
Pye's supernova/"gas" humor, the firing/activation orders, the failure
aftermath (Yarrow, Pye), and the memory statues + masks (Phlox, Daz,
Yarrow, Ramie, Oeno, Root). Idaea masculine. Preserved the countdown
tokens in 1304 (<RemainingMinutes>, <MinutesToRedGiant>, ...) plus \n,
and <TimeMinutes>/<TimeSeconds> in 1962; kept the "third eye" Nomai
detail and the gas/supernova jokes.

Verified: XML well-formed; keys identical; only these 61 values changed;
markup/token parity; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:28:08 +02:00
Jaroslav Beneš 8c06b2a5f2 Dialogue batch 4 (Ash Twin warp mechanism) + rename Black Hole Forge
Batch 4 — 53 Nomai lines: warp-tower alignment lore, White Hole Station
tutorial, tower designs, ore/shell construction, and the warp-core-source
debate (Yarrow, Clary, Poke, Root, Phlox, Oeno, Cycad, Annona, Ramie,
Ilex). Pye feminine, Plume masculine. Preserved <MinutesSinceRedGiant>/
<SecondsSinceRedGiant> tokens and \n in entry 359; kept Poke's "cervical
spine" Nomai joke. "Twilight Twin" rendered provisionally as Súmračné
dvojča (flagged for review).

Terminology change (user): Black Hole Forge -> Kováreň čiernych dier
(was Zlieváreň čiernej diery), applied file-wide — 15 occurrences across
ship log + dialogue; real "čiernej diery" (black holes) left untouched.

Verified: XML well-formed; all keys identical; markup/token parity;
UI/ship-log byte-consistent except the forge rename; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:21:17 +02:00
Jaroslav Beneš 7a49f50c65 Translate dialogue batch 3: Orbital Probe Cannon (Phase 5)
50 Nomai lines: Construction Yard cyclones (Conoy, Spire, Cassava),
building and firing the cannon (Cassava, Daz, Mallow, Privet, Avens,
Yarrow), the "search for the Eye -> send a probe" decision, and the
cannon's damage-report / launch-log system text. Excluded the Hearthian
cyclone/island dialogue (belongs to the travelers batch).

Avens masculine, Ramie feminine (recorded in glossary). Preserved
<TimeMinutes>/<TimeSeconds> tokens, the hugging color tag in 1293, and
the "on the other appendage" Nomai hand-joke. Glossary terms applied
(Orbitálne delo sondy, Stavenisko, Modul sledovania sondy, ...).

Verified: XML well-formed; keys identical; only these 50 values changed;
markup/token parity on all; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:11:25 +02:00
Jaroslav Beneš 8597d10e1b Translate dialogue batch 2: Vessel / warp-core debate (Phase 5)
29 lines: the Nomai clan debating how to obtain the advanced warp core
for the Ash Twin Project (Oeno, Clary, Poke, Idaea, Avens, Cassava, Spire,
Mitis), Poke's personal reflections, and the Vessel's escape-pod launch /
crash computer log. Poke & Clary feminine, Annona masculine (recorded in
glossary). Glossary terms applied (Projekt Dvojčaťa Popolu, Plavidlo,
Zlieváreň čiernej diery, Únikový modul); markup, speaker prefixes, and
entry 42's internal newline preserved.

Verified: XML well-formed; keys identical; only these 29 values changed;
markup tokens intact; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 13:04:21 +02:00
Jaroslav Beneš d6ca4e1415 Translate dialogue batch 1: Solanum (Phase 5)
Start the dialogue category, batched by content type (the flat <entry>
list is asset-ID ordered, not planet-ordered, so true per-planet batches
aren't in the data — grouping Nomai lore by speaker instead).

Batch 1 = Solanum, all 70 lines: the Quantum Moon pilgrim's astronomy-
museum wall text, Tower of Quantum Knowledge / Quantum Shrine scrolls,
and Eye-of-the-universe philosophy. Feminine voice (locked); player
addressed as ty. Preserved <color=…>/<i> markup, speaker prefix, and
per-entry wrapping whitespace; Nomai names kept (Conoy, Bells).

Verified: XML well-formed; keys identical; only these 70 values changed;
markup tokens intact; ship log/UI/rest byte-unchanged; mod builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 12:59:00 +02:00
Jaroslav Beneš 5633d68a91 Translate ship log to Slovak (Phase 5, first pass)
Machine-assisted first pass over the entire <table_shipLog> section — all
483 entries (115 location/entry names + 368 rumor/fact paragraphs).
String <key> lookups left untouched; plain text, no markup.

Locked decisions applied:
- Narrator voice = masculine (genderless protagonist); Solanum feminine,
  Coleus masculine, other "they" travelers masculine by default.
- New place names: Hanging City -> Visuté mesto, Sunless City ->
  Bezslnečné mesto, Orbital Probe Cannon -> Orbitálne delo sondy,
  Cinder Isles -> Vyhorené ostrovy, plus High Energy Lab, White Hole
  Station, Gravity Cannon, the Quantum towers/shrine, anglerfish ->
  udicovka, etc. (recorded in docs/glossary.md §3, §5b).

XML re-verified well-formed; keys identical; UI/rest byte-unchanged;
no English place names remain in values; mod still builds.

Still needs the Slovak review pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 12:40:09 +02:00
Jaroslav Beneš 3b18c156f1 Lock place-name glossary decisions & re-pass UI (Phase 4/5)
Reviewed the place names "risky" — translate them all:
- Timber Hearth -> Drevený kozub (Hearthian -> Kozubčan/Kozubčania)
- The Attlerock -> Skalka ("a little rock" pun)
- Ash Twin -> Dvojča Popolu (Ash Twin Project -> Projekt Dvojčaťa Popolu)
- Ember Twin -> Dvojča Uhlíka; Brittle Hollow -> Krehká dutina;
  Hollow's Lantern -> Lampáš; Black Hole Forge -> Zlieváreň čiernej diery
- Owlks -> Soví ľudia; Nomai -> indeclinable
- Signalscope -> Signáloskop; Scout -> Skaut; Scout Launcher -> Odpaľovač Skauta

Applied a consistency re-pass across the already-translated <table_ui>
section (45 entries) so the UI matches the locked terms. XML re-verified
well-formed; no stale terms remain; mod still builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 11:18:49 +02:00
Jaroslav Beneš 3344dabf67 Translate UI/menus category to Slovak (Phase 5, first pass)
Machine-assisted first pass over the entire <table_ui> section — all 814
UI/menu strings translated to Slovak. Integer <key> IDs left untouched;
preserved \n newline markers, <!> input-prompt tokens, <Profile Name>
placeholder, and color/italic markup verbatim. Casing mirrors the source
(ALL-CAPS button labels stay caps). Uses the glossary's tone (informal ty)
and term renderings. XML re-verified well-formed; mod still builds.

Still needs the Slovak review pass, especially the place-name renderings
flagged in docs/glossary.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 10:32:45 +02:00
Jaroslav Beneš 854eee4275 Add OWML mod skeleton and import English translation template
Phase 2 (mod skeleton) + Phase 3 (import English source):

- manifest.json / SlovakTranslation.cs / ILocalizationAPI.cs registering
  "Slovenčina" via xen.LocalizationUtility (Interplanetary Polyglot).
- SlovakTranslation.csproj / .sln building net48 against the OWML and
  OuterWildsGameLibs NuGet packages — no game install needed to compile.
- assets/Translation.xml: English source template (896 KB, 2424 entries,
  keys == values) to be translated into Slovak.
- Project docs (README/PLAN/CLAUDE) and .gitignore.

Build verified: dotnet build -c Release stages a loadable mod folder.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 10:12:10 +02:00
13 changed files with 16972 additions and 1 deletions
+11
View File
@@ -0,0 +1,11 @@
# Build output
bin/
obj/
# User-specific project files
*.user
# IDE
.vs/
.vscode/
.idea/
+32
View File
@@ -0,0 +1,32 @@
# Changelog
Kept as the work happens, not assembled at release time. Format is
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
[SemVer](https://semver.org/spec/v2.0.0.html).
## Unreleased
## 1.0.0 — 2026-08-08
The first tagged version: *Outer Wilds* and *Echoes of the Eye* are translated,
which is what this mod set out to do.
### Added
- Slovak localization of *Outer Wilds* and *Echoes of the Eye*, as an OWML mod
built on `xen.LocalizationUtility`.
- A fixed glossary of proper nouns and recurring terms, so names stay consistent
across the whole script.
### Changed
- The documentation left the repository. The working notes, the phase roadmap,
the glossary and the in-game review notes are now the
[wiki](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki),
and the history was rewritten in the same pass so they are not present at any
commit. `assets/Translation.xml` stays here — it ships with the mod.
### Note on history
Any clone taken before 2026-08-08 has a different history and should be
discarded rather than merged.
+42
View File
@@ -0,0 +1,42 @@
using OWML.ModHelper;
using System;
using System.Collections.Generic;
using UnityEngine;
// Interface copied from xen-42's Localization Utility (MIT), so this mod can
// resolve the utility's API through OWML's TryGetModApi<T>. Keep in sync with
// https://github.com/xen-42/outer-wilds-localization-utility.
namespace SlovakTranslation
{
public interface ILocalizationAPI
{
#region Add new language
void RegisterLanguage(ModBehaviour mod, string languageName, string translationPath);
void RegisterLanguage(ModBehaviour mod, string languageName, string translationPath, string languageToReplace);
void AddLanguageFont(ModBehaviour mod, string languageName, string assetBundlePath, string fontPath, out Font font);
void AddLanguageFixer(string languageName, Func<string, string> fixer);
void SetLanguageDefaultFontSpacing(string languageName, float defaultFontSpacing);
void SetLanguageFontSizeModifier(string languageName, float fontSizeModifier);
#endregion
#region Add translations to new/existing languages
void AddTranslation(ModBehaviour mod, string languageName, string translationPath);
void AddTranslation(string languageName, KeyValuePair<string, string>[] regularEntries, KeyValuePair<string, string>[] shipLogEntries, KeyValuePair<int, string>[] uiEntries);
void AddRegularTranslation(string languageName, string key, string value);
void AddRegularTranslation(string languageName, string commonKeyPrefix, params string[] entries);
void AddRegularTranslation(string languageName, params KeyValuePair<string, string>[] entries);
void AddShiplogTranslation(string languageName, string key, string value);
void AddShiplogTranslation(string languageName, string commonKeyPrefix, params string[] entries);
void AddShiplogTranslation(string languageName, params KeyValuePair<string, string>[] entries);
void AddUITranslation(string languageName, int key, string value);
void AddUITranslation(string languageName, params KeyValuePair<int, string>[] entries);
#endregion
#region obsolete
[Obsolete] void AddLanguageFont(ModBehaviour mod, string languageName, string assetBundlePath, string fontPath);
#endregion
}
}
+78 -1
View File
@@ -1,2 +1,79 @@
# Outer-Wilds-SK-Translation-Mod # Outer Wilds — Slovenský preklad / Slovak Translation Mod
> **Neoficiálny slovenský preklad hry Outer Wilds** (základná hra + rozšírenie
> *Echoes of the Eye*). Pridáva do hry jazyk **Slovenčina**.
>
> *An unofficial Slovak (slovenčina) translation mod for Outer Wilds, covering
> the base game and the Echoes of the Eye DLC.*
**Stav / Status:** 🚧 **Work in progress** — the mod scaffold and translation are
being built. See the [Roadmap](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki/Roadmap).
Outer Wilds officially ships in 12 languages; Slovak is not one of them. This mod
adds it as a new selectable language using the community localization framework —
no changes to the game's own files are required.
---
## How it works
The mod is a small [OWML](https://github.com/ow-mods/owml) mod that registers a
new language through **[Interplanetary Polyglot / Localization Utility](https://outerwildsmods.com/mods/interplanetarypolyglot/)**
(`xen.LocalizationUtility`). All translated text lives in a single
`assets/Translation.xml`; the utility swaps the game's strings for the Slovak ones
at runtime.
## Installation
1. Install the **[Outer Wilds Mod Manager](https://outerwildsmods.com/mod-manager/)**.
2. Install this mod through the Mod Manager. Its dependency **Interplanetary
Polyglot** (`xen.LocalizationUtility`) will be pulled in automatically.
3. Launch the game via the Mod Manager.
4. In **Settings → Language**, choose **Slovenčina**.
- Tip: the optional [Language Swap](https://outerwildsmods.com/mods/languageswap/)
mod lets you switch language in-game with `Ctrl+L`.
> Until the first release is published, the mod is not yet in the Mod Manager
> database — see the [Roadmap](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki/Roadmap) for how to build it from source.
## Contributing / Prispievanie
Translation fixes are very welcome — the goal is natural, consistent Slovak.
- **Report** mistranslations or awkward phrasing as an issue.
- **Edit** only the `<value>` of each entry in `assets/Translation.xml`.
**Never change the `<key>`** — it is the English identifier the game matches on.
- Preserve all inline formatting exactly, e.g. `&lt;color=orange&gt;…&lt;/color&gt;`,
`&lt;i&gt;`, and speaker prefixes like `POKE:`.
- Follow the terminology in the [Glossary](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki/Glossary) so names (Nomai, the Eye, Ash Twin
Project, …) stay consistent across the whole game.
See the [Working notes](https://git.houmeres.sk/Houmeres/Outer-Wilds-SK-Translation-Mod/wiki/Working-notes) for the full conventions and repo layout.
## License & disclaimer
The **original mod code and the Slovak translation** in this repository are
released under the [MIT License](LICENSE).
The bundled fallback font in `assets/slovakfont` is
**[Cabin](https://github.com/impallari/Cabin)** by the Cabin Project Authors, used
under the **SIL Open Font License 1.1** (see
[`assets/Cabin-OFL.txt`](assets/Cabin-OFL.txt)). The game's own menu and HUD fonts
were never baked with Slovak caron glyphs, so those labels are redrawn with a font
that has them — preferably one of the game's own dynamic fonts, and Cabin only where
it ships none. See [`SlovakFont.cs`](SlovakFont.cs), and the `preferGameTypeface`
setting if you would rather have Cabin everywhere.
This is an **unofficial** fan project. It is **not affiliated with, approved by, or
endorsed by Mobius Digital or Annapurna Interactive.** *Outer Wilds*, its story,
dialogue, characters, and other assets are **© Mobius Digital / Annapurna
Interactive**; the underlying game text remains their property and is used here
under **Mobius Digital's Fan Content Policy**. The MIT license covers only this
project's own contributions, not the source material.
## Credits
- **Mobius Digital / Annapurna Interactive** — *Outer Wilds*.
- **[xen-42](https://github.com/xen-42)** — the Localization Utility /
Interplanetary Polyglot framework this mod is built on.
- The Outer Wilds modding community.
+296
View File
@@ -0,0 +1,296 @@
using HarmonyLib;
using OWML.Common;
using OWML.ModHelper;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace SlovakTranslation
{
/// <summary>
/// Fixes the missing Slovak caron glyphs (č ď ĺ ľ ň ŕ ť ž) in the menus and HUD.
///
/// Outer Wilds renders Latin languages with a handful of *static* font atlases,
/// and only some of them were baked with Latin Extended-A:
///
/// Adobe - SerifGothicStd (+ExtraBold) menus 253 glyphs — no carons
/// Gill Sans MT (+Menu, Bold) HUD prompts 243 glyphs — no carons
/// ParaType - Futura PT Medium dialogue 663 glyphs — complete
/// SpaceMono-Regular translator 612 glyphs — complete
///
/// That is why dialogue and the Nomai translator always looked right while
/// "Pokračovať" came out as "Pokra ova".
///
/// Registering a whole custom language font via the Localization Utility fixes
/// the menus, but it also flips <c>TextTranslation.IsLanguageLatin()</c> to
/// false, which drags dialogue, the translator and the ship log off their
/// proper fonts. And <c>UIStyleManager.GetMenuFont()</c> — the obvious hook —
/// is dead code with no callers; the fonts are assigned straight onto the
/// <see cref="Text"/> components in the scenes.
///
/// So we substitute at the Text level, but the decision is made **per font, not
/// per label**: a font that cannot draw Slovak is replaced everywhere it is
/// used, so a menu never mixes two typefaces. Fonts that can draw Slovak —
/// the dialogue and translator fonts — are left completely alone.
///
/// The replacement is preferably the game's *own* dynamic cut of the same
/// typeface (it ships several, e.g. Adobe - SerifGothicStd_Dynamic), which keeps
/// the menu pixel-identical to vanilla. Bundled Cabin is the fallback.
/// </summary>
internal static class SlovakFont
{
/// <summary>Cabin (SIL OFL 1.1), a humanist sans in the Gill Sans lineage, used
/// where the game has no dynamic cut of its own. Dynamic, so it can draw any
/// glyph Slovak needs.</summary>
private static Font _font;
/// <summary>The letters Slovak adds on top of plain ASCII. Only these are worth
/// probing — anything else in the text was already fine in English.</summary>
private const string SlovakLetters = "áäčďéíĺľňóôŕšťúýžÁÄČĎÉÍĹĽŇÓÔŔŠŤÚÝŽ";
/// <summary>Stylised display faces (the ship's readouts, seven-segment digits).
/// Replacing these wholesale would cost more in looks than it gains, so they
/// are only substituted on the individual labels that actually need a glyph.</summary>
private static readonly string[] Stylised = { "VCR_OSD_MONO", "digital-7", "PCBius" };
/// <summary>Font instance ID → the Slovak letters that font cannot draw.</summary>
private static readonly Dictionary<int, string> _gaps = new Dictionary<int, string>();
/// <summary>Labels we substituted, and the font the game wanted on them.</summary>
private static readonly Dictionary<Text, Font> _swapped = new Dictionary<Text, Font>();
/// <summary>Original font instance ID → what we put in its place.</summary>
private static readonly Dictionary<int, Font> _substitutes = new Dictionary<int, Font>();
/// <summary>The game's own dynamic fonts, which can draw glyphs their static
/// siblings were never baked with.</summary>
private static Font[] _gameDynamicFonts = new Font[0];
/// <summary>When set, a static font is replaced by the game's own dynamic cut of the
/// same typeface where one exists, keeping the vanilla look. Cabin otherwise.</summary>
internal static bool PreferGameTypeface = true;
private static ModBehaviour _mod;
internal static bool Loaded => _font != null;
internal static void Load(ModBehaviour mod)
{
_mod = mod;
var path = mod.ModHelper.Manifest.ModFolderPath + "assets/slovakfont";
var bundle = AssetBundle.LoadFromFile(path);
if (bundle == null)
{
mod.ModHelper.Console.WriteLine("Could not load font bundle at " + path, MessageType.Error);
return;
}
foreach (var font in bundle.LoadAllAssets<Font>())
{
if (font.name != "SlovakUI") continue;
_font = font;
Object.DontDestroyOnLoad(font);
break;
}
if (_font == null)
mod.ModHelper.Console.WriteLine("Font bundle has no 'SlovakUI' font.", MessageType.Error);
}
/// <summary>Give <paramref name="text"/> a font that can draw Slovak, or hand back
/// the game's own font once it is no longer needed.</summary>
internal static void Apply(Text text)
{
if (_font == null || text == null) return;
var current = text.font;
Font stored;
var swapped = _swapped.TryGetValue(text, out stored) && stored != null &&
current == SubstituteFor(stored);
// If anything else assigned a font since our swap, that is the new baseline.
var wanted = swapped ? stored : current;
if (!swapped) _swapped.Remove(text);
if (wanted == null) return;
var needsHelp = NeedsSubstitute(wanted, text.text);
if (needsHelp == swapped) return;
if (needsHelp)
{
_swapped[text] = wanted;
text.font = SubstituteFor(wanted);
}
else
{
_swapped.Remove(text);
text.font = wanted;
}
}
/// <summary>What to draw <paramref name="original"/>'s labels with instead. The
/// game ships dynamic cuts of several of its typefaces; borrowing the matching one
/// keeps the menu looking exactly like vanilla, which no substitute font can.</summary>
private static Font SubstituteFor(Font original)
{
Font cached;
if (_substitutes.TryGetValue(original.GetInstanceID(), out cached) && cached != null) return cached;
if (!PreferGameTypeface) return _font;
if (_gameDynamicFonts.Length == 0) RefreshGameFonts();
Font best = null;
var bestLength = 0;
foreach (var candidate in _gameDynamicFonts)
{
if (candidate == null) continue;
var baseName = candidate.name.EndsWith("_Dynamic")
? candidate.name.Substring(0, candidate.name.Length - "_Dynamic".Length)
: candidate.name;
if (baseName.Length <= bestLength) continue;
if (!original.name.StartsWith(baseName, System.StringComparison.Ordinal)) continue;
if (GapsOf(candidate).Length != 0) continue;
best = candidate;
bestLength = baseName.Length;
}
if (best == null) return _font;
_substitutes[original.GetInstanceID()] = best;
_mod?.ModHelper.Console.WriteLine(
$"drawing \"{original.name}\" with the game's own \"{best.name}\"", MessageType.Info);
return best;
}
private static void RefreshGameFonts()
{
var found = new List<Font>();
foreach (var font in Resources.FindObjectsOfTypeAll<Font>())
{
if (font != null && font.dynamic && font != _font) found.Add(font);
}
_gameDynamicFonts = found.ToArray();
}
/// <summary>Drop every cached decision, so a settings change takes effect at once.</summary>
internal static void ForgetChoices()
{
_substitutes.Clear();
_gameDynamicFonts = new Font[0];
foreach (var pair in _swapped)
{
if (pair.Key != null && pair.Value != null) pair.Key.font = pair.Value;
}
_swapped.Clear();
}
/// <summary>Re-check every live label. Scene loads and language changes reassign
/// fonts wholesale, and menus are built lazily, so sweep periodically too.</summary>
internal static void ApplyToAll()
{
if (_font == null) return;
// Labels that have since been destroyed would otherwise pile up.
var dead = new List<Text>();
foreach (var pair in _swapped)
{
if (pair.Key == null) dead.Add(pair.Key);
}
foreach (var text in dead) _swapped.Remove(text);
RefreshGameFonts();
foreach (var text in Object.FindObjectsOfType<Text>()) Apply(text);
}
private static bool NeedsSubstitute(Font font, string content)
{
if (!CustomLanguageActive()) return false;
var gaps = GapsOf(font);
if (gaps.Length == 0) return false;
// Ordinary UI faces are replaced everywhere they appear, so a menu never
// mixes typefaces. Stylised readouts only give way when a glyph is at stake.
if (!IsStylised(font.name)) return true;
if (string.IsNullOrEmpty(content)) return false;
foreach (var c in content)
{
if (gaps.IndexOf(c) >= 0) return true;
}
return false;
}
private static string GapsOf(Font font)
{
var id = font.GetInstanceID();
string gaps;
if (_gaps.TryGetValue(id, out gaps)) return gaps;
// Dynamic fonts only report a character as present once it has been
// rasterised, so ask for the whole Slovak set before probing.
if (font.dynamic) font.RequestCharactersInTexture(SlovakLetters);
var builder = new StringBuilder();
foreach (var c in SlovakLetters)
{
if (!font.HasCharacter(c)) builder.Append(c);
}
gaps = builder.ToString();
_gaps[id] = gaps;
if (gaps.Length > 0)
{
_mod?.ModHelper.Console.WriteLine(
$"font \"{font.name}\" cannot draw \"{gaps}\" — " +
(IsStylised(font.name) ? "substituting only where needed" : "substituting everywhere"),
MessageType.Info);
}
return gaps;
}
private static bool IsStylised(string fontName)
{
foreach (var stylised in Stylised)
{
if (fontName.IndexOf(stylised, System.StringComparison.OrdinalIgnoreCase) >= 0) return true;
}
return false;
}
/// <summary>True while a mod-registered language is selected. The Localization
/// Utility appends custom languages past <c>Language.TOTAL</c>, and treats
/// everything up to it as vanilla — same test it uses itself.</summary>
private static bool CustomLanguageActive()
{
if (TextTranslation.s_theTable == null) return false;
return TextTranslation.Get().GetLanguage() > TextTranslation.Language.TOTAL;
}
}
/// <summary>
/// Hooks: every label as it appears or changes, plus a sweep whenever the game
/// reassigns fonts wholesale.
/// </summary>
[HarmonyPatch]
internal static class SlovakFontPatches
{
[HarmonyPostfix, HarmonyPatch(typeof(Text), "OnEnable")]
public static void TextEnabled(Text __instance) => SlovakFont.Apply(__instance);
[HarmonyPostfix, HarmonyPatch(typeof(Text), "text", MethodType.Setter)]
public static void TextChanged(Text __instance) => SlovakFont.Apply(__instance);
// The game reassigns fonts wholesale when the language changes. Re-deciding here
// is safe: our own assignment re-enters once, finds the state already correct,
// and stops.
[HarmonyPostfix, HarmonyPatch(typeof(Text), "font", MethodType.Setter)]
public static void FontAssigned(Text __instance) => SlovakFont.Apply(__instance);
[HarmonyPostfix, HarmonyPatch(typeof(TextTranslation), nameof(TextTranslation.SetLanguage))]
public static void LanguageChanged() => SlovakFont.ApplyToAll();
}
}
+71
View File
@@ -0,0 +1,71 @@
using HarmonyLib;
using OWML.Common;
using OWML.ModHelper;
namespace SlovakTranslation
{
/// <summary>
/// Registers Slovenčina as a selectable language via xen-42's Localization
/// Utility (xen.LocalizationUtility). All the heavy lifting lives in the
/// utility; this mod just points it at our translated strings and patches the
/// few menu/HUD fonts that were never baked with Slovak glyphs (see
/// <see cref="SlovakFont"/>).
/// </summary>
public class SlovakTranslation : ModBehaviour
{
public static SlovakTranslation Instance;
/// <summary>Name the language is registered (and displayed) under.</summary>
public const string LanguageName = "Slovenčina";
/// <summary>Path (relative to the mod folder) to the translated strings.</summary>
public static string translationFile = "assets/Translation.xml";
/// <summary>The Localization Utility's API, kept for reflection in <see cref="SlovakFont"/>.</summary>
internal static ILocalizationAPI LocalizationApi;
private void Start()
{
Instance = this;
LocalizationApi = ModHelper.Interaction.TryGetModApi<ILocalizationAPI>("xen.LocalizationUtility");
if (LocalizationApi == null)
{
ModHelper.Console.WriteLine(
"Could not find xen.LocalizationUtility — is Interplanetary Polyglot installed?",
MessageType.Error);
return;
}
LocalizationApi.RegisterLanguage(this, LanguageName, translationFile);
ModHelper.Console.WriteLine("Registered language: " + LanguageName, MessageType.Success);
// Deliberately *not* AddLanguageFont: that would make IsLanguageLatin false
// and pull dialogue, the translator and the ship log off their correct
// vanilla fonts. We only patch the fonts that can't draw Slovak.
SlovakFont.Load(this);
if (SlovakFont.Loaded)
{
new Harmony("Homer.SlovakTranslation").PatchAll();
UnityEngine.SceneManagement.SceneManager.sceneLoaded += (scene, mode) => SlovakFont.ApplyToAll();
ModHelper.Console.WriteLine("Slovak menu/HUD font (Cabin) loaded and patched in.", MessageType.Success);
}
}
/// <summary>
/// <c>preferGameTypeface</c> — when on, a menu font that can't draw Slovak is
/// replaced by the game's own dynamic cut of the same typeface where one exists,
/// so the menu keeps its vanilla look. Turn it off to use the bundled Cabin
/// everywhere instead.
/// </summary>
public override void Configure(IModConfig config)
{
SlovakFont.PreferGameTypeface = config.GetSettingsValue<bool>("preferGameTypeface");
if (!SlovakFont.Loaded) return;
SlovakFont.ForgetChoices();
SlovakFont.ApplyToAll();
}
}
}
+42
View File
@@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<LangVersion>default</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
<RootNamespace>SlovakTranslation</RootNamespace>
<AssemblyName>SlovakTranslation</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<!-- Lets net48 build on machines without the .NET Framework targeting pack
(e.g. Linux / dotnet SDK only). Build-time only. -->
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
<PackageReference Include="HarmonyX" Version="2.10.0" />
<PackageReference Include="OWML" Version="2.5.2" />
<!-- Provides the Outer Wilds / Unity reference DLLs from NuGet, so no game
install is needed to compile. -->
<PackageReference Include="OuterWildsGameLibs" Version="1.1.12.168" />
</ItemGroup>
<ItemGroup>
<None Update="manifest.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="default-config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="assets/Translation.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="assets/slovakfont">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+22
View File
@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlovakTranslation", "SlovakTranslation.csproj", "{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}.Debug|Any CPU.Build.0 = Debug|Any CPU
{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}.Release|Any CPU.ActiveCfg = Release|Any CPU
{227A7B9F-9B05-4AE7-BDB9-1DE031C15853}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
+93
View File
@@ -0,0 +1,93 @@
Copyright 2018 The Cabin Project Authors (https://github.com/impallari/Cabin.git)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
+16268
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
{
"enabled": true,
"settings": {
"preferGameTypeface": true
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"filename": "SlovakTranslation.dll",
"author": "Jaroslav Beneš",
"name": "Slovak Localization / Slovenčina",
"uniqueName": "Homer.SlovakTranslation",
"version": "1.0.0",
"owmlVersion": "2.5.2",
"dependencies": [
"xen.LocalizationUtility"
]
}