flame
flame copied to clipboard
docs: document recommended approach for localization support
What could be improved
As a developer, I want to be able to access localizable strings within my game and within my custom components so that any strings can be localized. I not aware of any documentation/recommended approaches regarding how this could be achieved and felt it could be an area of improvement in terms of documentation.
Why should this be improved
Flame games should support localization and should ideally be compatible with the recommended localization approach.
Any risks?
This is just a request for documentation/clarification on what the recommended approach is. One solution could be to inject an AppLocalizations
instance into the custom FlameGame
and then access that via the game ref across components. Not sure if there are better alternatives used by the flame community but it would be great to discuss approaches and document the recommended approach.
Thanks for the suggestion! We definitely needs to improve on this area. Right, the recommended l10n approach is already possible as a Flame Game
exposes the build context after it is attached, so to access the l10n from a component, it would just be a matter of doing like this:
class MyTextComponent extends TextComponent with HasGameRef<MyGame> {
@override
Future<void> onLoad() async {
text = AppLocalizations.of(gameRef.buildContext).myKey;
}
}
Things that could be improved here are:
- Like mentioned on the description, mention this on the docs
- Maybe offer some helpers as that line can get a little bit long?
Things that could be improved here are:
* Like mentioned on the description, mention this on the docs * Maybe offer some helpers as that line can get a little bit long?
We could make it as a bridge package maybe? So we don't "lock" people in on localization on the engine?
Maybe offer some helpers as that line can get a little bit long?
User-defined getter in MyGame
is sufficient for this
AppLocalizations get t => AppLocalizations.of(gameRef.buildContext);
Like mentioned on the description, mention this on the docs
This could go in a special "cookbook" collection of recipes, but we haven't started one yet.
Found this i18n_extension
package, which looks simple enough to not requiring any additional support from our side.
This can be added in the community snippets that we have open in another issue.
So, I looked through the standard internationalization library in Flutter, and also the i18n_extension
-- and I came to the conclusion that they may not be well-suited for games.
The main use case of these libraries is a widget-based App with some simple buttons, labels, and occasional text messages. Thus, the number of elements to translate is both small and known at compile time.
The needs in games, however, are different. There are WAY more things to translate:
- NPC names;
- object names and descriptions;
- dialogues;
- quests;
- books;
- captions;
- voice-overs;
- certain images, like signs (?);
- etc.
Moreover, many games allow downloadable content, so the content that needs to be translated would only be known at runtime. Also, since the translation data is large in size, it might be preferable to not bundle it with the game, but only download upon user request.
I think it might be better to investigate which l10n solutions exist for other game engines, and build a bridge package if possible.
Hi, how can I managed to get translated as you mentioned? I'm new to flame game and dart, and I've looked into some localization toturials but they all required set some delegates like
@override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: [ const Locale('en', "US"), const Locale('pt', "BR"), ], home: I18n(child: ...) ); }
But in my main dart the game entry was like this:
runApp(GameWidget(game: MyGame()));
It seems that the delegate must be initialized with in a MaterialApp but what a got is a GameWidget, you've mentioned that there's someway doable, but after a lot of searching I can't find a demo for the flame game, so could you please help me with this or send me some kind of torurials? Thanks
@tommycloud just put the GameWidget
as a child into the tree that you posted, instead of putting it directly in runApp
Thank you @spydon , worked as charm Here's my code, in case some fresh like me needed
class MyApp extends StatelessWidget {
var gameWidget;
MyApp(this.gameWidget) : super();
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: gameWidget
);
}
}
Another solution is slang. It doesn't depend on Flutter, so you can use it on your backend too.
With Translation Overrides you can load translations dynamically without sacrificing type-safety.
Disclaimer: I am author of this package.
I think this can be closed, since you have access to the context and then can use the same solutions as in Flutter.