CDCO Chat Fork (allows RichText and more), and String/Number Utility Module

Hello!

I’ve decided I would open-source a couple modules people might find useful which are included in my game

Let me know if you encounter any issues or have any questions with any of the modules.

Chat Fork

Main features:

  • RichText in system messages (allows for fake speakers and just overall more customization)
  • Coloured chat bubbles (the old ones) based on the player’s ChatColor, which comes from their ExtraData
  • Easy to implement command usage
    • Fake command bot for successful and unsuccessful command usage
    local fakeCommandBot = require(commandModules.FakeServerBot)
    fakeCommandBot:CreateUnsuccessfulMessage('Oh no, the command failed!')
    fakeCommandBot:CreateSuccessfulMessage('Yay, the command worked!')
    

Get the chat fork here:
CDCOChat.rbxm (119.1 KB)

String/number utility module:

local module = {
	['Lerp'] = function(self, lBound, uBound, alpha) -- linear interpolation
		return lBound + (uBound - lBound) * alpha
	end;
	['Round'] = function(self, number) -- kinda redundant now that we have math.round but I wrote this function probably back in May
		if type(number) == 'number' then
			return math.floor(number + 0.5)
		else
			return number
		end
	end;
	['RoundToThousandth'] = function(self, number) -- self-explanatory
		if type(number) == 'number' then
			return self:Round(number * 1000) / 1000
		else
			return number
		end
	end;
	['Abbreviations'] = {
		'K';
		'M';
		'B';
		'T';
		'Q';
		'Qn';
		'Sx';
		'Sp';
		'O';
		'N';
		'D';
	};
	['FormatNumberToBeDisplayed'] = function(self, number: number, abbreviate: boolean) -- inserts commas or letters and abbreviates the number
		number = type(number) == 'number' and number or tonumber(number)
		assert(number, string.format('Invalid number entry: %s is type %s, expected number!', tostring(number), type(number)))
		local numberIsToBeAbbreviated = number >= 1000000 and abbreviate
		if numberIsToBeAbbreviated then
			local logged = (math.floor(math.log10(number)))
			local suffix = math.floor(logged / 3)
			local mod = ((math.log10(number)) % 3) + 1
			local stringNumber = tostring(number)
			local preComma = stringNumber:sub(1,mod)
			local postComma = stringNumber:sub(mod + 1, mod + 1)
			return string.format('%s.%s%s+',preComma, postComma, self.Abbreviations[suffix])
		else
			local numberString = tostring(number)
			local amountOfCommas = math.round(numberString:len() / 3)
			local splitString = numberString:split('')
			for i = numberString:len() - 2, 1, -3 do
				if i ~= 1 then
					table.insert(splitString, i, ',')
				end
			end
			return table.concat(splitString)
		end
	end;
	['StringPatterns'] = {
		['Integer'] = function(str: string) -- removes any characters that aren't periods and numbers, then rounds the number
			local subbed = str:gsub('[^%d%.]+', '')
			print(subbed)
			local numeric = tonumber(subbed)
			if numeric then
				return true, math.round(numeric)
			end
			return false
		end;
		['Number'] = function(str: string) -- removes non-numeric and non-period characters
			local subbed = str:gsub('[^%d%.]+', '')
			local numeric = tonumber(subbed)
			if numeric then
				return true, numeric
			end
			return false
		end;
		['Underscores'] = function(str: string) -- replaces non-whitespace characters with underscores (which I use for text that has yet to be filtered)
			return true, str:gsub('[^%s]', '_')
		end,
	};
	['FormatString'] = function(self, stringToBeFormatted, stringType) -- formats a string based on the type specified in the above table
		if self.StringPatterns[stringType] then
			local success, result = self.StringPatterns[stringType](stringToBeFormatted)
			return success, result
		end
		return false
	end;
	['UTF8Sub'] = function(self, stringToSub, i, j) -- string.sub but a single grapheme is worth 1 character (ex, if I wanted to do string.sub('≠≠≠≠', 1, 3), it would return ≠ instead of ≠≠≠, UTF8Sub returns the expected ≠≠≠
		local number = 0
		local result = ''
		for startOfGrapheme, endOfGrapheme in utf8.graphemes(stringToSub) do
			number += 1
			if math.clamp(number, i, j) == number then
				result ..= stringToSub:sub(startOfGrapheme,endOfGrapheme)
			end
			if number == j then
				break
			end
		end
		return result
	end;
}

return module
9 Likes