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>
This commit is contained in:
Jaroslav Beneš
2026-07-20 10:12:10 +02:00
parent cec2cad2ce
commit e66ce54d3e
11 changed files with 16443 additions and 1 deletions
+11
View File
@@ -0,0 +1,11 @@
# Build output
bin/
obj/
# User-specific project files
*.user
# IDE
.vs/
.vscode/
.idea/
+99
View File
@@ -0,0 +1,99 @@
# CLAUDE.md — Outer Wilds SK Translation Mod
Working context for Claude Code (and human contributors) in this repository.
## What this repo is
An **unofficial Slovak (slovenčina) translation mod for *Outer Wilds*** — base
game **and** the *Echoes of the Eye* DLC. It is primarily a **data/translation
project**, not a conventional codebase: the bulk of the work is one large XML file
of translated strings, wrapped in a thin C# mod shell.
- **Not affiliated with Mobius Digital / Annapurna.** Game text is © Mobius
Digital, used under their Fan Content Policy. This project's own code and
translation are MIT (see [`LICENSE`](LICENSE) and [`README.md`](README.md)).
- Roadmap and phase status live in [`PLAN.md`](PLAN.md). Update it as phases land.
## How the mod works
It is an [OWML](https://github.com/ow-mods/owml) mod that depends on **xen-42's
Localization Utility / Interplanetary Polyglot** (`xen.LocalizationUtility`, MIT).
The utility does all the heavy lifting; this mod just:
1. Declares the dependency in `manifest.json`:
`"dependencies": ["xen.LocalizationUtility"]`.
2. In its `ModBehaviour.Start()`, grabs the API and registers a new language:
```csharp
var api = ModHelper.Interaction.TryGetModApi<ILocalizationAPI>("xen.LocalizationUtility");
api.RegisterLanguage(this, "Slovenčina", "assets/Translation.xml");
```
3. Ships the translated strings in `assets/Translation.xml`.
**No game files are needed to build the mod.** The English source
`Translation.xml` is published by the utility repo and used as the template.
Slovak is a Latin-script language, so **no `AddLanguageFixer`** (that's for RTL
scripts) is needed. A custom font via `AddLanguageFont` (Unity **2019.4.27f1**
asset bundle) is only required if the stock game font is missing Slovak glyphs —
to be verified during in-game testing (Phase 6/7).
## Planned repo layout
```
Outer-Wilds-SK-Translation-Mod/
├── manifest.json # OWML manifest (uniqueName, deps, entry DLL)
├── SlovakTranslation.cs # ModBehaviour: registers the language
├── ILocalizationAPI.cs # interface copied from the utility
├── SlovakTranslation.csproj # build against OWML/game refs
├── SlovakTranslation.sln
├── assets/
│ └── Translation.xml # THE translation (English keys, Slovak values)
├── docs/
│ └── glossary.md # fixed SK terms for proper nouns
├── README.md · CLAUDE.md · PLAN.md · LICENSE
```
Model the C#/manifest scaffold on the community Czech mod
([`shippy/outer-wilds-czech`](https://github.com/shippy/outer-wilds-czech)).
## Translation conventions (important)
`Translation.xml` is a **flat** `<TranslationTable_XML>` of repeated `<entry>`
blocks, each with a `<key>` and a `<value>`. Rules:
- **Never edit `<key>`.** It is the exact English source string the game matches
on — changing it silently breaks that string's translation.
- **Translate only `<value>`.** Start from a copy of the English file (key == value)
and replace each value with Slovak.
- **Preserve inline markup verbatim**, including XML-escaped tags:
`&lt;color=orange&gt;…&lt;/color&gt;`, `&lt;i&gt;…&lt;/i&gt;`, `&lt;/color&gt;`,
and raw entities `&lt; &gt; &amp;`. Translate the words, keep the tags.
- **Keep speaker prefixes** (e.g. `POKE:`, `CLARY:`) and any leading labels.
- **Use the glossary** (`docs/glossary.md`) for proper nouns and recurring terms so
Nomai / the Eye / Ash Twin Project / etc. render identically everywhere.
- Watch text length: Nomai text walls and UI have limited space — prefer concise
phrasings where the English is terse.
**Translation production:** machine-assisted first pass (clean-room, no third-party
text) followed by a Slovak-speaking review pass. Phase by category for shippable
increments: **UI/menus → dialogue/text walls → ship log**.
## Build & test
- Toolchain present locally: `dotnet 6.0.400`, `git`. **The game and the Outer
Wilds Mod Manager are NOT installed on this machine** — in-game testing (Phase 7)
requires installing *Outer Wilds* + Mod Manager + OWML first.
- Build: `dotnet build` (the `.csproj` references OWML/game DLLs — see the Czech
mod for the exact reference setup).
- Test: load via the Mod Manager, select **Slovenčina**, and verify menus,
dialogue, and the ship log render correctly (including diacritics
á ä č ď é í ĺ ľ ň ó ô ŕ š ť ú ý ž).
## Repo / process notes
- This is a **standalone project repo** (Gitea `Homer/Outer-Wilds-SK-Translation-Mod`),
independent of `~/Agent/Systems`. Changes here do **not** require a system
changelog entry — unless we install system tooling (game, Mod Manager, a Unity
version) to support it, in which case record that in `~/Agent` docs as usual.
- Commit as the Gitea identity (Homer <admin@ecoposta.sk>). Don't commit/push
unless asked.
+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
}
}
+93
View File
@@ -0,0 +1,93 @@
# PLAN.md — Slovak translation of Outer Wilds
Roadmap for building the mod. Status markers: ✅ done · 🚧 in progress · ⬜ todo.
## Goal
Add **Slovenčina** as a fully selectable language to *Outer Wilds*, covering the
**base game and the *Echoes of the Eye* DLC**, distributed as an Outer Wilds Mod
Manager mod. Quality target: natural, consistent Slovak — not literal machine
output.
## Approach
- Built on **xen-42's Localization Utility / Interplanetary Polyglot**
(`xen.LocalizationUtility`) — register a new language from one `Translation.xml`.
No game files needed to build.
- **Translation:** machine-assisted first pass (clean-room, no third-party
translation text reused), then a **Slovak-speaking human review pass**. Phased by
category so partial releases are usable: **UI/menus → dialogue/text walls →
ship log**.
- **Scope:** the single ~896 KB `Translation.xml` already contains base game + DLC
strings together, so scope is "everything," sequenced internally by category.
## Phases
### Phase 1 — Repo scaffold & docs ✅
`README.md`, `CLAUDE.md`, `PLAN.md`, and MIT `LICENSE` in place.
### Phase 2 — Mod skeleton ✅
Created the OWML mod shell, modelled on
[`shippy/outer-wilds-czech`](https://github.com/shippy/outer-wilds-czech):
- `manifest.json``author: Homer`, `uniqueName: Homer.SlovakTranslation`,
`name`, `version`, `owmlVersion`, `dependencies: ["xen.LocalizationUtility"]`.
- `ILocalizationAPI.cs` — interface copied from the utility.
- `SlovakTranslation.cs``ModBehaviour` calling
`api.RegisterLanguage(this, "Slovenčina", "assets/Translation.xml")`.
- `SlovakTranslation.csproj` / `.sln`, `.gitignore`, empty `assets/`.
- Optional: GitHub/Gitea release workflow.
### Phase 3 — Import English source ✅
Imported the base English `Translation.xml` (896 KB, 2424 entries, keys == values)
from the utility repo into `assets/`. This is the file to translate.
> Build verified: `dotnet build -c Release` compiles against the `OWML` /
> `OuterWildsGameLibs` NuGet packages (no game install needed) and stages a
> loadable mod folder (`SlovakTranslation.dll` + `manifest.json` +
> `default-config.json` + `assets/Translation.xml`) in `bin/`.
### Phase 4 — Glossary ⬜
Write `docs/glossary.md` fixing SK renderings (or keep-in-English decisions) for
proper nouns and recurring terms, e.g.: Nomai, Hearthian, the Eye / Eye of the
Universe, Ash Twin Project, Vessel, Black Hole Forge, Quantum Moon, Sun Station,
ship log, Nomai statue, Ember Twin, Ash Twin, Timber Hearth, Brittle Hollow,
Giant's Deep, Dark Bramble, Interloper, Stranger (DLC), Owlk/"Owlks" (DLC).
Decide tone/register (informal *ty* vs. formal) and lock it here.
### Phase 5 — Translate `<value>` entries 🚧/⬜
Machine-assisted pass → human review, by category (UI/menus → dialogue → ship log),
base + DLC. Preserve all `&lt;color=…&gt;`/`&lt;i&gt;` markup, entities, and speaker
prefixes. Track progress and any hard-to-translate lines here or in issues.
### Phase 6 — Diacritic / font check ⬜
Verify the stock game font renders all Slovak glyphs
(á ä č ď é í ĺ ľ ň ó ô ŕ š ť ú ý ž). Only if any are missing: build a font asset
bundle in **Unity 2019.4.27f1** and wire `api.AddLanguageFont(...)`.
### Phase 7 — Build & in-game test ⬜
**Prerequisite:** install *Outer Wilds* + Outer Wilds Mod Manager + OWML (none are
on this machine yet). Then `dotnet build`, load via the Mod Manager, select
Slovenčina, and verify menus, dialogue, and ship log render correctly.
### Phase 8 — Release ⬜
Tag a Gitea release; optionally submit to the Outer Wilds mod database so the mod
appears in the Mod Manager for everyone.
## Open items / risks
- **Font coverage** for Slovak-specific glyphs (ľ ĺ ŕ ô ä) is unverified until
in-game testing (Phase 6/7).
- **Translation volume is the real cost** — ~896 KB of source text. A
Slovak-speaking review pass is essential, especially for DLC/dialogue nuance,
puns, and Nomai text-wall length constraints.
- **In-game testing is blocked** until the game + Mod Manager are installed locally.
- Confirm the tone/register decision (Phase 4) early — reworking it later is costly.
## References
- Localization Utility / Interplanetary Polyglot (framework, MIT, source template):
https://github.com/xen-42/outer-wilds-localization-utility
- Czech mod (structure reference): https://github.com/shippy/outer-wilds-czech
- OWML: https://github.com/ow-mods/owml
- Mod Manager: https://outerwildsmods.com/mod-manager/
+69 -1
View File
@@ -1,2 +1,70 @@
# 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 [`PLAN.md`](PLAN.md) for the 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 [`PLAN.md`](PLAN.md) 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 `docs/glossary.md` so names (Nomai, the Eye, Ash Twin
Project, …) stay consistent across the whole game.
See [`CLAUDE.md`](CLAUDE.md) 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).
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.
+35
View File
@@ -0,0 +1,35 @@
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.
/// </summary>
public class SlovakTranslation : ModBehaviour
{
public static SlovakTranslation Instance;
/// <summary>Path (relative to the mod folder) to the translated strings.</summary>
public static string translationFile = "assets/Translation.xml";
private void Start()
{
Instance = this;
var api = ModHelper.Interaction.TryGetModApi<ILocalizationAPI>("xen.LocalizationUtility");
if (api == null)
{
ModHelper.Console.WriteLine(
"Could not find xen.LocalizationUtility — is Interplanetary Polyglot installed?",
MessageType.Error);
return;
}
api.RegisterLanguage(this, "Slovenčina", translationFile);
ModHelper.Console.WriteLine("Registered language: Slovenčina", MessageType.Success);
}
}
}
+39
View File
@@ -0,0 +1,39 @@
<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>
</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
+16019
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
{
"enabled": true
}
+11
View File
@@ -0,0 +1,11 @@
{
"filename": "SlovakTranslation.dll",
"author": "Jaroslav Beneš",
"name": "Slovak Localization / Slovenčina",
"uniqueName": "Homer.SlovakTranslation",
"version": "0.1.0",
"owmlVersion": "2.5.2",
"dependencies": [
"xen.LocalizationUtility"
]
}