Im new to scripting and im working on a username ranking system which will give a player a rank S+ - F depending on how rare their username is and im trying to figure how to make it so a player will be ranked based on if their username is a real word or not. I dont know how I would do this. This is the current code: The dictionary section was just a test and i dont plan on keeping it.
Im trying to remake this roblox games username ranking system if you want a reference:
local RankingModule = {}
function RankingModule.calculateScore(username)
local score = 10 – Baseline score
-- Length-based scoring
if #username <= 4 then
score = score + 50
elseif #username > 4 and #username <= 8 then
score = score + 30
elseif #username > 8 and #username <= 20 then
score = score + 10
elseif #username > 20 then
score = score + 40
end
-- Bonus for exactly 2 underscores
local _, underscoreCount = username:gsub("_", "_")
if underscoreCount == 2 then
score = score + 25
end
-- Unique repeated characters
local uniqueRepeat = username:match("^([%a%d_])%1+$")
if uniqueRepeat then
score = score + 50
end
-- Non-unique repetition penalty
local badRepeatPattern = username:match("(%a)(%1*)([%a%d_])(%2+)")
if badRepeatPattern then
score = score - 20
end
-- Dictionary words bonus
local dictionaryWords = {"apple", "banana", "cat", "dog", "house", "robot", "game", "builder", "world", "speed"}
for _, word in ipairs(dictionaryWords) do
if username:lower() == word then
score = score + 50
break
end
end
-- Special characters bonus (capped at 5 points)
local specialCount = username:gsub("[%w_]", ""):len()
score = score + math.min(specialCount, 5)
return math.max(score, 0)
end
function RankingModule.determineRank(score)
if score >= 126 then
return “Rank S+”
elseif score >= 95 then
return “Rank S”
elseif score >= 69 then
return “Rank A”
elseif score >= 53 then
return “Rank B”
elseif score >= 37 then
return “Rank C”
elseif score >= 21 then
return “Rank D”
else
return “Rank F”
end
end
While repetitive, this is my recommended method for finding whole words in the username for scoring:
Reorganize String:
a) create a list of words in a module (you could also use pastebin or another site, and make a HttpService:GetAsync request to the site)
a1) all words should be lowercase to save time later
b) retrieve the player’s name; use string.lower on it because capitals wont change a words spelling
c) string.split the name by “”, so that it returns a table containing the split word like {“t”, “h”, “i”, “s”}
d) with the split string, table.remove numbers and additional punctuation. I’d suggest you make a punctuation table and loop through to check if any characters match the items, then remove them
at this point, the players name should be only letters. (i.e. Roblox1234_ would become {“r”, “o”, “b”, “l”, “o”, “x”}
Perform checks
a) keep the table discussed in letters c/d as a variable, you’ll need to now make a new variable local concat = ""
b) then for _, s in splittable do concat = concat..s end
c) this will make the concat variable equal to the concatenate of the split name, or in basic terms the name as one string type.
d) now, we will loop through the module discussed in part 1, letter a. Also make a new table local results = {}
e) for _, word in module do if string.find(concat, word) then table.insert(results, word) else continue end
f) This code will check if the concat string contains any word in the list. The results table will include any cases in which a word was found.
Validity of Results
a) Now, we will need to reuse the concat and results table.
b) You may notice that the word concat contains the word concat, but also the word cat and con. Judging on how you reward score, I assume that you don’t want to give extra score because there were multiple words.
c) for this reason, we will loop through the results again, this time removing items that are irrelevant.
d) utilize table.sort(results, function(a, b) return #a > #b end) to reorder the table from longest to shortest words.
e) now, for i, s in results do if string.find(concat, s) then string.gsub(concat, s, "") else table.remove(results, i) end this code removes any and all occurrences of a word found in concat, so words cannot be repeated. If the word isnt found in concat, it is removed from results.
f) award score accordingly. A sample using a score variable already defined would be: for _, result in results do score += #result, which awards score based on the length of the result.
This code should be run when a player joins, and once a players score is calculated it should be saved into a datastore to prevent future runs. However, if their name isn’t the same when rejoining, their data should be wiped and recalculated.
Let me know if you have any questions, concerns, or issues.
local RankingModule = {}
function RankingModule.calculateScore(username)
local score = 10 -- Baseline score
-- Length-based scoring
if #username <= 4 then
score = score + 50
elseif #username > 4 and #username <= 8 then
score = score + 30
elseif #username > 8 and #username <= 20 then
score = score + 10
elseif #username > 20 then
score = score + 40
end
-- Bonus for exactly 2 underscores
local _, underscoreCount = username:gsub("_", "_")
if underscoreCount == 2 then
score = score + 25
end
-- Unique repeated characters
if username:match("^(%a%d_)(%1+)$") then
score = score + 50
end
-- Non-unique repetition penalty
if username:match("(%a)(%1*)([%a%d_])(%2+)") then
score = score - 20
end
-- Dictionary words bonus
local dictionaryWords = {"apple", "banana", "cat", "dog", "house", "robot", "game", "builder", "world", "speed"}
for _, word in ipairs(dictionaryWords) do
if username:lower() == word then
score = score + 50
break
end
end
-- Special characters bonus (capped at 5 points)
local specialCount = username:gsub("[%w_]", ""):len()
score = score + math.min(specialCount, 5)
return math.max(score, 0)
end
function RankingModule.determineRank(score)
if score >= 126 then
return "Rank S+"
elseif score >= 95 then
return "Rank S"
elseif score >= 69 then
return "Rank A"
elseif score >= 53 then
return "Rank B"
elseif score >= 37 then
return "Rank C"
elseif score >= 21 then
return "Rank D"
else
return "Rank F"
end
end
return RankingModule
Just a tip, the elseif statements are redundant as the first checks if its less or equal to 4 then the next checks that its more than 4 which has to be to case 100% of the time, meaning you only need to check less or equal to 8.
Also unless done intentionally, you can write score += 123 instead of score = score + 123 if prefered, as it’d do the same thing