Textbox as in-game code runner

It always duplicate… that’s why look my video.

It only duplicates in Studio :slightly_smiling_face:

Oh only on studio? So if in-game it’s not gonna duplicate?

Yes.

is there a way that studio also doesn’t duplicate?

It is a bug.

Why do you bind to LogService?

You should replace print with another function that adds a line of text to the output GUI.

I’m not 100% sure how to do it and I can’t verify it, but your options are:

  1. Use setfenv to replace the loaded function’s environment with one that contains a different print function;
  2. Prepend code to the function that replaces print with something else before the user’s code runs.

What??? How to do it… hmm? I don’t know what do you mean.

So is this just a virtial script interface?

Both of these options are a billion trillion times simpler and more reliable than whatever you were doing above this.

Normally print() will output a message to the log, which you can get with LogService.
I suggested replacing print with something that outputs to the GUI directly instead of the log.
e.g.

function print(...)
	local messages = {...}
	-- convert each argument to string
	for i, message in ipairs(messages) do
		messages[i] = tostring(message)
	end
	-- show the result in a textlabel
	local TextLabel = game.ReplicatedStorage.Output:Clone()
	TextLabel.Text = table.concat(messages, "\t")
	TextLabel.Parent = Player.PlayerGui.NC.Output.ScrollingFrame
end

The first option was to replace the environment of the function.

local env = {
	print = print, -- the print function from above
	Player = Player, -- the player that ran this code
	game = game, -- you'll have to add a LOT of stuff here
}

local func = loadstring(YOUR_CODE_HERE)
setfenv(func, env)
func()

The second option was to add code that runs before your user’s code.
This is a lot less reliable, though. In fact, it’s very poor form, but still better than reading the console.

local preamble = [[
local Player = ]] .. Player:GetFullName() .. [[

function print(...)
	local messages = {...}
	-- convert each argument to string
	for i, message in ipairs(messages) do
		messages[i] = tostring(message)
	end
	-- show the result in a textlabel
	local TextLabel = game.ReplicatedStorage.Output:Clone()
	TextLabel.Text = table.concat(messages, "\t")
	TextLabel.Parent = Player.PlayerGui.NC.Output.ScrollingFrame
end

]]

local func = loadstring(preamble .. YOUR_CODE_HERE)
func()

Well is like roblox studio command bar or script runner but in-game.

How to use the first option tho?

I know the point of option 2, but like you said it’s less reliable as option 1. So how to use option 1?

But second option I try and it says attempt to index nil with robloxjw02 ← my username

That’s what I meant by ‘less reliable’. It’s generating code that tries and fails to get game.Players.

How to use the first option tho?

You just use setfenv(func, environment) to change the environment of a function to another table.

has an example of this.

I’m not sure how you couldn’t get the first one to work if you could make the second one run and show an error.

local RemoteEvent = game.ReplicatedStorage.Test

--local Modules = game.ReplicatedStorage.Loadstring

--local LogService = game:GetService("LogService")

local Players = game:GetService("Players")

RemoteEvent.OnServerEvent:Connect(function(Player, Text)

local preamble = [[

local preamble = [[

local Player = ]] .. Player:GetFullName() .. [[

function print(...)

local messages = {...}

-- convert each argument to string

for i, message in ipairs(messages) do

messages[i] = tostring(message)

end

-- show the result in a textlabel

local TextLabel = game.ReplicatedStorage.Output:Clone()

TextLabel.Text = table.concat(messages, "\t")

TextLabel.Parent = Player.PlayerGui.NC.Output.ScrollingFrame

end

]]

local func = loadstring(preamble..Text)

func()

end)

This is my code now using your second option.

If i use the first option, where should i put the function print(…), inside ServerEvent or outside?

Ah no, your first option works. But i don’t see anything on the command bar is it because of setenv?

It works, it gives the textlabel, but it doesn’t show anything on Roblox Studio Output, is it because of SetEnv?

It doesn’t show anything on the output because it wasn’t programmed to write anything to studio output, only to the GUI.

If you want that, just make it print as well.

local realprint = print
local function print(...)
	realprint(...)
	local messages = {...}
	-- convert each argument to string
	for i, message in ipairs(messages) do
		messages[i] = tostring(message)
	end
	-- show the result in a textlabel
	local TextLabel = game.ReplicatedStorage.Output:Clone()
	TextLabel.Text = table.concat(messages, "\t")
	TextLabel.Parent = Player.PlayerGui.NC.Output.ScrollingFrame
end