Ways to simplify this code?

I am curious to see if I can make this duplicate code into one?

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then return end
	local func = beginState[input.KeyCode]
	if func then
		func()
	end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessed)
	if gameProcessed then return end
	local func = endState[input.KeyCode]
	if func then
		func()
	end
end)

I’ve tried some ways but I’m curious to see what other options I have

3 Likes
local UserInputService = game:GetService("UserInputService")
local binds = { InputBegan = {}, InputEnded = {} }

for Event, _ in next, binds do
    UserInputService[Event]:Connect(function(input, g))
        local callback = binds[Event][input.KeyCode]
        if (callback) then callback() end
    end)
end

to be honest im not sure whether the syntax is correct or not, havent touched lua for a while

5 Likes

I’d honestly just stick to a helper function for this instead of using a loop. It keeps things readable and avoids duplicating the gameProcessed logic.

local function bindInput(event, stateTable)
	UserInputService[event]:Connect(function(input, gameProcessed)
		if gameProcessed then return end
		
		local callback = stateTable[input.KeyCode]
		if callback then
			callback()
		end
	end)
end

bindInput("InputBegan", beginState)
bindInput("InputEnded", endState)

Works fine and keeps the callbacks clean

4 Likes

This is how I would do it

local function processInput(input: InputObject, processed: boolean)
    if processed then
        return
    end

    local callback: () -> nil = beginState[input.Keycode]
    if not callback then
        return
    end

    callback()
end

game.UserInputService.InputBegan:Connect(processInput)
game.UserInputService.InputEnded:Connect(processInput)
1 Like

That actually is very clean code.

TNLO approved. :vulcan_salute:

That’s honestly a pretty rare thing to come across.

Not really a simplification, but I can offer an optimization instead.

Do note that this is only intended as a performance optimization when using --!native. On current Luau builds, the benefit comes from native compilation; without it, this pattern is generally not worthwhile for performance.

Yeah, it’s a bit hacky, but I figured I’d share it anyway.

--!strict
--!optimize 2
--!native
local SetProperty = select(2,xpcall(function():()
	(game::any)[nil]=nil
end,function():()
	return debug.info(2,"f")
end))::(ins:Instance,prop:string,val:any)->()

local GetProperty = select(2,xpcall(function():()
	return (game::any)[nil]
end,function():()
	return debug.info(2,"f")
end))::(ins:Instance,prop:string)->any

local GetService = GetProperty(game,"GetService")::(DataModel:DataModel,service:string)->Instance

local UserInputService = GetService(game,"UserInputService")::UserInputService
local InputBegan = GetProperty(UserInputService,"InputBegan")::RBXScriptSignal
local Connect = InputBegan.Connect::(RBXScriptSignal,func:(...any)->...any)->RBXScriptConnection
local Once = InputBegan.Once::(RBXScriptSignal,func:(...any)->...any)->RBXScriptConnection

local InputObject_Get: InputObject_KeyCode&InputObject_UserInputState&InputObject_UserInputType&InputObject_any
type InputObject_KeyCode = (obj:InputObject,"KeyCode")->Enum.KeyCode
type InputObject_UserInputState = (obj:InputObject,"UserInputState")->Enum.UserInputState
type InputObject_UserInputType = (obj:InputObject,"UserInputType")->Enum.UserInputType
type InputObject_any = (obj:InputObject,property:string)->any

local InputBegan_Func = function(input:InputObject,gameProcessed:boolean):()
	if gameProcessed then return end
	local func = beginState[InputObject_Get(input,"KeyCode")]
	if not func then return end
	func()
end

Once(InputBegan,function(input:InputObject,gameProcessed:boolean):()
	xpcall(function():()
		return (input::any)[nil]
	end,function():()
		InputObject_Get = debug.info(2,"f")::typeof(InputObject_Get)
	end)

	Connect(InputBegan,InputBegan_Func)
	InputBegan_Func(input,gameProcessed)
end)

Connect(GetProperty(UserInputService,"InputEnded"),function(input:InputObject,gameProcessed:boolean)
	if gameProcessed then return end
	local func = endState[InputObject_Get(input,"KeyCode")]
	if not func then return end
	func()
end)
1 Like

I might be late but I recommend you migrate to the new IAS system
Roblox no longer gives proirity to UIS


    Action.Pressed:Connect(function()
        --no if statements just code
    end)
    
    Action.Released:Connect(function()
        --no if statements just code
    end)


It’s a lot simpler in my opinion, you can see other benefits in teh documentation

1 Like

son :skull_and_crossbones: let this guy have readable code im crien

3 Likes

:gear: Official Statement from TNLØ–RDN

(The New Luau Order – Real Developers Nation)

Fact Check Status: FALSE :cross_mark:

Certified by: TNLØ–RDN Optimization Assembly :vulcan_salute:

Following an emergency benchmark session, the Assembly has determined that “readability” remains a subjective construct.

No universal unit of readability has yet been discovered.

Optimization, however, is measurable.

Therefore, under Article §3 of the Optimization Codex:

Subjective preferences shall not supersede measurable evidence.

The Assembly reminds all Developers that code is not judged by how comforting it appears to the observer, but by what it demonstrably accomplishes.

Truth before familiarity.

Benchmarks before feelings.

Optimization above all. :gear::vulcan_salute:

i cant defend you on everything son pls i cant do this

TNLO Please
My bloat is kinda homeless

Please TNLO i need this OOP

TNLO Please
My source bloat is shaving 15ns of the cold path

Please TNLO i need this long code

local function handleInput(stateTable)
    return function(input, gameProcessed)
        if gameProcessed then return end
        local func = stateTable[input.KeyCode]
        if func then
            func()
        end
    end
end

UserInputService.InputBegan:Connect(handleInput(beginState))
UserInputService.InputEnded:Connect(handleInput(endState))

This is how I would probably do it!

Well, that’s absolutely correct statement.
There are no such tools as “readabilitymeters”, so it’s impossible to apply them and get some readability value.
But hold on. We are not first here, right? There were people who developed software years before us and they’ve got experience and even have shared it as recommendations. And they suggest to write a “readable” code.

Though there’s no value for “readability”, but it still exists and affects developers performance, for example:

  • give a code that does the same in readable and unreadable forms to two same qualified developers
  • ask them to add a feature to the code or fix a bug
  • start timer
  • once the task is completed, stop the timer
  • compare difference

Speaking about code you shared here: Ways to simplify this code? - #5 by Yarik_superpro :

  • spaces are not consistent, not using spaces, like in a=2+2 makes code too dense
  • using your words this is just bloat:
    local Connect = InputBegan.Connect::(RBXScriptSignal,func:(...any)->...any)->RBXScriptConnection
    and can be simplified to
    local Connect = InputBegan.Connect
  • another bloat is:
    type InputObject_UserInputState = (obj:InputObject,"UserInputState")->Enum.UserInputState
    can be
    type InputObject_UserInputState = (InputObject, string) -> Enum.UserInputState
1 Like

Not really
Autocompletion will be worse without overloads

Auto-completion sometimes refuses to work without casting, and weird errors may appear
Although, yeah, this one specific case may be a bloat nowadays if type checking has been improved, so its old habit is dragged

Instead of “readability,” I think proper terminology would be “ease of interpretation.”
If you need to decode logic or if it’s already based on clarity
The next contributor may be the length of a code that is fair.
But the problem is that the word “readability” does not inherently include or exclude any of it
That’s why using it is a bad idea, and you should be more specific instead

1 Like

im crineee, what is thissss TwT

Used this to come up with this method

for keybind, content in next, keybinds do
	ContextActionService:BindAction(keybind, content.func, false, content.key)
end

with a module that contains all keybinds :happy2:
Making it more simplified, clear and easy to read! which was my goal!!