Typewriter Module review

Hello,

I would like some review for my Typewriter Module. You can find the RBXL file here. The module is inside of StarterGui.

If you would not like to download anything, here’s the bare-bones module:

--[[

// SCRIPT INFO

// pos0
// TypewriterModule
// 1/7/22
// Updated 1/8/22
// This module creates a type-writer like effect. See configurations in the CONFIG table, and see documentation below.

// DOCUMENTATION

	// FUNCTIONS:
	
	// Function typeWriter:StartTypewriter(stringToWrite):
		// Variables:
			// stringToWrite: string
			// setSpeed: number
			// effects: table
		// Description: Starts a TypeWriter, this function yields until complete.
		// Return values: Returns true after completion, returns false if failure.
		// Example use case: typeWriter:StartTypewriter("Hello, world!", 0.5, { speed = {
			{4, 13} -- Gets faster at 4, returns to normal speed at 13.
		}, reverse = true, color = Color3.new(1, 0, 0)})
	// Function printErrorMessage(message):
		// Variables:
			// message: string
		// Description: Prints out a basic error message using string.format.
		// Return values: Returns true after completion.
		// Example use case: printErrorMessage("Hello, world!")
	// Function parseEffects(effects):
		// Variables:
			// effects: table
		// Description: Parses some additional effects that don't need to be parsed in the StartTypewriter function.
		// Return values: Returns true after completion.
		// Example use case: parseEffects({ speed = {
			{4, 13}
		}, reverse = true -[ Reverses the string ]-, color = Color3.new(1, 0, 0) -[ Changes the color ]-})
	
	// EFFECTS:
		// Speed:
			// Description: This effect changes the speed from a certain character to another character, or 0 if until the end of the string.
			// Example use case: speed = {
				{4, 13}
			}
		// Reverse:
			// Description: This effect reverses the final string.
			// Example use case: reverse = true
		// Color:
			// Description: This effect changes the color of the final string.
			// Example use case: color = Color3.new(1, 0, 0) -- Changes the color to red
			
	// CONFIG TABLE:
		// gui:
			// Description: GUI where your TextLabel for the TypeWriter is.
		// speed:
			// Description: Speed of which your TypeWriter goes if setSpeed if the 2nd argument in the StartTypewriter function is not defined.
		// labelToEditName:
			// Description: The name of the TextLabel inside of your GUI for editing.
		// useVisibleGraphemes:
			// Description: This toggles the use of the MaxVisibleGraphemes for the TypeWriter.
--]]

local typeWriter = {}
local CONFIG = {
	gui = script.Parent:WaitForChild("TypewriterGui"),
	speed = 0.5,
	labelToEditName = "TypeLabel",
	useVisibleGraphemes = true
}

function printErrorMessage(message)
	print(string.format("TypewriterModule: %s", message))
	
	return true
end

function parseEffects(effects)
	if CONFIG["gui"]:FindFirstChild(CONFIG["labelToEditName"]) == nil then printErrorMessage("Could not parse effects. labelToEditName could not be found inside of gui") return false end
	for v,i in pairs(effects) do
		if v == "color" then
			CONFIG["gui"][CONFIG["labelToEditName"]].TextColor3 = i
		end
	end
	
	return true
end

function typeWriter:StartTypewriter(stringToWrite, setSpeed, effects)
	if typeof(stringToWrite) ~= "string" then printErrorMessage("Could not start type writer. stringToWrite is not type of string") return false end
	if typeof(effects) ~= "table" then printErrorMessage("Could not start type writer. effects is not type of table") return false end
	if CONFIG["gui"]:FindFirstChild(CONFIG["labelToEditName"]) == nil then printErrorMessage("Could not start type writer. labelToEditName could not be found inside of gui") return false end
	
	parseEffects(effects)
	
	for i in utf8.graphemes(stringToWrite) do
		if CONFIG["useVisibleGraphemes"] then
			CONFIG["gui"][CONFIG["labelToEditName"]].Text = stringToWrite
			CONFIG["gui"][CONFIG["labelToEditName"]].MaxVisibleGraphemes = i
		else
			local sub = utf8.graphemes(stringToWrite) - i
			local final = nil
			if effects["reverse"] ~= nil and effects["reverse"] then
				final = string.reverse(string.sub(stringToWrite, 1, i))
			else
				final = string.sub(stringToWrite, 1, i)
			end
			
			CONFIG["gui"][CONFIG["labelToEditName"]].Text = final
		end
		
		if setSpeed == nil and effects == nil then
			task.wait(CONFIG["speed"] / 10)
		elseif setSpeed ~= nil and effects == nil then
			task.wait(setSpeed / 10)
		elseif setSpeed ~= nil and effects ~= nil then
			for b,o in pairs(effects["speed"]) do
				if o[1] == nil then printErrorMessage("Could not continue type writer. Speed effects must look like this: {1, 5}, or you will get this error.") return false end
				if o[2] == nil then printErrorMessage("Could not continue type writer. Speed effects must look like this: {1, 5}, or you will get this error.") return false end
				if i >= o[1] and i < o[2] or i >= o[1] and o[2] == 0 then
					task.wait(setSpeed / 50)
				elseif i >= o[2] then
					task.wait(setSpeed / 10)
				elseif o[2] == nil then
					task.wait(setSpeed / 10)
				else
					task.wait(setSpeed / 10)
				end
			end
		end
		
		i+=1
	end
	
	return true
end

return typeWriter

Thanks,
pos0.

you didn’t need all of this complication and fanciness.

Also for configuration, users may want for different instances of the typewriter effect class to have different configurations. Use a table for argument in the constructor and assert for the existance of the elements previously chosen by you in the module config table.

I hope that helps :smiley:

1 Like