So I like using the same module for doing client and server things to keep things organized (for instance, I reuse my projectile class and it has different functions on the client and on the server). While I can find a workaround, it’d be nice to know really fast if the script is running on the server or if it’s running on a client. It would make these nice double-purposed modules I’m writing really easy to make.
Here’s a little trick to do it. Obviously needs to be adjusted to work in Test Solo though:
local function RunningOnServer()
return game:FindFirstChild("NetworkServer") ~= nil
end
Edit: For clients, you could also check to see if NetworkClient exists.
The problem with that is that in PlaySolo a NetworkServer won’t exist and it will always return that it’s a client. It won’t have a NetworkClient either, so you won’t be able to tell if you check for both.
It would be nice if ROBLOX gave us a good way to tell. If you want to try to solve the issue now though, it’ll require a rewrite of your modules possibly so you can use getfenv(). You’ll have to make sure each module returns a function, because getfenv() only works if the script that required the module is calling a function.
Example of module:
local isServer
return function()
local i=1
--allows this to work no many scripts up the original requirer is
while getfenv(i).script.ClassName == "ModuleScript" do i=i+1 end
isServer = getfenv(i).script.ClassName == "Script" or false
print(isServer)
>true or false
end
Example of script:
require(module)()
[quote] Here’s a little trick to do it. Obviously needs to be adjusted to work in Test Solo though:
local function RunningOnServer()
return game:FindFirstChild("NetworkServer") ~= nil
end
Edit: For clients, you could also check to see if NetworkClient exists. [/quote]
Another good way to do it is to create a temporary RemoteEvent and pcall FireServer and FireClient. It’s neat because it detects Play Solo, which is both a server and a client. Here’s a module:
-- Returns a table containing information about the current peer.
local Peer = {
IsServer = false;
IsClient = false;
Player = game:GetService('Players').LocalPlayer;
}
local r = Instance.new('RemoteEvent', game:GetService('ReplicatedStorage'))
local s, e = pcall(r.FireClient, r, nil)
if s or e ~= 'FireClient can only be called from the server' then
Peer.IsServer = true
end
local s, e = pcall(r.FireServer, r, nil)
if s then
Peer.IsClient = true
end
r:Destroy()
return Peer
I don’t think that method would need to be called externally (“workspace.RandomScript:IsRunningOnServer()” wouldn’t be a common use-case), and that you just need something in the script’s environment that lets you know.
_G is per-client/server, so I sometimes use it for things like that.
Just be very careful when differentiating between server/client when the code runs on both, and make sure your game still works in Play Solo (where the client and server are the same).
I do things like this when the server or client need their own slightly different implementation.
I think my game does something weird like this:
_G.IsServer = #game:GetService("ServerStorage"):GetChildren() > 0 -- Assuming there's always something there
_G.IsClient = game:GetService("Players").LocalPlayer ~= nil
Of course you could just have a module that returns that, because modulescripts are also per-client/server:
IsServer = require(game:GetService("ReplicatedStorage").Blah.NetworkStuff).IsServer
But _G.IsServer is much more convenient in my opinion, especially for things you use a lot. Just make sure that the script that puts stuff in _G runs before other scripts…
My game only has one startup Script and one startup LocalScript who’s only job is to require modules. This is to assure that things like that are done before any other code that might depend on it may run. This prevents me from doing what I did before the days of ModuleScripts, when I found myself doing things like this:
-- please don't do this, wait loops are almost always bad >:O
while not _G.Blah do
wait(0.03)
end
Edit: looks like Anaminus ninja’d me on a few things (by like 25 minutes lol :P)
[quote] Here’s a little trick to do it. Obviously needs to be adjusted to work in Test Solo though:
local function RunningOnServer()
return game:FindFirstChild("NetworkServer") ~= nil
end
Edit: For clients, you could also check to see if NetworkClient exists. [/quote]Similar to how I do it, except I use FindService.
local isServer = game:FindService("NetworkServer");
local isClient = not isServer;
if game:FindService("NetworkClient") then
-- client
elseif game:FindService("NetworkServer") then
-- server
else
-- play solo or run
-- check game.Players.LocalPlayer if you want
end
[quote]
local isServer = game:FindService("NetworkServer");
local isClient = not isServer;
[/quote]
This might break PlaySolo, when isServer and isClient should both be true
I like Seranok’s code :]
[quote]
local isServer = game:FindService("NetworkServer");
local isClient = not isServer;
[/quote]
This might break PlaySolo, when isServer and isClient should both be true
I like Seranok’s code :][/quote]Was never a problem for me, I don’t use Play Solo. ![]()
Bump, using remotes and pcalling them now apparently doesn’t work anymore for detecting Client/Server in PlaySolo. Can we have this yet, or does anyone have another hack I can use for testing?
RunService:IsClient(), RunService:IsServer()
Play solo is IsClient() == true && IsServer() == true
Defeats the purpose, I need to detect while inside of play solo, whether a module was required from the client, or from the server.
In this case you should probably use Test Server+Client instead of Play Solo.
PlaySolo is much much quicker on my PC than start server, and I see no reason why I can’t be allowed to get my scripts to work on both. Start server takes two minutes, play solo takes six seconds
They already addressed this in another thread, basically they coded studio to make each instance require a new window, and you need two instances to get two environments for the screpts.
What they need is a button to automatically start server and player on that server.
And a button to restart the server with the updated place, and re-enter the player into the restarted server.
Basically some ugly hack to streamline the workflow, if reworking how play solo works (and probably how many other things work, because of the single-window = single-instance assumption)
What do you mean? We’ve got a button like that, you can spawn 1 server and zero/one/multiple players at the same time if you want to. And you can click the clear button to kill all running instances. Or do you mean you want those all in the same window?
Hm.
Ive been using the SystemMenu style, which doesnt have that one, so I forgot.
Is there a way to make the ribbonbar
- Not close (I actually dont know if this is the default behavior or if thats something I changed?)
- Not have everything spread over 10 tabs I need to click between
- Have keyboard shortcuts for everything if I cant have the above 2
because otherwise its just faster to start server and player manually through systemmenu style so the option is kind of useless…
Yes. You can toggle between always open and only open while you have a tab selected with this button:
Yes. You can mod the ribbon.xml file to change how the tabs are set up (like in the image above), but you’ll need to use a custom studio launcher to prevent those changes from being overwritten when Studio updates (unless you want to manually copy it in every time). You can also make Studio look essentially how it was in SystemMenu by adding things to the Quick Access Menu (in between File button and ribbon tabs) by clicking the dropdown arrow immediately left of the first ribbon tab. This is how Studio usually looks for me (I keep the ribbon closed):
Yes. I modified my file menu too, so I don’t know where it is normally, but I think it’s under File > Advanced Options. Look for “Customize Shortcuts”. You can bind any studio action (anything that showed up on system menu bar pretty much) to a key with this.
If your question remains unanswered: game:GetService(“RunService”):IsRunMode() is what you’re looking for to detect while inside Play Solo
So in modules where you don’t want server-sided code run on the client but still want them accessible in solo mode, you’d write
if (RunService:IsServer() or RunService:IsRunMode()) then
I don’t see how that will tell me if the script using the module is from the client or from the server, that will only tell me if it’s in PlaySolo, right? Which could be from a Script or a LocalScript, and there’s no way to tell.

