Datastore realm portal game

I’m trying to make a realm game which has a function. When you complete the first realm the second opens and when its not completed yet it’s closed. But when you completed the first one, but the second not yet, the second portal is still open, but the third one is closed, since someone did not completed the other portal realm yet. Here’s what I mean from a fottage. IMG_20210222_210652

Maybe you can do it client side (so that only the player who completed it can see the portal open) but with server side checks (with a remote event) on the teleport to prevent the exploiters from jumping the others

2 Likes

That’s a great idea! But do you know how to do it? It’s not bad if you don’t.

I can try to write you a sample code if you want

Sure that would be nice, maybe you can also say what code it is. If it local or normal.

2 Likes

[script not tested]

-- server side code to put in the server script service (Script)
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local levelsDS = DataStoreService:GetDataStore("levelsDataStore")

local Event = ReplicatedStorage:WaitForChild("Portals") or Istance.new("RemoteEvent", ReplicatedStorage)
Event.Name = "Portals" -- create the event to communicate with the client and set the name

local function kick(plr)
    plr:Kick("Do not hack! :)")
end

local function getLevel(plr)
    -- learn more: https://developer.roblox.com/en-us/articles/Data-store
    local success, level = pcall(function()
        return levelsDS:GetAsync(plr.UserId)
    end)
     
    if success then
        return level
    end
    return false
end

local function UpdateClient(plr)
    local level = getLevel(plr)
    if level then
        Event:FireClient(plr, getLevel)
    end
end

Event.OnServerEvent:Connect(function(player, argument1, argument2)
    if argument1 == "update" then
        UpdateClient(player)
    elseif argument1 == "teleport" then
        if tonumber(argument2) then
            -- argument2 is the number of the portal
            if argument2 <= getLevel(player) then -- if the portal number is lower or equal to the level unlocked
                -- do the teleport (in another place if possible, using teleport service)
                -- https://developer.roblox.com/en-us/articles/Teleporting-Between-Places
            else
                kick() -- Called a portal not unlocked, hacking
            end
        else
            kick() -- Called the remote incorrectly, hacking
        end
    else
        kick() -- Called the remote incorrectly, hacking
    end
end)

--====================================================================================================

-- To set the level
-- add this script at the finish of the level (in the serverscriptservice!!!)
-- when unlocking do:
local player = --get this from your script
local function getLevel(plr)
    -- learn more: https://developer.roblox.com/en-us/articles/Data-store
    local success, level = pcall(function()
        return levelsDS:GetAsync(plr.UserId)
    end)
     
    if success then
        return level
    end
    return false
end

local levelToUnlock = 1 -- put the level to unlock
if levelToUnlock <= getLevel(player) then -- if the level is already unlocked then stop
    return false
else
    local success, err = pcall(function()
        levelsDS:SetAsync(player.UserId, levelNumber)
    end)
    
    if success then
        print("Level saved!")
    end
end

--====================================================================================================

-- client side to put in the player starter scripts (LocalScript)
local Event = ReplicatedStorage:WaitForChild("Portals")
local currentLevel = 1 -- default

local portals = {
    [1] = portal1; -- define the portals !!!
    [2] = portal2;
    [3] = portal3;
    [4] = portal4
}

local function updatePortals()
    for i=0, currentLevel, 1 do -- open all the unlocked portals
        portals[i] -- do whatever you want to open the portal
        -- tip: put the middle of the portal in the lighting and then make the script put it in the workspace
    end
end

Event.OnClientEvent:Connect(function(argument1)
    currentLevel = argument1 -- set the level unlocked
    updatePortals()
end)

for i, v in pairs(portals) do
    v.middle.Touched:Connect(function() -- when the middle of the portal is touched
        Event:FireServer("teleport", tonumber(v.Name)) -- MAKE SURE THE PORTAL NAME IS THE NUMBER OF THE PORTAL 1, 2, 3..
    end)
end

Event:FireServer("update") -- initialize

--====================================================================================================
-- if you need more help in the future: Riky47#3355 on discord

Things that might be useful to you:

Thanks for the code and help! I will use it and contact you there if there’s something wrong.

1 Like