The most accurate Operating System detector

Here is the function:

return function ()
	local GuiService = game:GetService("GuiService")
	local UserInputService = game:GetService("UserInputService")
	local VRService = game:GetService("VRService")
	local TextService = game:GetService("TextService")
	
	local TextSettings = {
		16,
		"SourceSans",
		Vector2.new(1000, 1000),
	}
	
	local invalidCharacterSize = TextService:GetTextSize("\u{FFFF}", table.unpack(TextSettings))
	
	local function isValidCharacter(character)
		local characterSize = TextService:GetTextSize(character, table.unpack(TextSettings))
		return characterSize.Magnitude ~= invalidCharacterSize.Magnitude
	end

	local RobloxVersion = version()
	local ButtonSelectImage = UserInputService:GetImageForKeyCode(Enum.KeyCode.ButtonSelect):lower()

	local isDesktop = RobloxVersion:match("^0%.") ~= nil
	local isConsole = GuiService:IsTenFootInterface() or RobloxVersion:match("^1%.") ~= nil
	local isMobile = RobloxVersion:match("^2%.") ~= nil
	local isVR = UserInputService.VREnabled and VRService.VREnabled
	local isWindows = GuiService.IsWindows
	local isApple = isValidCharacter("\u{F8FF}")

    if isConsole then
		local isPS4 = ButtonSelectImage:match("ps4")
		local isPS5 = ButtonSelectImage:match("ps5")
        local isXBox = ButtonSelectImage:match("xbox") or isWindows

        if isPS4 then
			return Enum.Platform.PS4
		elseif isPS5 then
			return Enum.Platform.PS5
		elseif isXBox then
			return Enum.Platform.XboxOne
		end
	elseif isMobile then
		local isUWP = isWindows

		if isUWP then
			return Enum.Platform.UWP
		else
			local isIOS = isApple
			local isAndroid = UserInputService.TouchEnabled

			if isIOS then
				return Enum.Platform.IOS
			elseif isAndroid then
				return Enum.Platform.Android
			else
				return Enum.Platform.Linux -- Sober (Linux)?
			end
		end
	elseif isDesktop then
		if isApple then
			return Enum.Platform.OSX
		elseif isWindows then -- Maybe check for Wine?
			return Enum.Platform.Windows
		end
	elseif isVR then
		if isMobile then
			return Enum.Platform.MetaOS
		end
	end

	return Enum.Platform.None
end

Credits to this article I read

Thanks @Tavikron For the PS4 and PS5 detection :pray:

49 Likes

Hey, great work, I read that article too, pretty interesting tbh and inspired me to do similar.

thanks for spending your time on this.
im curious though, whats the use case for this?

The original use case was novelty games like Flex Your Operating System, owned by shy (whose the author of the article linked above). Beyond that then ig OS detection can be useful for small but practical things like platform-specific UX adjustments, alternate control bindings, or disabling features that behave poorly on certain devices like androids. It’s not got a lot of use cases, but it’s a cool and handy thing in niche areas where platform really matters. You could also use it for profiling, such as tracking which OS plays your game the most or the least, and then tuning your experience, support, or marketing based on that data. It can also help highlight underperforming platforms, so you can improve compatibility or engagement/retention.

4 Likes

Taken from a custom script:

if UserInputService:GetImageForKeyCode(Enum.KeyCode.ButtonSelect) == "rbxasset://textures/ui/Controls/PlayStationController/PS4/ButtonTouchpad@2x.png" then
			InputInfo = "PS4"
		elseif UserInputService:GetImageForKeyCode(Enum.KeyCode.ButtonSelect) == "rbxasset://textures/ui/Controls/PlayStationController/PS5/ButtonShare@2x.png" then
			InputInfo = "PS5"
		elseif UserInputService:GetImageForKeyCode(Enum.KeyCode.ButtonSelect) == "rbxasset://textures/ui/Controls/XboxController/ButtonSelect@2x.png" then
			InputInfo = "XBOX"
		end
2 Likes

Can somebody on Ubuntu fact check this Pls :pray:
Apparently U+E0FF is the Ubuntu Logo

Thanks

Okay I added Ubuntu detection but I’m not sure if it works…

Sorry to break a bit, but I recommend putting some kind of disclaimer due to how many amounts of UI accessibility issues (e.g. large, obstructive touch buttons while playing on a tablet with mouse & keyboard) caused by incorrect use of workarounds such as OS estimation algorithms like this (which is very good and accurate, to be honest).

Just in case any of you is here to implement GUI-related workarounds, this is NOT the way you detect your GUI, as most operating systems that can run Roblox doesn’t 100% define what the type, size and capabilities of the device are.

For example, an Android or iOS device could be just a tablet that’s configured like if it’s a laptop. A Windows, macOS or Linux device could also be a tablet or a handheld that’s configured like if it’s a tablet or a smartphone.

I recommend to use better things that Roblox already provides like relative UDim2 values, UISizeConstraint, UserInputService.LastInputTypeChanged, and UserInputService:GetLastInputType() to make your UIs adapt to almost, if not all devices possible.

1 Like

out of curiosity where’d you find the article i had no idea anyone outside of my friends had read it

1 Like

Chat GPT

there is no way you actually found it from chatgpt come on…

1 Like

No like I genuinely found it from ChatGPT

why is chatgpt promoting my blog thats crazy :sob::sob::sob:

2 Likes

You’re welcome

1 Like

I found it on discord (word limit)

1 Like

Felt like sharing this.


Windows 11. Don’t know about the 32.

1 Like

Why doesn’t it work the second time?

InternalTest is apparently a new permission level, and I lowered mine attempting to see where the function cuts off from being called.

1 Like

Update:

Made it more readable and put everything in one function