How to make a player name shortening system?

For example I was wondering how do I detect that seiyak is seiyakido

1 Like

The issue with this is there’s infinitely many usernames and edge cases were this wouldn’t work at all.

You could look for common endings and cut them out, but there would always be a edge case, such as tido turning into t.

If you absolutely need shorter names, have the user input their own.

Edit: Sorry, I thought you mean getting seiyak from seiyakido

2 Likes

Well, I wish I could abbreviate the players’ names so I don’t have to write all of them for example

!trade seiyak instead of !trade seiyakido

But of course if there were two players that started with the one described for example “sei” seiuwu and seiyakido the system would ignore

1 Like

Do :match()

if "seiyak":match("seiyakido") then
    print("seiyak is seiyakido")
end
2 Likes

You could iterate trough all the players in the game and compare their name to the shortened name. Here is a code example:

local shortName = "Seiyak" -- short name the player provided
shortName = string.lower(shortName) -- we are turning everything to lowercase so players dont have to use correct capitalization every time

for _,plr in pairs(game.Players:GetChildren()) do
    local fullName = string.lower(plr.Name) -- lowercase here too
    if shortName == string.sub(fullName,1,string.len(shortName)) then -- compare the first (6) characters of the players name with the (6) character string given by the player running the command to see if they match
        -- It's a match!
    end
end
2 Likes

That string.sub code just does the same as string.match. (not saying sub = match)

I believe string.match should work fine and the other approach is fuzzy search? I wouldn’t want to do some algorithm like fuzzy search though just for some small name matching anyways.

2 Likes

string.match() doesn’t do the same, if I’m looking for “Vmena” and there are two people in the game:

“AmVmena”
“Vmena”

Both of these return something for string.match, but using string.sub all we get is the second one which should be exactly what we want.

How else are you going to do it? It needs to be flexible and work for anyone in the game so you’ll need to compare it with every player in the game.

2 Likes

Did not think of that example but then instead an alternate approach is string.find() and making sure the first find is at 1. String.sub() works fine ig, this would be my approach (using this on each iterated player)

local function isabbreviation(player, searchingName)
    local beginningMatch = string.find(player.Name:lower(), searchingName:lower())
    return beginningMatch == 1 and true
end

Because the searching name

What do you mean by this? Are you suggesting that fuzzy search should be used?

2 Likes

As he stated this is for an “admin-like” system where you can do !trade username without having to type out the whole username with proper casing. As far as I’m aware there’s no better way to do this without iterating through a list of player’s names and comparing them to the short user-given version, no matter what method of string comparison you use.

2 Likes

Yeah I said that small name match like this is fine for the case.

2 Likes

Right, so what was wrong with the code I provided exactly?

2 Likes

I never said anything was wrong with it? As a matter of fact, it is perfectly usable.

2 Likes

Alright, that’s fine. I see no reason to add another line of logic though just to make sure the string you found was on the first index, that’s what string.sub was made for.

3 Likes

This is a standard thing. You have to remember to iterate through all players, note a match, then
keep going and then reject if you find another match. (You have to reject ambiguous search strings.)
eg. if someone searches for “GoOb” (yes, we :lower() everything), if we have players “goober” and
“Gooby”, then it must reject as ambiguous. Match example:
if string.find( plyrName:lower(), searchStrLower, 1, true ) == 1 then…

2 Likes