Script builders like that tend to either catch, or redirect script output. Additionally, script builders use tons of sandboxing for security. I wrote a fairly advanced module (usage-wise, the concept is not super complicated however, hence why I plan on rewriting the tool) for that purpose as well, but, if you only intend to execute code from specific people, like yourself, that likely isn’t necessary.
As for actual code input, most SBs tend to use a lua parser to parse code into something that’s easy to work with, then they can color the code with that information (I believe with the new upcoming RichText feature this will be much, much easier when it’s fully featured).
Catching output
Catching output can be done through certain Roblox services, primarily LogService, which shows all output, and or ScriptContext.Error which only captures errors from non corescripts, however, provides a ton of extra information.
ScriptContext.Error is primarily used in SB games to collect errors from additional threads. Since ScriptContext.Error reports the script that the error was created by.
Redirecting output
Redirecting output is a lot simpler and is what most script builders do, and, its really just as easy as replacing print
, warn
, error
, and assert
for the code you are running, and, for example, pcalling
the returned loadstring function. This will allow you to capture any output.
The print
/warn
functions can basically be rewritten in lua-form like this:
local function print(...)
local arguments = table.pack(...)
for index=1, arguments.n do -- Note: I intentionally do this here since nil arguments would leave holes in the array (and it wouldn't loop over them with ipairs or pairs), n is from table.pack
arguments[index] = tostring(arguments[index])
end
local stringOutput = table.concat(arguments, " ")
someRawPrintCode(stringOutput)
end
local function warn(...)
local arguments = table.pack(...)
for index=1, arguments.n do -- Note: I intentionally do this here since nil arguments would leave holes in the array (and it wouldn't loop over them with ipairs or pairs), n is from table.pack
arguments[index] = tostring(arguments[index])
end
local stringOutput = table.concat(arguments, " ")
someRawWarnCode(stringOutput)
end
In this case, someRawPrintCode
is just a placeholder for whatever code is used to actually output the string. So, really, if you want to make modifications to the print
/warn
functions you might want to call the real print/warn function. (e.g. realPrint(...)
or realPrint(stringOutput)
).
At this point, you can really use the outputs however you’d like.
Conclusion
Hopefully this all is useful to you (or others), I’ve spent a decent bit of time writing this up. And again, unless you’re experienced, allowing anyone to run code (beyond yourself and maybe a few other of your game’s developers or something) can be fairly dangerous because it can basically give anyone access to your game if not done correctly. It’s best to stay away from it unless you’re experienced (hence why I wrote the tool I mentioned to make the process at least a decent bit less difficult by providing tools for sandboxing code).