If name contains certain word (like string.find but names)

so, any ideas? not sure what to do about this one…

local vehiclesLocation = {
    "428toyotacamry",
    "751chevroletcamaro",
    "136bugattiveyron"
}

Let’s start with the above; assume that vehiclesLocation is reffering to where all the cars will be stored (in perhaps a folder in workspace). So in the code, you won’t need to actually create this table; it’s only for vanilla Lua testing purposes.

What do you do when you want to make a new serial? I’ve thought about it and decided that math.random(100, 999) should work well. Why 100 to 999 you ask? Because all of the possible numbers generated will have 3 digits in them; it’ll make things much easier. Then to actually generate a string of the name of the plane/vehicle you’re spawning in, I’ve made this function:

local function getNewSerial(vehicleName)
    local newSerial = math.random(100, 999)
    local alreadyUsed = false

    for i, v in pairs(vehiclesLocation) do
        if newSerial == tonumber(string.sub(v, 1, 3)) then
            alreadyUsed = true
            break
        end
    end

    if alreadyUsed == false then
        return tostring(newSerial) .. vehicleName
    else
        return getNewSerial(vehicleName)
    end
end

The getNewSerial function should generate a random number between 100 and 999, then check if it’s already being used; if it is, it will recursively call itself to generate a number once again. Once it has a unique serial number, it will return the number and the name together in a single string (to be used for the name of the model). Keep in mind, where it says vehicleLocation you’ll want to replace it with something along the lines of, folderWhereCarsAre:GetChildren(). After that, you’ll also want to replace where it says v with v.Name instead.

Here’s example usage of the function:

local newName = getNewSerial("BlueFighter")
newlySpawnedPlane.Name = newName

Let me know if there’re any questions.

Here’s how i incorporated it into the old script:

local vehiclesLocation = {
}
local function getNewSerial(vehicleName)
	local newSerial = math.random(1, 5)
	local alreadyUsed = false

	for i, v in pairs(vehiclesLocation) do
		if newSerial == tonumber(string.sub(v, 1, 3)) then
			alreadyUsed = true
			break
		end
	end
	if alreadyUsed == false then
		return tostring(newSerial) .. vehicleName
	else
		return getNewSerial(vehicleName)
	end
end

db1 = true
function regenerate()
if not db1 then
	return
else
	db1 = false
		local Vehiclesinspawn = script.Parent:GetChildren()
		for i, v in ipairs(Vehiclesinspawn) do
			if string.match(v.Name, "BlueFighter") then
				if (v.PlaneSeat.CFrame.p-Spawn.CFrame.p).magnitude <= Range then
					v:Destroy()
				end
			end
		end
		Vehicle = OldVehicle:Clone()
		local newName = getNewSerial("BlueFighter")
		Vehicle.Name = newName
		Vehicle.Parent = script.Parent
		Vehicle.Values.Owner.Value = script.Buyer.Value
		local regentime = 0
		regentime = 15

However i did a test between 1 and 5, and of eight attempts i got (1x1, 2x1, 3x0, 4x1, 5x3) so the serials are the same on a chance. Why?

edit: I think it’s because the vehicles don’t get put into vehiclelocation. How should i put them there

You keep getting the same serial numbers?

My bad; I believe this has to do with how math.random() works. When you want to generate a pseudorandom number using it, you need to use math.randomseed(seed). In this case, a good seed would be os.time() or tick(). And think of the seed like the starting point of the pseudorandom number generator; if you give it the same starting point, it will calculate the same number over and over again.

Try simply placing math.randomseed(os.time()) at the top of your script, and let me know how it goes.

1 Like

nonono, i think your code did it correctly, its just that my script never entered the vehicle into VehicleLocation so the serials never get checked. how could i do this?

Right there I said you’ll need to replace vehicleLocation with the folder/area the vehicles are in (and use :GetChildren()), and v in the code with v.Name. Sorry if I wasn’t being clear.

So what was the issue with just checking the range of the the vehicles that have been spawned in?

Another way you could do this is with collectionservice, which I’d say is probably a more suitable solution. The issue with the random number thing you have now is that it’s not guaranteed that each name is unique. With collection service you can tag vehicles that are freshly spawned and then remove that tag when they leave spawn. You then just need to use collectionservice:GetTagged(“InSpawn”) to get the vehicle(s) that need to be destroyed.

1 Like

right so I tried that, and there are no errors, warnings, etc. everything works fine now except that i still get the same serial occasionally. Here is the code:

Really appreciate all your help thus far.

I see now; it’s because of how I designed the code to work.

if newSerial == tonumber(string.sub(v.Name, 1, 3)) then
    alreadyUsed = true
    break
end

The above code from the script is what is causing this. It’s not “wrong” per se, it’s just that it checks the first three characters with string.sub, which is meant for numbers with three digits between 100 and 999. So if it’s checking for three digits, but the number is only in the first digit, the script will never realize that it’s the same number of course. Being even clearer, it’s basically checking, “is ‘5bl’ equal to 5?” And of course it’s not. I hope it clarifies the issue.

If you’d like to test the code with digits greater than or less than three, you’ll just need to change the parameters in string.sub(). In this case with single digit numbers, here’s what you’ll want to change it to:

-- Gets the range of the first character to the first character in v.Name
if newSerial == tonumber(string.sub(v.Name, 1, 1)) then
2 Likes

I CAN’T BELIEVE I DIDN’T REALIZE THIS

regardless

this is very epic, thank you @MJTFreeTime, very cool

1 Like

It’s been a while but I think it’s necessary to clarify some misinformation:

Disproving statements without good reason can serve to be misinformation and confuse readers, and that’s likely not to be the reason it didn’t work.

All obj.Name:match(toFind) was used for in my provided (and given intentionally vague) example (it was an example model after all) was to return a boolean indicating whether an object contained the substring “bluefighter” in its name and thus whether its serial was preceded by “bluefighter” (since the only possible strings that can occur in this environment are those preceded by serials) so the object could be added to an array. If I’m not wrong that’s exactly what you asked for; to get all objects that contain in their name the specified string.

It also could’ve been that the code I provided was executed without necessary edits (e.g changing the string to match, in mine all characters were all lowercase).

Again this post was just needed to prevent potentially incorrect information, it doesn’t require a response.