{"id":19568251,"url":"https://github.com/turtiesocks/bevy_simple_i18n","last_synced_at":"2025-04-22T17:04:08.084Z","repository":{"id":262010361,"uuid":"885971399","full_name":"TurtIeSocks/bevy_simple_i18n","owner":"TurtIeSocks","description":"Plugin for the Bevy Engine that provides easy to use bindings for the rust-i18n crate","archived":false,"fork":false,"pushed_at":"2024-12-18T21:50:39.000Z","size":84743,"stargazers_count":17,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-15T18:59:10.487Z","etag":null,"topics":["bevy","bevy-engine","bevy-plugin","game-development","i18n"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TurtIeSocks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE-APACHE","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,"zenodo":null},"funding":{"github":"TurtIeSocks"}},"created_at":"2024-11-09T21:12:24.000Z","updated_at":"2025-04-12T17:09:09.000Z","dependencies_parsed_at":"2025-04-22T17:03:29.617Z","dependency_job_id":null,"html_url":"https://github.com/TurtIeSocks/bevy_simple_i18n","commit_stats":null,"previous_names":["turtiesocks/bevy_i18n","turtiesocks/bevy_simple_i18n"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TurtIeSocks%2Fbevy_simple_i18n","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TurtIeSocks%2Fbevy_simple_i18n/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TurtIeSocks%2Fbevy_simple_i18n/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TurtIeSocks%2Fbevy_simple_i18n/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TurtIeSocks","download_url":"https://codeload.github.com/TurtIeSocks/bevy_simple_i18n/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250285650,"owners_count":21405296,"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":["bevy","bevy-engine","bevy-plugin","game-development","i18n"],"created_at":"2024-11-11T06:03:04.609Z","updated_at":"2025-04-22T17:04:08.050Z","avatar_url":"https://github.com/TurtIeSocks.png","language":"Rust","funding_links":["https://github.com/sponsors/TurtIeSocks"],"categories":[],"sub_categories":[],"readme":"# bevy_simple_i18n\n\n[![crates.io](https://img.shields.io/crates/v/bevy_simple_i18n)](https://crates.io/crates/bevy_simple_i18n)\n[![license](https://img.shields.io/crates/l/bevy_simple_i18n)](https://github.com/TurtIeSocks/bevy_simple_i18n#license)\n\nAn opinionated but dead simple internationalization library for the Bevy game engine.\n\n## Project Status\n\nThis project wraps [rust-i18n](https://github.com/longbridgeapp/rust-i18n) library and is therefore not very \"Bevy\" like. The `rust-i18n` library embeds all of your locales via macros at compile time, while this is incredibly convenient, it isn't always desirable for game development. I have attempted to wrap the library in the most Bevy way I could but the long term goal is to create a more Bevy-like internationalization library, so this is mostly a proof of concept and you should expect breaking changes.\n\n## [Demo](https://turtiesocks.github.io/bevy_simple_i18n/)\n\n## Usage\n\n### CLI\n\n```sh\ncargo add bevy_simple_i18n\n```\n\n### Cargo.toml\n\nAdd the following to your `Cargo.toml`:\n\n```toml\nbevy_simple_i18n = { version = \"*\" }\n```\n\n### main.rs\n\n```rust\nfn main() {\n    App::new()\n        .add_plugins(DefaultPlugins)\n        .add_plugins(I18nPlugin)\n        .add_systems(Startup, setup)\n        .run();\n}\n\nfn setup(mut commands: Commands) {\n    commands.spawn(Camera2d::default());\n    commands.spawn((I18nText::new(\"hello\"), I18nFont::new(\"NotoSans\")));\n    commands.spawn((I18nNumber::new(2503.10), I18nFont::new(\"NotoSans\")));\n}\n```\n\n## File Structure\n\nIn order to use this plugin, the following folder structure is recommended:\n\n```ts\n.\n├── assets\n│   ├── locales\n│   │   ├── {locale_file}.yml\n│   │   ├── {locale_file}.json\n│   │   └── {locale_file}.toml\n│   └── fonts\n│       └── {font_name}\n│           ├── fallback.ttf\n│           ├── {locale}.ttf\n│           └── {locale}.otf\n└── Cargo.toml\n```\n\n## Locale Files\n\nLocale files can technically be put anywhere in your `assets` folder and this crate should find them. Since we're just using the `rust-i18n` library, the format is the same. You can find more information on the supported formats [here](https://github.com/longbridgeapp/rust-i18n?tab=readme-ov-file#locale-file).\n\n## Features\n\n### Text Translations\n\nTo translate text, you can use the `I18nText` component. This component takes a string as an argument and will automatically translate it based on the current locale.\n\nTranslation File:\n\n```yml\n_version: 2\nhello:\n  en: Hello world\n  zh-TW: 你好世界\n  ja: こんにちは世界\n```\n\nBevy code:\n\n```rust\ncommands.spawn(I18nText::new(\"hello\"));\n```\n\n### Number Localization\n\nTo localize numbers, you can use the `I18nNumber` component. This component will automatically localize the number based on the current locale.\n\nBevy code:\n\n```rust\ncommands.spawn(I18nNumber::new(2350.54));\n```\n\n### Interpolation\n\nInterpolation is supported using the `I18nText` component. You can interpolate variables by adding tuple (key, value) arguments to the `I18nText` component.\n\nTranslation File:\n\n```yml\n_version: 2\nmessages.hello:\n  en: Hello, %{name}\n  zh-TW: 你好，%{name}\n  ja: こんにちは、%{name}\nmessages.cats:\n  en: You have %{count} cats\n  zh-TW: 你有%{count}隻貓\n  ja: あなたは%{count}匹の猫を持っています\n```\n\nBevy code:\n\n```rust\ncommands.spawn(I18nText::new(\"messages.hello\").with_arg(\"name\", \"world\"));\ncommands.spawn(I18nText::new(\"messages.cats\").with_num_arg(\"count\", 20));\n```\n\n### Dynamic Fonts\n\nDynamic fonts enable this plugin to automatically switch between different fonts based on the current locale. For example, since Japanese and English languages have different character sets, you may want to use different fonts for each language. In order to make use of dynamic font, you must follow the file structure mentioned above.\n\nFolder setup:\n\n```ts\n.\n├── assets\n│   └── fonts\n│       └── NotoSans\n│           ├── fallback.ttf\n│           ├── ja.ttf\n│           └── zh.ttf\n└── Cargo.toml\n```\n\nWe would then spawn the dynamic font using:\n\n```rust\ncommands.spawn((I18nText::new(\"hello\"), I18nFont::new(\"NotoSans\")))\n```\n\nWhen the locale is set to `ja`, the font will be set to `ja.ttf`. If the locale is set to `zh-TW`, the font automatically load `zh.ttf`, since `zh-TW` does not have a font file. If the locale is set to any other locale, Bevy will load `fallback.ttf`.\n\n### Automatic Text Re-Rendering\n\nWhen the locale is changed, the plugin will automatically update all `I18nText` components to reflect the new locale. No boilerplate code is required, other than changing the locale using the `I18n` resource.\n\n```rust\nfn change_locale(mut i18n: ResMut\u003cI18n\u003e) {\n    i18n.set_locale(\"zh-TW\");\n}\n```\n\n## Traits\n\n### `I18nComponent`\n\nImplementing this trait for your component makes it eligible to register it and enable automatic re-translations. See [Example Implementation](./src/components/i18n_number.rs) for an example.\n\n### `I18nComponentRegistration`\n\nThis trait enables the `register_i18n_component` method on your Bevy App. Registering your components with this method will allow the plugin to automatically update the components when the locale is changed, requires your component to implement the `I18nComponent` trait. Unfortunately, this does not work with the Dynamic Font feature yet.\n\n```rust\n  app.register_i18n_component::\u003cI18nText\u003e();\n```\n\n## Bevy support table\n\n| bevy | bevy_simple_i18n |\n| ---- | ---------------- |\n| 0.15 | 0.1              |\n\n## Credits\n\n- [Fonts](https://fonts.google.com/noto/fonts)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturtiesocks%2Fbevy_simple_i18n","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fturtiesocks%2Fbevy_simple_i18n","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturtiesocks%2Fbevy_simple_i18n/lists"}