Making gangs which share between all game servers

  1. What do you want to achieve? Keep it simple and clear!
    So basically i’m working on gang system for my Army game, the problem is i have no idea how to share gang data between servers, i have gang name and gang type, i need to add also gang upgrades, but this later, and i need to somehow share data between ALL Experience servers
  2. What is the issue? Include screenshots / videos if possible!
    Described in 1.
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub? I tryed to find smth on youtube and devforum, but i found only info about gangs, which saves only for 1 server, and on other servers, it got created when owner joins.

Code to save(it won’t work anyways)

local GangCEvent = game.Workspace.GangsEvents.GangCEvent
local dss = game:GetService("DataStoreService")
local gangds = dss:GetDataStore("GangNames")
local gangs = {"gang1","gang2"}
gangds:SetAsync("key", gangs)
GangCEvent.OnServerEvent:Connect(function(plr, GangName, GangType)
	local newGang = {
		["GangName"] = GangName,
		["GangType"] = GangType,
		["PlayerLimit"] = 10,
		["Upgrades"] = {
			
		}
		
	}
	table.insert(gangs, newGang)
	end)	
1 Like

For now, I can give a little overview. You have 2 choices:

  1. Make a DataStore. However the saved data will only be downloaded to new servers. It’s hard to share data between already running servers with DataStoreService.

  2. Use Roblox’s MessagingService to communicate live between servers.

You can try take a look at the documentation and if you still need help transferring the data, let me know.

1 Like

Well, so i should use both of them, to save to current server and to all servers or i’m wrong?

Yeah, if you wish the same information to be available to the new servers too, this would be the best option. Another option would be to send the data frequently trough all servers, but I wouldn’t recommend it.

1 Like
	local GangCEvent = game.Workspace.GangsEvents.GangCEvent
	local dss = game:GetService("DataStoreService")
	local ms = game:GetService("MessagingService")
	local gangds = dss:GetDataStore("GangNames")
	local gangs = {""}

	GangCEvent.OnServerEvent:Connect(function(plr, GangName, GangType)
		local newGang = {
			["GangName"] = GangName,
			["GangType"] = GangType,
			["PlayerLimit"] = 10,
			["Upgrades"] = {
				
			}
			
		}
		table.insert(gangs, newGang)
		gangds:SetAsync("key", gangs)
		local MESSAGETOPIC = newGang	
		local subscribeSuccess, subscribeConnection = pcall(function()
			return ms:SubscribeAsync(MESSAGETOPIC, function(message)
				table.insert(gangs, MESSAGETOPIC)
			end)
	end)
	if subscribeSuccess then
		
		plr.AncestryChanged:Connect(function()
			subscribeConnection:Disconnect()
		end)
	end
		end)	

Well it should work, isn’t it?

1 Like

Oh, uh, not really.
First issue:
local gangs = {""} should be local gangs = {} instead. No idea why you would add an empty string there.

Second thing, you need to fill the gangs table will the already saved data. Basically:

local GetSuccess, GetError = pcall(function()
        gangs = gangds:GetAsync("key")
end)
if not GetSuccess then
        warn("Error fetching DS data!")
end

The third thing would be that you shouldn’t use SetAsync here. Why? Because you risk losing data. When several servers create new DataStore entries, they will overwrite each other. Therefore, I suggest you use UpdateAsync after you check if the DataStore is empty of not.

And I am unsure that this is the proper way to use MessagingService, but I will test myself.

1 Like
--// Variables
local GangCEvent = game.Workspace.GangsEvents.GangCEvent
local dss = game:GetService("DataStoreService")
local ms = game:GetService("MessagingService")
local gangds = dss:GetDataStore("GangNames")
local gangs
local MessagingTopic = "GangUpdateEvent"

--// Fetch saved data
local GetSuccess, GetError = pcall(function()
	gangs = gangds:GetAsync("key")
end)
if not GetSuccess then
	warn("Error while fetching the DataStore gang data: ", GetError)
	return
end

--// Receive event
GangCEvent.OnServerEvent:Connect(function(plr, GangName, GangType)
	if not plr or not GangName or not GangType then
		warn("Remote event data passing failed. Missing argument.")
		return
	end
	local newGang = {
		["GangName"] = GangName,
		["GangType"] = GangType,
		["PlayerLimit"] = 10,
		["Upgrades"] = {

		},
	}	
	
	--// Save data
	if gangs == nil then
		print("DataStore is empty, attempting to set new raw data.")
		gangs = {}
		table.insert(gangs, newGang)
		gangds:SetAsync("key", gangs)
	else
		print("DataStore isn't empty, setting new table data.")
		table.insert(gangs, newGang)
		print(gangs)
		local UpdateSuccess, UpdateError = pcall(function()
			gangds:UpdateAsync("key", function(oldData)
				return gangs
			end)
		end)
		if UpdateSuccess then
			print("Data updated successfully!")
		else
			warn("Update error: ", UpdateError)
		end
	end
	
	--// Send data
	local PublishSuccess, PublishError = pcall(function()
		ms:PublishAsync(MessagingTopic, gangs)
	end)
	if not PublishSuccess then
		warn("Error while publishing new gang data: ", PublishError)
		return
	end
end)


--// Update data on publishing from other servers
local SubscribeSuccess, SubscribeError = pcall(function()
	return ms:SubscribeAsync(MessagingTopic, function(message)
		if message.Data then
			local gangs = message.Data
		else
			warn("Couldn't receive data from subscription!")
		end
	end)
end)
if not SubscribeSuccess then
	warn("Error while updating data from other servers: ", SubscribeError)
	return
end

This is what I did and it works.

1 Like

Alright lemme test it, a second.
image
Hmm well it works i think, now i need to get players in that gang, in case i need to make an special GUI where you can see Gang Name, Gang Type, Gang Players and Gang Upgrades. Hmmm should i add another array called “Players”?

1 Like

Well idk if this good solution, or better to add special value into player, which Value is “CoolGang” for example. Or better using that:

	local newGang = {
		["GangName"] = GangName,
		["GangType"] = GangType,
		["PlayerLimit"] = 10,
		["Players"] = {
			plr.Name,
			
		},
		["Upgrades"] = {

		},
	}	

Well then i need to update Gang Players from any server, maybe by using UpdateAsync and messagingService again.

Well so i made small GUI for Your Gang GUI(It’s called like that), now last exact Problem. is to make player list and upgrades list.

Well i made an local Script initializer which should initialize gui, but it not seems to work. Here is it:

--GUI Variables
local GangInfo = script.Parent.GangInfo
local GangName = GangInfo.GangName
local GangType = GangInfo.GangType
local GangOwner = GangInfo.GangOwner
local GangLimit = GangInfo.GangLimit

local MemberList = script.Parent.MemberList

local UpgradesList = script.Parent.UpgradesList
--DSS Variables
local dss = game:GetService("DataStoreService")
local gangds = dss:GetDataStore("GangNames")
local gangs = gangds:GetAsync("key")
--Other Variables
local Player = game.Players.LocalPlayer
local PlrGang = Player.GangFolder.PlrGang
local MemberAmount = 0
if GangInfo.Visible == true and MemberList.Visible == true and UpgradesList.Visible == true then 
if table.find(gangs, PlrGang.Value) then
	local GangMain = table.find(gangs, PlrGang.Value)
	GangName.Text = PlrGang.Value
	GangType.Text = GangMain.GangType
	GangOwner.Text = GangMain.GangOwner
	for i,players in pairs(GangMain.Players) do
		MemberAmount += players
		GangLimit.Text = "Members:"..MemberAmount.."/"..GangMain.PlayerLimit
	end
	for i, members in ipairs(GangMain.Players) do
		for i,MemberLabels in ipairs(MemberList:GetChildren()) do
			MemberLabels.Visible = true
			MemberLabels.Text = members
		end
	end
	for i, upgrades in ipairs(GangMain.Upgrades) do
		for i,UpgradesLabels in ipairs(UpgradesList:GetChildren()) do
			UpgradesLabels.Visible = true
			UpgradesLabels.Text = upgrades
		end
	end
end
end

You cannot access DataStores in local scripts.

Oh well, then how i should get data from this table and send it to client?

Get in on a server script and send a remote with every gang data.

Okay let me try that. (30 lettersssssssss)