diff --git a/PumaShared/I18N/ILanguageService.cs b/PumaShared/I18N/ILanguageService.cs
new file mode 100644
index 0000000..bdbfe53
--- /dev/null
+++ b/PumaShared/I18N/ILanguageService.cs
@@ -0,0 +1,29 @@
+/*
+ * This file is part of PumaFramework.
+ *
+ * PumaFramework is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PumaFramework is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with PumaFramework. If not, see .
+ */
+
+namespace PumaFramework.Shared.I18N
+{
+
+public interface ILanguageService
+{
+ string Get(string path);
+
+ string Format(string path, params object[] args);
+}
+
+
+}
\ No newline at end of file
diff --git a/PumaShared/I18N/LanguageService.cs b/PumaShared/I18N/LanguageService.cs
new file mode 100644
index 0000000..bfc9bfa
--- /dev/null
+++ b/PumaShared/I18N/LanguageService.cs
@@ -0,0 +1,90 @@
+/*
+ * This file is part of PumaFramework.
+ *
+ * PumaFramework is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PumaFramework is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with PumaFramework. If not, see .
+ */
+
+using System.Collections.Generic;
+using System.Linq;
+using CitizenFX.Core.Native;
+
+namespace PumaFramework.Shared.I18N
+{
+
+public class LanguageService : ILanguageService
+{
+ readonly Dictionary _gameLanguageIdDict = new Dictionary
+ {
+ {0, Language.English},
+ {1, Language.French},
+ {2, Language.German},
+ {3, Language.Italian},
+ {4, Language.Spanish},
+ {5, Language.Portuguese},
+ {6, Language.Polish},
+ {7, Language.Russian},
+ {8, Language.Korean},
+ {9, Language.ChineseTraditional},
+ {10, Language.Japanese},
+ // Mexico
+ {11, Language.Spanish},
+ {12, Language.ChineseSimplified}
+ };
+
+ readonly LocalizedStringSet _localizedStringSet;
+
+ readonly List _fallbackStringSets;
+
+ // if it is client side code, auto detect game language
+ public LanguageService(string feature, Language language = Language.English )
+ {
+ #if CLIENT
+ language = _gameLanguageIdDict[API.GetCurrentLanguageId()];
+ #endif
+ _localizedStringSet = new LocalizedStringSet(feature, language);
+ var fallbacks = LanguageDescription.Get(language).Fallbacks;
+ _fallbackStringSets = fallbacks.Select(fallback => new LocalizedStringSet(feature, fallback)).ToList();
+ }
+
+ /*
+ since LocalizedStringSet.Get returns path if not found
+ if fallback strings also returns path, it means either:
+ 1) value is the key 2) not defined in anyway
+ hence default to path(key)
+ */
+ public string Get(string path)
+ {
+ var str = _localizedStringSet.Get(path);
+ foreach (var fallbackStringSet in _fallbackStringSets)
+ {
+ if (fallbackStringSet.Get(path) != str) return fallbackStringSet.Get(path);
+ }
+
+ return str;
+ }
+
+ // same logic as Get()
+ public string Format(string path, params object[] args)
+ {
+ var str = _localizedStringSet.Format(path, args);
+ foreach (var fallbackStringSet in _fallbackStringSets)
+ {
+ if (fallbackStringSet.Format(path, args) != str) return fallbackStringSet.Format(path, args);
+ }
+
+ return str;
+ }
+}
+
+}
\ No newline at end of file
diff --git a/PumaShared/PumaShared.projitems b/PumaShared/PumaShared.projitems
index 78f7fe8..c72e671 100644
--- a/PumaShared/PumaShared.projitems
+++ b/PumaShared/PumaShared.projitems
@@ -15,8 +15,10 @@
+
+