Help making a console

Ok so, yeah like it says in the title I need help making a custom console for my game to execute commands and such, I got the base of syntax highlighting done, but I don’t know how to make the actual console part of it, where it has the output and stuff in the actual console part, and you can execute commands through it, this is what I’m kind of basing it off of:


this is the code I have right now.

--// variables \\--

local console = script.Parent.console
local cmdbar = console.cmdbar
local output = console.output
local hotkey = Enum.KeyCode.P
local UIS = game:GetService("UserInputService")
local word = string.split(cmdbar.Text, ' ')


--// syntax & colors \\--

local syntax = {
	log = "255,0,0";
	dog = "0,255,0";
	--keyword = rgb color;
}

function insertHighlights(txt) --txt is the text you want to highlight
	txt = " "..txt.." " --add some padding because my string pattern smells
	for i,v in next, syntax do --loop through keywords
		txt = txt:gsub("%A"..i.."%A",function(x) --replace keyword with result of function
			return x:gsub(i,function(y) --remove %A and %A used to see if its a freestanding word (ig. foob wouldnt highlight)
				return "<font color=\"rgb("..v..")\">"..y.."</font>" --richtext junk 
			end)
		end)
	end
	return txt:sub(2,#txt-1) --remove padding added line #1 of function
end

function refreshOutput()
	output.Text = insertHighlights("<font color=\rgb(41, 140, 184)\> >  </font>"..cmdbar.Text)
	--i dont know how to do the rest
end

This is the UI that I have done:

1 Like

I’ve made one of these before and have had some fun with it honestly. It isn’t too difficult either which is great and it looks good.

So basing off of your script, you are updating an existing textlabel and concatenating new outputs with old outputs. I recommend veering away from this and creating a new TextLabel for each entry instead. These are easily manageable by using UIListLayouts.

A few things to change:
1- Change output to be a ScrollingFrame
2- Change output’s CanvasSize to {1,0}, {0,0}
3- Change output’s AutomaticCanvasSize to Y

Here’s how I’d do it:

local commands = {
    ['hi'] = function()
        return 'hello!'
    end;
}

local function getCommand(commandName)
    for i,v in pairs(commands) do
        if i == commandName then
            return v
        end
    end
end

local function getResult(plainText)
    -- here is where you'd determine the output
    local splitString = string.split(plainText, ' ')
    local command = splitString[1]
    table.remove(splitString, 1)
    local commandFunction = getCommand(command)
    local output = commandFunction(splitString) -- send the arguments if needed
    return output
end

cmdbar.FocusLost:Connect(function(isEnterPressed)
    if isEnterPressed then
        local result = getResult(cmdbar.Text)
        local newLabel = Instance.new('TextLabel') -- you could also just create a template and clone
        newLabel.Text = result
        newLabel.Parent = output
    end
end)
3 Likes

I did a bit of editing to your script to fit the way I wanted it, and it errors and says this when i press enter in the textbox and stuff:


my code:

--// variables \\--

local console = script.Parent.console
local cmdbar = console.cmdbar
local output = console.output
local hotkey = Enum.KeyCode.P
local UIS = game:GetService("UserInputService")
local word = string.split(cmdbar.Text, ' ')
local linenum = 0


--// syntax & colors \\--

local syntax = {
	test = "255,0,0";
	ban = "255,0,0";
	--keyword = rgb color;
}

function insertHighlights(txt) --txt is the text you want to highlight
	txt = " "..txt.." " --add some padding because my string pattern smells
	for i,v in next, syntax do --loop through keywords
		txt = txt:gsub("%A"..i.."%A",function(x) --replace keyword with result of function
			return x:gsub(i,function(y) --remove %A and %A used to see if its a freestanding word (ig. foob wouldnt highlight)
				return "<font color=\"rgb("..v..")\">"..y.."</font>" --richtext junk 
			end)
		end)
	end
	return txt:sub(2,#txt-1) --remove padding added line #1 of function
end

local commands = {
	['test'] = function()
		return 'hello!'
	end;
}

--// functions cool B) \\--

local function getCommand(commandName)
	for i,v in pairs(commands) do
		if i == commandName then
			return v
		end
	end
end

local function getResult(plainText)
	-- here is where you'd determine the output
	local splitString = string.split(plainText, ' ')
	local command = splitString[1]
	table.remove(splitString, 1)
	local commandFunction = getCommand(command)
	local output = commandFunction(splitString) -- send the arguments if needed
	return output
end

cmdbar.FocusLost:Connect(function(isEnterPressed)
	if isEnterPressed then
		local result = getResult(cmdbar.Text)
		local newLabel = Instance.new('TextLabel') -- you could also just create a template and clone
		newLabel.TextColor3 = Color3.new(1, 1, 1)
		newLabel.Text = insertHighlights(result)
		newLabel.Name = "line "..linenum + 1
		newLabel.BackgroundTransparency = 1
		newLabel.Parent = output
	end
end)
1 Like

Try making an if statement to check if something was returned,

    local commandFunction = getCommand(command)
    if commandFunction then
    	local output = commandFunction(splitString) -- send the arguments if needed
	    return output
    end
1 Like