How to make a functional level browser

I am making a level editor in my game.
This is the script inside the level editor place inside the ServerScriptService:

local joinMessage=" has joined! Welcome!"
local chatMessageRemoteEvent=game.ReplicatedStorage.ChatMessage

local publishMessage="If you want to cancel publishment please say :cancel, if you want to proceed say your map name in the chat instead"
local cancelMessage="You have succesfully cancelled publishing"
local successMessage="Your map has succesfully been published"
local error1Message="Your map is not complex enough"
local error2Message="Please wait until you can publish another map"
local error3Message="Your map name has been filtered. Please try again with a different, non-rule breaking name"

function messages(plr)

	local stage=0
	-- fire all clients chatMessageRemoteEvent with the message and the color green
	chatMessageRemoteEvent:FireAllClients(plr.Name..joinMessage,Color3.new(0, 255, 0))

	plr.Chatted:Connect(function(msg)
		if plr.UserId==owner then
			if msg == ":publish" and stage==0 then
				chatMessageRemoteEvent:FireAllClients(publishMessage,Color3.new(255, 255, 0))
				stage=1
			elseif msg == ":cancel" and stage==1 then
				chatMessageRemoteEvent:FireAllClients(cancelMessage,Color3.new(255, 255, 0))
				stage=0
			elseif stage==1 then

				local mapName=msg
				-- lets filter the mapName
				local success, filteredMapName = pcall(function()
					return game:GetService("Chat"):FilterStringAsync(mapName,plr,plr)
				end)
				if success then
					if msg==mapName then
						print("same")
						local objects=workspace.Spawned
						if #objects:GetChildren() < 10 then
							stage=0
							chatMessageRemoteEvent:FireAllClients(error1Message,Color3.new(255, 0, 0))
						else
							stage=2
							chatMessageRemoteEvent:FireAllClients(successMessage,Color3.new(0, 255,0))
						end
					else
						print("not same")
						chatMessageRemoteEvent:FireAllClients(error3Message,Color3.new(255, 0, 0))
					end
				else
					chatMessageRemoteEvent:FireAllClients("Error filtering the map name, please try again.",Color3.new(255, 0, 0))
				end
			end
		else
			chatMessageRemoteEvent:FireAllClients("Only the owner of this server can publish their map.",Color3.new(255, 0, 0))
		end
	end)

end

game.Players.PlayerAdded:Connect(messages)

Now when I actually publish the level… how do I do that? I want in the main game place there to be a button where you can load a level by going into a level browser, with a scrollingFrame that shows the most popular levels and a search bar to search for levels.

How do I store the level? Like how do I get all the published levels and display them?

This is how I load levels if that matters:

local dataStore = game:GetService("DataStoreService"):GetDataStore("MapSave"..number) -- The data store service, and the data store we wanna use
		local player = script.Parent.Parent.Parent -- The player that is saving the data
		local data -- We will define the data here so we can use it later, this data is the table we saved
		local success, err = pcall(function()
			data = dataStore:GetAsync(player.UserId) -- Get the data from the datastore
		end)
		--now lets check if the data has been loaded
		if success then -- If the data has been loaded
			if data then -- And if the data isn't empty
				local dataToSend={} -- no strings!
				dataToSend.mapName=data[1]
				dataToSend.data=game:GetService("HttpService"):JSONDecode(data[2])
				print(dataToSend)
				loadMapFromData(dataToSend.data)
				print("Data has been loaded!")
			else
				print("No data found!")
			end
		else
			print("Data hasn't been loaded!")
			warn(err)
		end

And this is how I save levels if that matters:

	local tableToSave = {
		mapName,
		data
	}

	local success, err = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save
	end)

	if success then
		print("Data has been saved!")
	else
		print("Data hasn't been saved!")
		warn(err)		
	end

This is what happens before the save function:

table.clear(Current_data)
	local spawnedObjects=workspace.Spawned

	for i,v in pairs(spawnedObjects:GetChildren()) do
		if v:IsA("BasePart") then
			local object={}
			object.N_=v.Name
			object.C_=v.ClassName
			object.CF_={v.CFrame.Position.X..","..v.CFrame.Position.Y..","..v.CFrame.Position.Z,v.Orientation.X..","..v.Orientation.Y..","..v.Orientation.Z}
			table.insert(Current_data,object)
		elseif v:IsA("Model") then
			local object={}
			object.N_=v.Name
			object.C_=v.ClassName
			object.CF_={v.PrimaryPart.Position.X..","..v.PrimaryPart.Position.Y..","..v.PrimaryPart.Position.Z,v.PrimaryPart.Orientation.X..","..v.PrimaryPart.Orientation.Y..","..v.PrimaryPart.Orientation.Z}


			table.insert(Current_data,object)
		end
	end

	local dataStore = game:GetService("DataStoreService"):GetDataStore("MapSave"..number) -- The data store service, and the data store we wanna use
	local data = game:GetService("HttpService"):JSONEncode(Current_data) -- The data we wanna save, in this case, the Current_data table
	local player = script.Parent.Parent.Parent -- The player that is saving the data

	-- lets filter the currentMapName text, so there isnt anything innapriopriate
	local nameOfMap=filterCurrentMapName()
	currentMapName=nameOfMap

	saveData(currentMapName, data, player, dataStore) -- Call the saveData function
1 Like

If yall need more info please let me know as I don’t know if I included everything that is needed to solve this issue. Thanks.

1 Like

What exactly can make the level popular? Visits? Likes?

2 Likes

I think im gonna make it like based and you can only like a level once

I added 2 more parts of scripts so it can maybe help

1 Like