{"id":22899079,"url":"https://github.com/kovacsgg/pyi2l","last_synced_at":"2026-01-03T14:24:59.235Z","repository":{"id":185900632,"uuid":"674271281","full_name":"KovacsGG/pyI2L","owner":"KovacsGG","description":"Mod I2Localization translations in Unity projects","archived":false,"fork":false,"pushed_at":"2024-11-15T15:23:44.000Z","size":5732,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-07T23:08:01.210Z","etag":null,"topics":["crowdin","csv","i2localization","modding","unity"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KovacsGG.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-03T14:31:46.000Z","updated_at":"2025-04-09T17:53:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"40d76c5a-b2b8-43a9-a416-72f38193d87e","html_url":"https://github.com/KovacsGG/pyI2L","commit_stats":null,"previous_names":["kovacsgg/pyi2l"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KovacsGG%2FpyI2L","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KovacsGG%2FpyI2L/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KovacsGG%2FpyI2L/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KovacsGG%2FpyI2L/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KovacsGG","download_url":"https://codeload.github.com/KovacsGG/pyI2L/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252968117,"owners_count":21833251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crowdin","csv","i2localization","modding","unity"],"created_at":"2024-12-14T00:35:49.862Z","updated_at":"2026-01-03T14:24:59.230Z","avatar_url":"https://github.com/KovacsGG.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyI2L\n\nThe tool was created to assist in quick offline prototyping of [Crowdin](https://crowdin.com) localization projects. It is my hope that it's also useful to mod community translations into Unity games utilizing the [I2 Localization Engine](https://inter-illusion.com/forum/i2-localization).\n\n## Installation\n\nDownload the latest Windows release to the right, or clone the repo and run with `python -m pyI2L`.\n\n## Usage\n\n`.\\pyI2L.exe ASSETS OPTIONS`\n\nUse without arguments to extract `./resources.assets.csv` from `./resources.assets`. The CSV will be in the format used by The Wandering Village Crowdin project.\n\n### `-a`, `--apply`\n\nSets apply mode and specifies the source file that contains the translations that should be modded into the bundle. Omitting it will set extract mode.\n\n### `-f`, `--format`\n\nIn apply mode it sets how the applied file will be parsed. In extract mode it will format the output file accordingly. Formatters can be installed by dropping them in the `parsers` directory. See [#Installing a formatter](#installing_a_formatter). Defaults to `Wavi` (for The Wandering Village Crowdin project). `rawCSV` recommended as a project-agnostic choice.\n\n### `-o`, `--output`\n\nSets the path of the produced file. In extract mode it defaults to `[ASSETS].[EXT]`, where `EXT` is an appropriate file extension for the used format. In apply mode it defaults to `[ASSETS]` and so will overwrite it.\n\nUse `./pyI2L.exe -h` for more information on usage.\n\n### Steps to mod in a custom translation for beginners\nYou need to run the commands in a command-line interface (CLI). CLI commands are executed relative to a directory (the \"current working directory\"), this is the path shown at the beginning of the line. On Windows you can open a terminal in a directory by Shift-clicking a directory and selecting \"Open in Terminal\". Alternatively, you can change the working directory by the `cd [PATH]` command.\n\n1. Find the I2Localization asset. It's usually in `resources.assets` in the `[GAME NAME]_Data` directory, but you can make sure by searching for a known string with `grep -rF KNOWN_STRING` (on Linux).\n2. Get the strings in some way:\n    * Download it from a Crowdin project by selecting \"Download\" on the correct file.\n    * Run the tool in extract mode (without arguments, or only specifying format and output) in the same directory as the assets file. The recommended format for generic projects is `rawCSV`.\n3. Make your edits to the strings.\n4. Run the tool with `./pyI2L.exe -a Wavi_Localization.csv` (substituting the appropriate file name) if your strings and assets file are in the same directory. This will overwrite the assets file, you might want to back it up first.\n\n\n## Installing a formatter\u003ca name=\"installing_a_formatter\"\u003e\u003c/a\u003e\n\nThe module should export an iterable `Reader(file_path: str)` class with a `languages` and `padding` attribute.\n\n`next(Reader())` should return a list of strings containing a key and its translations:\n\n```py\n[key: str, value0: str, value1: str, ..., type: int]\n```\n\n`languages` should be a list of tuples containing column/language names and an int for every alternative:\n\n```py\n[(lang0.name: str, lang0.code: str, lang0.type: int), (lang1.name: str, lang1.code: str, lang1.type: int), ...]\n```\n\n`padding` should be an `int` specifying the number of `\\x00` bytes between records of the I2Languages binary representation. 16 is a common default.\n\nThe module should export `Writer(data: I2)` class with a `to_bytes()` method.\n\n```py\nclass I2:\n    languages: Languages\n    body: Body\n    header: Header\nclass Languages:\n    length: int # Number of languages/columns\n    items: list[tuple[Field, Field, int]]\nclass Body:\n    padding: int # Between Records\n    length: int # Number of records\n    items: list[Record]\nclass Record:\n    id: int # Key\n    type: int # Usually 0, 9 for some records in some games. The meaning is unkown\n    length: int # Number of fields\n    items: list[Field]\nclass Field:\n    v: str # Value\n    span: int # Byte length of value\n    padding: int # After value (4-byte alignment)\nclass Header: ...\n```\n\nEvery class has a `to_bytes()` method.\n\nThe module can optionally export an `ext` string to be used as a default extension by the CLI app.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkovacsgg%2Fpyi2l","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkovacsgg%2Fpyi2l","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkovacsgg%2Fpyi2l/lists"}