Creating potatoes

Let's begin where we left off:

function SpawnPotato(position) {
    -- We will finish this in the next step!
}

while true {
    wait(1)
    position = Vector3.new(math.random(-100,100), 100, math.random(-100,100))
    SpawnPotato(position)
}

The first step in spawning a potato is creating its model. We will create a ball with a mesh applied to it that looks like a potato. For this, we can use the Instance.new() function.

function SpawnPotato(position) {
    newPotato = Instance.new("Part", workspace)
    newPotato.Shape = "Ball"
    newPotato.Position = position
    newMesh = Instance.new("SpecialMesh", newPotato)
    newMesh.Scale = Vector3.new(1.5, 1.5, 1.5)
    newMesh.MeshId = "rbxassetid://477543051"
    newMesh.TextureId = "rbxassetid://477543054"
    Debris.AddItem(newPotato, 60)
}

while true {
    wait(1)
    position = Vector3.new(math.random(-100,100), 100, math.random(-100,100))
    SpawnPotato(position)
}

Let's break it down:

  • newPotato = Instance.new("Part", workspace.Potatoes) creates a new Part and puts it in workspace.

  • newPotato.Shape = "Ball" and newPotato.Position = position sets the new part's shape to Ball and sets its position to the position we generated.

  • newMesh = Instance.new("SpecialMesh", newPotato) creates a new SpecialMesh (part's appearance) and puts it in the part.

  • newMesh.Scale = Vector3.new(1.5, 1.5, 1.5), newMesh.MeshId = "rbxassetid://477543051" and newMesh.TextureId = "rbxassetid://477543054" set the mesh's model to be a potato.

  • Debris.AddItem(newPotato, 60) will delete the potato after 60 seconds, in case it's not picked up by anyone.

Great, now we have potatoes falling in a loop. But the potatoes can't currently be picked up. Let's fix it.

First, after the potato is created, we will need to listen to the event when the potato is touched:

function SpawnPotato(position) {
    newPotato = Instance.new("Part", workspace)
    newPotato.Shape = "Ball"
    newPotato.Position = position
    newMesh = Instance.new("SpecialMesh", newPotato)
    newMesh.Scale = Vector3.new(1.5, 1.5, 1.5)
    newMesh.MeshId = "rbxassetid://477543051"
    newMesh.TextureId = "rbxassetid://477543054"
    Debris.AddItem(newPotato, 60)
    
    event newPotato.Touched(otherPart) {
        
    }
}

while true {
    wait(1)
    position = Vector3.new(math.random(-100,100), 100, math.random(-100,100))
    SpawnPotato(position)
}

However, the Touched event is triggered when anything touches the potato, including non-players and the map, such as the baseplate. To prevent this, we can check if the potato was touched by a player's limb:

function SpawnPotato(position) {
    newPotato = Instance.new("Part", workspace)
    newPotato.Shape = "Ball"
    newPotato.Position = position
    newMesh = Instance.new("SpecialMesh", newPotato)
    newMesh.Scale = Vector3.new(1.5, 1.5, 1.5)
    newMesh.MeshId = "rbxassetid://477543051"
    newMesh.TextureId = "rbxassetid://477543054"
    Debris.AddItem(newPotato, 60)
    
    event newPotato.Touched(otherPart) {
        if otherPart.Parent:FindFirstChild("Humanoid") {
            sound = Instance.new("Sound", newPotato)
	    sound.SoundId = "rbxassetid://3125624765"
	    sound.PlayOnRemove = true
	    newPotato:Destroy()
	}
    }
}

while true {
    wait(1)
    position = Vector3.new(math.random(-100,100), 100, math.random(-100,100))
    SpawnPotato(position)
}

Let's explain how this works. A player's character is actually a model comprised of limbs and a Humanoid object which is what makes the model a character that can walk, jump, die, etc. Only characters have the Humanoid object, therefore if the touched part's parent has a Humanoid, it is a limb belonging to a character.

At the moment, the potato is immediately deleted from the game world with :Destroy() to give the effect that it was "collected", and a "Beep" sound is created and played to alert the collector about it.

Nice potatoes!

In honor of my friend NicePotato, who helped me a lot with the Powerlang project, let's add a second type of potato into our game, called the "nice potato". It will be a bigger and brighter version of the normal potato, and in the future, it will give more points to the player that collects it.

First, let's implement a 2% chance of getting a nice potato into our SpawnPotato function:

function SpawnPotato(position) {
    isPotatoNice = false
    if math.random(1,50) == 1 {
	isPotatoNice = true
    }
    
...

As you noticed, we have added a new variable isPotatoNice to the function, which is false by default, but using an if block, it has a 2% (1/50) chance of becoming true.

Now let's make the part appear bigger and brighter if isPotatoNice is true.

function SpawnPotato(position) {
	isPotatoNice = false
	if math.random(1,50) == 1 {
		isPotatoNice = true
	}
	newPotato = Instance.new("Part", workspace)
	newPotato.Shape = "Ball"
	newPotato.Size = Vector3.new(1,1,1)
	newPotato.Position = position
	newMesh = Instance.new("SpecialMesh", newPotato)
	newMesh.Scale = Vector3.new(1.5, 1.5, 1.5)
	newMesh.MeshId = "rbxassetid://477543051"
	newMesh.TextureId = "rbxassetid://477543054"
	Debris.AddItem(newPotato, 60)
	if isPotatoNice {
		newMesh.VertexColor = Vector3.new(2,2,2)
		newPotato.Size = Vector3.new(4,4,4)
		newMesh.Scale = Vector3.new(6,6,6)
		Instance.new("Sparkles", newPotato)
	}

...

Note the new if statement at the end. It will check if the potato is indeed nice, and if yes, then:

  • It will set the mesh's vertex color to 2,2,2 (essentially doubling its brightness)

  • It will increase the size of the potato by 4 times

  • It will add sparkles to the potato

By now, you should be able to see potatoes and nice potatoes rain from the sky.


But the game isn't fun without points. Let's add a system where players get rewarded points for collecting potatoes.

Last updated