Using the Command Line in Roblox Studio to access information stored in Module results in two different versions of the same Module

When creating in Roblox Studio, I am setting up a coin system to store the values of every player. I am doing so, by storing a ModuleScript in ServerScriptService, called “PlayerCoinsModule”. Inside it, you’ll find a table containing how many coins each player has, stored using each player’s User ID as indexes for identification, and the usual functions to alter and read coin amounts. Here is an example:

local PlayerCoinsModule = {}

local PlayerCoins = {}

function PlayerCoinsModule.IncrementCoins(userId, amount)
	PlayerCoins[userId] += amount
end

function PlayerCoinsModule.GetUserCoinAmount(userId, amount)
	return PlayerCoins[userId]
end

Players.PlayerAdded:Connect(function(player)
	local userId = player.UserId
	local PlayerCoins[userId] = 0
end)

Players.PlayerRemoving:Connect(function(player)
	local userId = player.UserId
	local PlayerCoins[userId] = nil
end)

return PlayerCoinsModule

(Note that this is a simplified example, and I am aware it lacks components and best practices. Assume it has all the services available and works perfectly.)

What is the issue?
First, let me contextualize:
When treating a ModuleScript as a source of stored information for the server, whenever I require the Module in question using Server Scripts, the amount of player coins each UserId has attributed to it is always consistent, no matter when I require the module, or in what Server Script I do it.
This is also consistent when doing the same thing in the command line in game by pressing f9 (NOT in studio, this is important)

For example: Let’s say that I create two server scripts and put them in workspace. Let’s say they both require “PlayerCoinsModule”
We’ll call the first script InitialScript, and the second one, ReadScript.
Assuming the userId is for the exact same player in both scripts, let’s check the behavior.
Here is the behavior of InitialScript summarized:

local PlayerCoinsModule = require(ServerScriptService.PlayerCoinsModule)
local userId = Player.UserId
PlayerCoinsModule.IncrementCoins(userId, 5)

Here is the behavior of ReadScript summarized:

task.wait(5)
local PlayerCoinsModule = require(ServerScriptService.PlayerCoinsModule)
local userId = Player.UserId
local value = PlayerCoinsModule.GetUserCoinAmount(userId, value)
print(value)

What happens then? In normal circumstances, even though ReadScript required PlayerCoinsModule 5 seconds after InitialScript did, ReadScript should still print “5”, since InitialScript changed that value for that UserId, and the information should be consistent.
This is the case for me, naturally, when treating ModuleScripts as source of stored information, both in studio and in game.

However, things change when I start using the Studio Command line.
But to contextualize even more, let’s talk about the in-game command line first. Not the studio one.
In-game, by pressing f9, I can run commands, which I personally love to do in order to debug certain elements of the game. Let’s say I want to quickly give the player 100 coins in order to buy an item and test it. I would just run something of the sorts in the command line:

local PlayerCoinsModule = require(ServerScriptService.PlayerCoinsModule)
local userId = Player.UserId
PlayerCoinsModule.IncrementCoins(userId, 5)

(Again, this is a simplified example, pretend it has all the necessary services and components available)

The expected behavior is that it would do exactly what it is meant to do: give the player 5 coins. And that is exactly what it does, IF:

  • I require the “PlayerCoinsModule” using another ServerScript
  • I require the “PlayerCoinsModule” using not a ServerScript, but the command line in-game, by pressing f9 (which should also run server code)

When does it NOT do that?

  • When using the Server-Sided command line in ROBLOX STUDIO

Elaboration: When using the command line in Roblox Studio, I find myself incapable of reading and changing information consistent to the actual game within that module, because it seems that, by running the same debug code example I showed you above in the Studio command line, an alternate version of the “PlayerCoinsModule” seems to be created, where information is completely different, as if the module that was created had never been altered by “InitialScript” in the first place.

Let’s practice the same example of the two ServerScripts, but instead of 2 ServerScripts requiring the module, it will be 1 ServerScript, the InitialScript, and then I will attempt to read the coin amount by using the Roblox Studio Command Line. Let’s hit it:

Here is the behavior of InitialScript summarized, it is the same as before:

local PlayerCoinsModule = require(ServerScriptService.PlayerCoinsModule)
local userId = Player.UserId
PlayerCoinsModule.IncrementCoins(userId, 5)

Here is the debug line that should be ran on Studio Command Line, after InitialScript has done its job:

local PlayerCoinsModule = require(ServerScriptService.PlayerCoinsModule)
local userId = Player.UserId
local value = PlayerCoinsModule.GetUserCoinAmount(userId, value)
print(value)

For some unknown reason, when running this debug line in the Roblox Studio Server-Sided Command Line, even though it has behavior identical to the previously demonstrated “ReadScript”, and also runs Server-Sided, it prints the value “0” instead, as the “PlayerCoinsModule” had never been ever altered in the first place. And it gets worse, if I attempt to alter the values for the “PlayerCoinsModule” using the Studio Command Line, it will treat it as a completely identical copy of the original module, except those changes are only seen by the command line. Example:

If, even after the InitialScript showed above has ran and set the coins for the specified plaver to 5, I run the following code using the STUDIO COMMAND LINE:

local PlayerCoinsModule = require(ServerScriptService.PlayerCoinsModule)
local userId = Player.UserId
PlayerCoinsModule.IncrementCoins(userId, 15)

A weird behavior appears.
After the “InitialScript” incremented 5 coins to that UserId, and the Roblox Studio Command Line incremented 15, Suppose we have the following debug command and want to run it:

local value = PlayerCoinsModule.GetUserCoinAmount(userId, value)
print(value)

The expected behavior is that, since InitialScript added 5 coins, and then the Studio Command Line added 15, no matter where I run those 2 lines, as long as it’s Server-Sided, it should print 20. However this is not the case.

  • Running the 2 demonstrated debug lines in Studio Command Line, prints “15”
  • Running the 2 demonstrated debug lines in any Server Script, prints “5”

I do not understand why this is happening, given that the in-game f9 command line works properly, and that doing the same thing with ServerScripts also results in expected behavior. It is as if the Roblox Studio Command Line has a completely different behavior. Am I doing something wrong? Am I treating modules incorrectly? Is there any “fine print” of sorts that I am not aware of? I know that ModuleScripts will only run the first time you use “require()” them and will return what they first returned afterwards, yes, however, I am sure the information altered within variables there should be kept consistent thorough the server. This is how I have been building my structures to store player information. Am I wrong and doing this incorrectly? Or is this a very specific bug/unwanted conditional behavior that I have found?

TL;DR: Why does requiring (Server-Sided) ModuleScripts from the (Server-Sided) Studio Command line create a replica of the (Server-Sided) ModuleScript, while requiring it anywhere else (Also from the Server Side), including the f9 command line, does not?

Things to be kept in mind

  • I am completely aware that different versions of a module script existing is expected behavior IF you require it from the server, and require again from the client. This is never the case, as my example Module is in ServerScriptService. The issue described here arises only when requiring a module using the Studio Command Line. In the issue described here, the module is always required by the server. The client is not involved in this issue, therefore the client and its replication are irrelevant to the topic.
  • I am also completely aware that the Studio has two command lines, one for running server sided code, and one for running client sided code. The issue described arises when running server sided code, and once again, the client is not involved. As a matter of fact, the debug lines presented here would not even run if they were to be executed in the client, as it cannot access the module that is in ServerScriptService.

Thanks in advance!

It doesnt quite “create a replica”
It just runs it in a different environment ( aka “sandboxed” mode (has nothing to with new sandboxing features).
Im not aware if it was intentional or not, but you just have to remember that testing modules in CommandLine its not a good idea.

Instead I usually set up a unit tests or just use “Cmdr” and add custom commands to work with the module.

2 Likes

That must be the reason why using the f9 Command Line in the game itself works, and Studio Doesn’t. I was unaware that it ran on a different environment, could you perhaps elaborate on that behavior if possible?

Additionally, should I be concerned about the way I am utilizing my modules to store relevant player information, or does the issue arise only from the usage of the Studio Command Line and my player info storage solutions are fine?

Finally, what should I be aware of when running code using the Command Line? Given that it fails at such a simple task as helping debug my modules in the manner described in my topic, what else should I be aware of and in what cases should I be wary when using the Studio Command Line?

While Command Line have access to directly change properties of objects in game, it does not work well with Module Scripts. You just have to kinda remember that.

Dont worry about that at all, the way you work with modules is fine. Its just how Command Line works in Studio.

dont try to use it that much, because any changes made in Command Line cant be reverted with Ctrl+Z, For example if you trying to weld all parts in the model using command line and you messed up, you cant do anything about it, at all.

1 Like

Becouse its like using client
there is 3 contexts (actually meight be 4 if count roblox internals)

  • Client
  • Server
  • Plugins (command bar included)

So essentially its the same behavior as if calling client module on the server if it makes sense.

That makes sense and I will keep it in mind. Thanks!
Godspeed, Fellow Dev!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.