CountryFlags
Utilities for turning country, region and language codes into flag emoji, and for finding out
which country a player or the server is in. The module is a plain table of functions: there is
nothing to construct and no self to pass.
local Players = game:GetService("Players")
local CountryFlags = require(path.to.CountryFlags)
-- Server: greet each player with the flag of the country they are connecting from.
Players.PlayerAdded:Connect(function(player)
local ok, countryCode = pcall(CountryFlags.GetPlayerRegion, player) -- yields, e.g. "US"
if not ok then
return
end
local flag = CountryFlags.Flags[countryCode] or CountryFlags.Get("UN")
print(("Welcome %s %s"):format(player.Name, flag))
end)
-- Anywhere: flags from a region string or a language code.
local language, country = CountryFlags.SplitRegion("en-us") -- "EN", "US"
print(CountryFlags.Flags[country]) -- "🇺🇸"
print(CountryFlags.FromLanguage(language)) -- "🇺🇸" (EN is mapped to US)
print(CountryFlags.FromLanguage("ja")) -- "🇯🇵"
Codes are compared case-insensitively by the helper functions (they upper-case their input), but the CountryFlags.Flags and CountryFlags.LanguageMap tables themselves are keyed by upper-case codes.
Credits: written by KashTheKing. No third-party dependencies.
Installation and guide: CountryFlags package page.
Types​
LocationData​
interface LocationData {ip:Â string--
The public IP address the request was made from, e.g. "2605:c840:402:8bac::8e03".
ip_decimal:Â number--
The same IP address as a decimal number.
country:Â string--
Full country name, e.g. "United States".
country_iso:Â string--
Two-letter ISO 3166-1 country code, e.g. "US". Pass this to CountryFlags.Get.
country_eu:Â boolean--
Whether the country is a member of the European Union.
region_name:Â string--
Name of the state, province or region, e.g. "Nevada".
region_code:Â string--
Short region code, e.g. "NV".
metro_code:Â number--
Metro (designated market area) code, e.g. 839.
zip_code:Â string--
Postal code, e.g. "89183".
city:Â string--
City name, e.g. "Las Vegas".
latitude:Â number--
Latitude in decimal degrees, e.g. 36.0021.
longitude:Â number--
Longitude in decimal degrees, e.g. -115.147.
time_zone:Â string--
IANA time zone name, e.g. "America/Los_Angeles".
}
The JSON body returned by https://ifconfig.co/json, as decoded by CountryFlags.GetLocationData.
Because it describes the machine that made the HTTP request, it is the location of the game
server, not of any player. Fields are whatever the service returns; some may be missing for
IP addresses the service cannot geolocate.
Properties​
Flags​
This item is read only and cannot be modified. Read OnlyCountryFlags.Flags: {[string]:Â string}
Dictionary of upper-case ISO 3166-1 alpha-2 country codes to their flag emoji, e.g.
CountryFlags.Flags.GB == "🇬🇧". Besides real countries it also contains EU (European Union)
and UN (United Nations), which are handy fallbacks. Indexing an unknown code returns nil.
LanguageMap​
This item is read only and cannot be modified. Read OnlyCountryFlags.LanguageMap: {[string]:Â string}
Maps an upper-case two-letter ISO 639-1 language code to the country code whose flag
is conventionally used for that language, e.g. EN -> "US", JA -> "JP", PT -> "BR",
AR -> "SA". It is used by CountryFlags.FromLanguage. Only about two dozen common languages
are mapped; a language is not a country, so the choice is a convention, not a fact. You may
add or override entries at runtime (CountryFlags.LanguageMap.EN = "GB") before calling
CountryFlags.FromLanguage.
Functions​
GetCodes​
CountryFlags.GetCodes() → {string}--
Array of upper-case country codes such as "US", including "EU" and "UN".
Returns every code that has a flag in CountryFlags.Flags, as a new array. The order is not
defined (it comes from pairs), so sort it yourself if you need a stable list.
local codes = CountryFlags.GetCodes()
table.sort(codes)
print(#codes, codes[1]) -- 231 AD
IsA​
CountryFlags.IsA(t:Â T--
Any value; non-strings return false.
) → boolean--
true if the value passes the country-code shape check.
Tells whether value looks like a two-letter country code. It only checks the shape of the
value (a string of length two once letters are accounted for); it does not check that the
code exists in CountryFlags.Flags, so IsA returning true does not guarantee that
CountryFlags.Get will find a flag.
CAUTION
The current implementation strips the letters with gsub("%a", "") and then requires the
remaining string to be two characters long. A plain code such as "US" therefore
returns false, and CountryFlags.Get (which asserts on this function) errors for it. Until
this is fixed, index CountryFlags.Flags directly for lookups.
Get​
CountryFlags.Get(countryCode:Â string--
Two-letter country code, any case.
) → string--
The flag emoji, or nil when the code is unknown.
Returns the flag emoji for a country code. The code is upper-cased before the lookup, so
"gb" and "GB" both work. If the code passes CountryFlags.IsA but has no entry in
CountryFlags.Flags, the result is nil even though the declared return type is string.
print(CountryFlags.Get("de")) -- "🇩🇪"
Errors
| Type | Description |
|---|---|
| "Invalid country code" | When `countryCode` does not satisfy [CountryFlags.IsA] (see the caution there). |
GetPlayerRegion​
This item only works when running on the server. ServerThis is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. YieldsCountryFlags.GetPlayerRegion() → string--
Upper-case country/region code such as "US".
Returns the two-letter country/region code the player is connecting from, e.g. "US", by
calling LocalizationService:GetCountryRegionForPlayerAsync. Despite the name, the result is
a country code, not a language-COUNTRY locale string, so it can be used directly with
CountryFlags.Flags. Wrap the call in pcall: the underlying Roblox API yields and raises an
error if the request fails or the player has already left.
local ok, code = pcall(CountryFlags.GetPlayerRegion, player)
if ok then
print(CountryFlags.Flags[code])
end
Errors
| Type | Description |
|---|---|
| string | Propagated from `GetCountryRegionForPlayerAsync` when the lookup fails. |
GetLocationData​
This item only works when running on the server. ServerThis is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Fetches the geolocation of the game server by requesting https://ifconfig.co/json with
HttpService:GetAsync and decoding the JSON body into a LocationData table. This is the
server's public IP location (the data centre the server runs in), not a player's location;
use CountryFlags.GetPlayerRegion for players.
Requirements and failure modes:
- Server only: the function asserts
RunService:IsServer(). - HTTP requests must be enabled in Game Settings, otherwise
GetAsyncerrors. -
The request yields and can fail (network error, rate limit, service down), so call it in a
pcalland cache the result rather than calling it per player.
local ok, location = pcall(CountryFlags.GetLocationData)
if ok then
print(location.country, location.country_iso, CountryFlags.Flags[location.country_iso])
end
Errors
| Type | Description |
|---|---|
| "You must be on the server" | When called from a client. |
| string | Any error raised by `HttpService:GetAsync` or `HttpService:JSONDecode`. |
SplitRegion​
CountryFlags.SplitRegion(regionString:Â string--
A locale string containing at least one -, e.g. "en-us".
) → (string,--
The language code in upper case, e.g. "EN".
string--
The country/region code in upper case, e.g. "US".
)
Splits a language-COUNTRY locale string such as "en-us" (the format of
LocalizationService.RobloxLocaleId or Player.LocaleId) into its language and country codes,
both upper-cased. Only the first two segments are returned, so "zh-Hans-CN" gives
"ZH", "HANS".
local language, country = CountryFlags.SplitRegion(player.LocaleId) -- "EN", "US"
local flag = CountryFlags.Flags[country] or CountryFlags.FromLanguage(language)
Errors
| Type | Description |
|---|---|
| "Invalid region string" | When the string does not contain a `-`. |
FromLanguage​
CountryFlags.FromLanguage(languageCode:Â string--
Two-letter ISO 639-1 language code, any case.
) → string?--
The flag emoji of the mapped country, or nil if the language is not mapped.
Returns a representative flag for a language code by looking the upper-cased code up in
CountryFlags.LanguageMap and then in CountryFlags.Flags. Returns nil when the language
has no mapping, which is the case for most of the world's languages, so always handle nil.
print(CountryFlags.FromLanguage("ko")) -- "🇰🇷"
print(CountryFlags.FromLanguage("eo")) -- nil (Esperanto is not mapped)