Вы задали много вопросов, поэтому я постараюсь ответить на них все
Можете ли вы сохранить таблицы в хранилище данных в студии Roblox? ... мне нужно три значения по ключу. Это: строка, столбец и цвет завоеванной платформы.
Таблицы не могут быть сохранены, но если ваши данные могут быть сериализованы, вы можете преобразовать таблицу в строку, используя HttpService: JSONEncode () и обратно в таблицу с использованием HttpService: JSONDecode () .
local HttpService = game:GetService("HttpService")
local dataString = HttpService:JSONEncode({
row = 5,
column = 10,
color = "Red",
})
print(dataString)
local reconstructedData = HttpService:JSONDecode(dataString)
print(reconstructedData.row, reconstructedData.column, reconstructedData.color)
Может ли хранилище данных быть «безличным», что не обязательно связано с ID игрока в качестве ключа
Конечно, вы можете хранить информацию под любым ключом, который вы хотите. Но вы должны быть очень осторожны при выборе ключей, потому что каждый отдельный игровой сервер будет записывать эти ключи. Вот почему всегда рекомендуется указывать playerID, поскольку он является гарантированным уникальным ключом, и игроки не могут одновременно находиться на двух серверах, поэтому нет риска случайной записи двух серверов на один и тот же ключ одновременно.
Если у вас есть несколько игровых серверов, пишущих на один и тот же ключ, очень велика вероятность того, что два сервера перезапишут данные друг друга и чьи-то вещи будут потеряны.
Я хочу, чтобы данные, сохраненные во время игры, были извлечены во время игры ... Я хочу, чтобы каждый игрок имел доступ к этому хранилищу данных, когда он присоединяется или когда он обновляется.
Это не хороший вариант использования для хранилищ данных. Хранилища данных должны использоваться для постоянного хранения данных об игроках или мире, которые должны переноситься на несколько серверов. Например, подумайте о глобальной таблице лидеров, о прогрессе игры игрока или о том, насколько глубока яма, вырытая несколькими людьми (если вы хотите, чтобы эта дыра сохранялась при следующем запуске игры).
Если вы пытаетесь получить доступ к информации о состоянии игры и все еще находитесь в активной игре, вы можете просто заставить нового игрока построить свою игровую доску на основе текущего состояния. Нет необходимости сообщать об этом через DataStores.
Хороший способ обработки информации о состоянии активной игры - создать объект «GameManager» в сценарии сервера и предоставить ему полномочия в отношении изменений, происходящих в игре. А игрок забивает? Скажите GameManager, он обновит табло. Игрок присоединяется? Спросите GameManager, каково текущее состояние платформ / игрового поля.
Вы можете выполнить sh всего этого с помощью простых lua таблиц, RemoteEvents и RemoteFunctions. Мне нравится использовать ModuleScript для создания моего класса GameManager. Я бы грубо обрисовал архитектуру примерно так ...
local PlayerService = game:GetService("Players")
-- keep a list of RemoteFunctions and RemoteEvents that are fired by players when they do something
local GetState = game.ReplicatedStorage.Functions.GetState
local PlayerAction = game.ReplicatedStorage.Events.PlayerAction
-- keep a list of RemoteEvents that are fired by the GameManager when something should be communicated to the players
local StartGame = game.ReplicatedStorage.Events.StartGame
local UpdateBoard = game.ReplicatedStorage.Events.UpdateBoard
local EndGame = game.ReplicatedStorage.Events.EndGame
-- make an authority over the game state
local GameManager = {}
GameManager.__index = GameManager
function GameManager.new()
local gm = {
-- keep a list of players
teams = { "red" = {}, "blue" = {} },
-- keep a list of scores per team
scores = { "red" = 0, "blue" = 0 },
-- keep track of the board colors
platforms = {},
-- keep track of the state of the game
currentGameState = "WaitingForPlayers", --InGame, PostGame
-- as good housecleaning, hold onto connection tokens
__tokens = {},
}
setmetatable(gm, GameManager)
-- if anyone ever asks what the current state of the game is, let them know!
GetState.OnServerInvoke = function()
return gm.scores, gm.platforms, gm.currentGameState, gm.teams
end
return gm
end
function GameManager:waitForPlayers()
-- wait for players to join to start the game
while #PlayerService:GetPlayers() < 1 do
wait(5)
end
wait(5)
-- tell everyone the round is starting!
self:startNewGame()
end
function GameManager:startNewGame()
-- start listening to game events
local playerActionToken = PlayerAction:OnServerEvent(function(player, ...)
-- the player has done something, update the game state!
local args = { ... }
print("PlayerAction : ", player.Name, unpack(args))
-- if a platform was taken, alert all players so they can update their stuff
UpdateBoard:FireAllClients(self.platforms)
end)
table.insert(self.__tokens, playerActionToken)
-- assign players to teams...
-- tell all the players that the game has begun
StartGame:FireAllClients()
-- rather than code a game loop, just kill the game for now
spawn(function()
wait(30)
-- tell everyone the game is over
self:endGame()
end)
end
function GameManager:endGame()
self.currentGameState = "PostGame"
-- communicate to all players that the game is over, and let them know the score
EndGame:FireAllClients(self.scores)
-- stop accepting actions from the game and clean up connections
for _, token in ipairs(self.__tokens) do
token:Disconnect()
end
-- start the game over again!
spawn(function()
wait(30)
self:waitForPlayers()
end)
end
return GameManager
Затем в скрипте сервера просто создайте GameManager ...
local GameManager = require(script.Parent.GameManager) -- or wherever you've put it
local gm = GameManager.new()
gm:waitForPlayers()
Затем в LocalScript, попросить игроков запрашивать состояние игры, когда они присоединяются к игре ...
-- connect to all the game signals that the server might send
game.ReplicatedStorage.Events.StartGame:Connect(function(args)
-- construct the local game board
print("Game has started!")
end)
game.ReplicatedStorage.Events.UpdateBoard:Connect(function(newBoardState)
print("Board state has changed!")
end)
game.ReplicatedStorage.Events.EndGame:Connect(function(scores)
print("Game has ended!")
end)
-- request the current game state with a RemoteFunction
local GetState = game.ReplicatedStorage.Functions.GetState
local scores, platforms, currentGameState, teams= GetState:InvokeServer()
-- parse the current game state and make the board...
for k, v in pairs(scores) do
print(k, v)
end
for k, v in pairs(platforms) do
print(k, v)
end
print(currentGameState)
for k, v in pairs(teams) do
print(k, v)
end