Undo same place teleportation with clipboard using stacks

Hello developers. I am here to give another tutorial that uses stacks. To understand stacks, please go to my other tutorial at https://devforum.roblox.com/t/how-to-use-stacks/965284?u=kingschool9. Today’s tutorial will be very short but simple. I will be showing step by step instructions on how to efficiently save teleportation data using stacks with a clipboard to show previous locations.

How can this be useful?
Allow admins to go back to their last teleport if they accidentally teleport to the wrong location. It’s an undo button. What else can I say?

Step 1
To begin, please understand this tutorial uses Stacks and OOP to create a module script that has a custom player teleportation method. Ok, let’s start by opening up our Roblox studio. Open a game file. Create a new ModuleScript in ServerStorage!

Step 2
Start by creating the class code in order to set up the OOP structure. We will take a player parameter in the constructor because we want to handle the player’s teleportation. We will create our required variables Character in the constructor and finish making our class.

-- OOP boilerplate - create a class, add __index, then make a constructor
function Stack.new(player) 
	local stackVars = {}
	setmetatable(stackVars, Stack)

	stackVars.Player = player
	stackVars.Character = player.Character or player.CharacterAdded:Wait()

	return stackVars
end

Step 3
In a stack, there will be pop and push methods so lets add them. First, the pop method allows the user to remove the most recent object in the table. The code first checks if the length of the Stack is less than 0 because it would error with a stack underflow. We get the most recent object by taking the index of the length of the table which is exactly the last object. Because we are removing the object, we need to set it to nil. Once we set it to nil, the object will be collected by garbage.

-- take an object off a stack
function Stack:pop()
	assert(#self > 0, "Stack underflow")
	local output = self[#self]
	self[#self] = nil
	return output
end

Step 4
Now for the push method! We need to add to the top of a Stack so how? Well its very easy. We take the length of the Stack and we add 1 so the index will be the next available spot. We set it to the input we took as a parameter and we’re done with that. If you would like you can also let it return something.

-- put a new object onto a stack
function Stack:push(input)
	self[#self+1] = input
end

Step 5
We need a peek method so we can see what our top most object is. To do this, we will take the length of the Stack as the index. That’s it.

function Stack:Peek()
	return self[#self]
end

Step 6: stack code
Now we have the basics of a stack. Pop and push. However, if we want to make a clipboard we will also need a toString method or an iterator. That will be in the extra section however because having an iterator in a stack is against LIFO.

-- OOP boilerplate - create a class, add __index, then make a constructor
Stack = {}
Stack.__index = Stack
function Stack.new(player) 
	local stackVars = {}
	setmetatable(stackVars, Stack)

	stackVars.Player = player
	stackVars.Character = player.Character or player.CharacterAdded:Wait()

	return stackVars
end
function Stack:Peek()
	return self[#self]
end
-- put a new object onto a stack
function Stack:push(input)
	self[#self+1] = input
end
-- take an object off a stack
function Stack:pop()
	assert(#self > 0, "Stack underflow")
	local output = self[#self]
	self[#self] = nil
	return output
end
end

Step 7
Now what? First, let’s make our custom teleportation method. We need to use this because normal teleportation will not tell the class of the position. Ok I lied, you CAN but we are not. If we make our own method to handle in place teleportation, we can ensure that the stack will push the value.
Whats happening in this code is we are getting the humanoidRootPart Position of the character and saving the position whenever we teleport the character. This way, the stack will store it and allow undos.

function Stack:teleport(pos)
	local HumanoidRootPart = self.Character:FindFirstChild("HumanoidRootPart")
	if HumanoidRootPart then
		local HumanoidRootPartPosition = HumanoidRootPart.Position
		self:Push(HumanoidRootPartPosition)
		HumanoidRootPart.Position = pos
	end
end

Step 8
We did it! Teleportation is now easy! But wait, how do we undo it? Well, let’s start by creating our method. This method will call the pop method in order to get the last value. We will then set the humanoid root part position to the most recent object by using our peek method we made earlier. This method can be called multiple times and it will still work thanks to our Stack.

function Stack:undo()
	local last = self:peek()
	
	if not last then
		return false
	end
	
	self:Pop()
	local HumanoidRootPart = self.Character:FindFirstChild("HumanoidRootPart")
	if HumanoidRootPart then
		HumanoidRootPart.Position = last
		return true
	end
end

We’re done! Thanks for everything developers! Hope you enjoy this tutorial and reply with parts I messed up on or I need to change up because as you can see it’s not very detailed as I rushed to this after finishing my other tutorial. I will be posting an undo tutorial using keybinds and textboxes. As you can see this tutorial was very easy and simple to replicate. You can replicate this style to anything you want such as undoing a build action, color changes, etc.

Problems with this code

  • If the player’s character is reset, the variable also needs to be reset.

Game Example
In this game example, I will show you how to utilize what I just explained into a real game with GUIs. The game will be uncopylocked and you can see how it looks if you use a Stack to create Undos.
Click me for game link.

Extra
If you are here then that means you want to make a clipboard. Which is great! A clipboard allows you to view every single teleportation that you have ever made since the server started. Note that this method to see a clipboard is against what a Stack is about. To see a clipboard, you just loop through self. Thats it. Go to the uncopylocked place’s scripts if you still don’t know how.

4 Likes

I have correctly fixed the game link. Devforum Stack game example - Roblox
The place is uncopylocked