Is this a good way to implement tutorial input checks?

What does the code do and what are you not satisfied with?
Checks if the W, A, S, and D keys pressed when inputbegan is called with the progress variable set to 1 (tutorial)
What potential improvements have you considered?
Using some sort of dictionary, though I’m unsure as to how I would implement that.
How (specifically) do you want to improve the code?
Have the tutorial input check be more optimized and waste less space

Relevant Code:

local STORAGE = game:GetService("ReplicatedStorage")
local INPUT = game:GetService("UserInputService")
local SOUND = game:GetService("SoundService")
local RUN = game:GetService("RunService")
local ui = workspace:WaitForChild("screen"):WaitForChild("g")
local progress = {0}
local movecamera = false
local keyboardgaming = false
local onsides = {false,false,false,false}
local sides = {}

local function write(obj: Instance,speed: number)
	for x = 1,#obj.ContentText - 1 do
		obj.MaxVisibleGraphemes = x
		task.wait(speed)
	end
	
	obj.MaxVisibleGraphemes = -1
end

local function resetsides()
	local function fromscale(X,Y)
		return Vector2.new(math.floor(X * workspace.CurrentCamera.ViewportSize.X),math.floor(Y * (workspace.CurrentCamera.ViewportSize.Y + 36)))
	end

	sides[1] = {fromscale(1,0.1),Vector2.new(0,0)}
	sides[2] = {fromscale(0.1,1),Vector2.new(0,0)}
	sides[3] = {fromscale(1,0.1),fromscale(0,0.9)}
	sides[4] = {fromscale(0.1,1),fromscale(0.9,0)}
end

resetsides()

workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(function()
	resetsides()
end)

workspace.CurrentCamera:GetPropertyChangedSignal("CameraType"):Connect(function()
	workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable
	workspace.CurrentCamera.CFrame = CFrame.new(0,0,0) * CFrame.Angles(0,math.rad(180),0)
end)

workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable
workspace.CurrentCamera.CFrame = CFrame.new(0,0,0) * CFrame.Angles(0,math.rad(180),0)

INPUT.InputBegan:Connect(function(key)
	if movecamera then
		if INPUT.KeyboardEnabled and keyboardgaming ~= nil then
			if key.KeyCode == Enum.KeyCode.W then
				keyboardgaming = true
				onsides[1] = true
				
				if progress[1] == 1 and not progress[2][1] then
					progress[2][1] = true
					ui.txt.Text = [[<font color="#ffffff">W</font>,<font color="]] .. (progress[2][2] and "#ffffff" or "#ffff64") .. [[">A</font>,<font color="]] .. (progress[2][3] and "#ffffff" or "#ffff64") ..  [[">S</font>,<font color="]] .. (progress[2][4] and "#ffffff" or "#ffff64") ..  [[">D</font> to move your camera]]
				end
			elseif key.KeyCode == Enum.KeyCode.A then
				keyboardgaming = true
				onsides[2] = true
				
				if progress[1] == 1 and not progress[2][2] then
					progress[2][2] = true
					ui.txt.Text = [[<font color="]] .. (progress[2][1] and "#ffffff" or "#ffff64") .. [[">W</font>,<font color="#ffffff">A</font>,<font color="]] .. (progress[2][3] and "#ffffff" or "#ffff64") ..  [[">S</font>,<font color="]] .. (progress[2][4] and "#ffffff" or "#ffff64") ..  [[">D</font> to move your camera]]
				end
			elseif key.KeyCode == Enum.KeyCode.S then
				keyboardgaming = true
				onsides[3] = true

				if progress[1] == 1 and not progress[2][3] then
					progress[2][3] = true
					ui.txt.Text = [[<font color="]] .. (progress[2][1] and "#ffffff" or "#ffff64") .. [[">W</font>,<font color="]] .. (progress[2][2] and "#ffffff" or "#ffff64") .. [[">A</font>,<font color="#ffffff">S</font>,<font color="]] .. (progress[2][4] and "#ffffff" or "#ffff64") ..  [[">D</font> to move your camera]]
				end
			elseif key.KeyCode == Enum.KeyCode.D then
				keyboardgaming = true
				onsides[4] = true

				if progress[1] == 1 and not progress[2][4] then
					progress[2][4] = true
					ui.txt.Text = [[<font color="]] .. (progress[2][1] and "#ffffff" or "#ffff64") .. [[">W</font>,<font color="]] .. (progress[2][2] and "#ffffff" or "#ffff64") .. [[">A</font>,<font color="]] .. (progress[2][3] and "#ffffff" or "#ffff64") ..  [[">S</font>,<font color="#ffffff">D</font> to move your camera]]
				end
			end
		end
	elseif progress[1] == 0 then
		progress = {-1}
		task.wait(0.25)

		ui.txt.Position = UDim2.new(0,0,0.35,0)
		local txt2 = ui.txt:Clone()
		txt2.Name = "txt2"
		txt2.Size = UDim2.new(1,0,0.15,0)
		txt2.Position = UDim2.new(0,0,0.55,0)
		txt2.Parent = ui

		ui.txt.MaxVisibleGraphemes = 0
		txt2.MaxVisibleGraphemes = 0
		ui.txt.Text = [[<font color="#ffff64">W</font>,<font color="#ffff64">A</font>,<font color="#ffff64">S</font>,<font color="#ffff64">D</font> to move your camera]]
		txt2.Text = [[or move your mouse to the <font color="#ffff64">top</font>,<font color="#ffff64">down</font>,<font color="#ffff64">left</font> and <font color="#ffff64">right</font> sides of the screen]]
		write(ui.txt,0.05)
		task.wait(0.1)
		write(txt2,0.05)
		progress = {1,{false,false,false,false,false,false,false,false}}
		movecamera = true
	end
end)

INPUT.InputEnded:Connect(function(key)
	if movecamera then
		if key.KeyCode == Enum.KeyCode.W then
			keyboardgaming = false
			onsides[1] = false
		elseif key.KeyCode == Enum.KeyCode.A then
			keyboardgaming = false
			onsides[2] = false
		elseif key.KeyCode == Enum.KeyCode.S then
			keyboardgaming = false
			onsides[3] = false
		elseif key.KeyCode == Enum.KeyCode.D then
			keyboardgaming = false
			onsides[4] = false
		end
	end
end)

INPUT.InputChanged:Connect(function(key)
	if key.UserInputType == Enum.UserInputType.MouseMovement and keyboardgaming ~= true then
		for x = 1,4 do
			if key.Position.X > sides[x][2].X and key.Position.Y > (sides[x][2].Y - 36) and key.Position.X < sides[x][1].X + sides[x][2].X and key.Position.Y < (sides[x][1].Y + sides[x][2].Y - 36) then
				keyboardgaming = nil
				onsides[x] = true
			else
				onsides[x] = false
			end
		end
	end
end)

RUN.RenderStepped:Connect(function(delta)
	local rotate = Vector3.new(((onsides[1] and 3 or 0) - (onsides[3] and 3 or 0)),((onsides[2] and 3 or 0) - (onsides[4] and 3 or 0)), 0) * delta
	
	if movecamera and (rotate.Magnitude > 0) then
		workspace.CurrentCamera.CFrame *= CFrame.Angles(rotate.X,0,0)
		workspace.CurrentCamera.CFrame *= CFrame.fromAxisAngle(workspace.CurrentCamera.CFrame:VectorToObjectSpace(Vector3.new(0,1,0)),rotate.Y)
	elseif keyboardgaming == nil then
			keyboardgaming = false
	end
end)

Solved it on my own. Turned the repeated code into a function and the rest into function arguments.