Deprecate RunService:IsRunMode(); Add RunService:IsRunning(), RunService:IsPlaySolo()

RunService:IsClient(), RunService:IsServer(), and RunService:IsStudio() were a sight for sore eyes when they were released – no longer did we have to resort to using hacky stuff to check those three things. However, those three didn’t entirely cut it, as it’s impossible to differentiate between Edit and Play Solo. The only way to detect PlaySolo right now is:

Instance.new("Part", ChangeHistoryService)
ChangeHistoryService:SetWaypoint()
local isPlaySolo = RunService:IsServer() and RunService:IsClient() and not (RunService:IsRunMode() or ChangeHistoryService:GetCanUndo())

The server and the client are the same in the following cases: Edit, Run Mode, and Play Solo. In edit mode you can undo changes and in run mode RunService:IsRunMode() is true, so if both IsRunMode() and GetCanUndo() are false and the server and client are the same, we can conclude we are in Play Solo. But we shouldn’t have to use hacks to differentiate between Edit and Play Solo.

With RunService:IsRunning() and RunService:IsPlaySolo(), we’d be able to detect all possible states of the game without hacks.

LiveServer = RunService:IsServer() and not RunService:IsStudio()
LiveClient = RunService:IsClient() and not RunService:IsStudio()
TestServer = RunService:IsServer() and RunService:IsStudio() and not RunService:IsClient()
TestClient = RunService:IsClient() and RunService:IsStudio() and not RunService:IsServer()
Edit = RunService:IsClient() and RunService:IsServer() and not RunService:IsRunning()
Run = RunService:IsClient() and RunService:IsServer() and RunService:IsRunning() and not RunService:IsPlaySolo()
PlaySolo = RunService:IsPlaySolo()

You might ask “Why not RunService:IsClient() and RunService:IsServer() and #game.Players:GetPlayers() > 0 to detect Play Solo?” The problem with that is when Play Solo starts, the player doesn’t exist at first. If your script is a plugin, it will run before the player is created.

1 Like

Looks like RunService:IsRunMode() doesn’t even work right off the bat. Checking that from a plugin immediately when it’s run will always return false, even if you are in Run mode. Running print(game:GetService("RunService"):IsRunMode()) in the command bar in Run mode will return true even though it previously returned false.

Plugins are probably already running before RunService:Run() is called.
It’s a bit sad that they add those nice methods, but that they don’t work 100% of the time…