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.