Live Update Plugin

I have spent the past few months working on a plugin so you can update your ROBLOX games without shutting down. All you have to do is install this plugin, open the place you want to live update, then enable the plugin for that particular file and publish. Then every time in the future you publish that particular place, all running game servers will detect the update and restart themselves.

It also gives you a handy “Restart Server” button you can use to reset your place. It’s essentially the same as shutting down the place and having all the players rejoin, but it takes a fraction of the time.

[size=4]But Why?[/size]
Sometimes you get really tired of shutting down that one test server and begging everyone to rejoin. And the only way ROBLOX will implement this as an official feature is if there is a working demo to show how useful it is. And teleporting is unreliable because players often end up in different servers.

[size=4]So this is for Front Page Games Right?[/size]
I advise that you don’t enable this plugin for popular games, for the simple reason that it’s likely to break with ROBLOX updates and you don’t want thousands of angry messages. The intention of this plugin is that you use it to DEVELOP your game. So please use a separate test place.

[size=4]Why Do I have to enable HttpService?[/size]
ROBLOX provides no API for getting an asset’s latest asset version ID, so I have to proxy that through another website. As soon as ROBLOX makes such an API I will gladly remove this dependency.

[size=4]But Can You Access My Place?[/size]
Nope. I never upload your place to my servers or anything like that so your secrets are safe. But if you don’t trust me, you don’t need to use this plugin.

[size=4]How It Works[/size]
Whenever you publish to one of your places, this plugin packs the entire DataModel into ServerStorage. Then there’s a server script which checks every couple of seconds to see if your place has been updated. If it has, it uses InsertService:LoadAssetVersion() to insert the latest version of the place. Then it clears the entire DataModel except for players and unpacks the newest version of your place. Once everything’s done, it re-enables all server scripts so they start running and then respawns all players.

[size=4]Players Already Present[/size]
When the server gets restarted, your server scripts will start running and there will already be players in the game. So it is necessary to loop through players. This is a good practice anyway.

function onPlayerAdded(player)
  print(player.Name, player.userId)
end
for _, player in pairs(game.Players:GetPlayers()) do
  onPlayerAdded(player)
end
game.Players.PlayerAdded:connect(onPlayerAdded)

[size=4]DataStore[/size]
If you are using the Data Store, and you want to save player data before the server gets restarted, you can set _G.OnClose to a function which will be called right before the DataModel is cleared. This will ensure that all your player data gets saved. Example code:

_G.OnClose = function()
  for _, player in pairs(game.Players:GetPlayers()) do
    savePlayerData(player)
  end
end

You don’t need to do anything like this if you are just using Data Persistence.

Known Issues:
[ul]
[li]If you add new CSG parts to your level, they won’t show up except in new servers[/li]
[li]The “Restart Server” button doesn’t work under FilteringEnabled[/li]
[li]Only changes properties which can be set by scripts. So if you check the LoadStringEnabled property of ServerScriptService, it will still be disabled in running games.
[li]Please don’t have your scripts parent themselves to nil. It will break everything because they won’t be stopped when the server restarts. Just don’t.[/li]
[/ul]

1 Like

Can’t you use the MarketplaceService:GetProductInfo() to use the “Updated”-field instead of a Http-thingy?
The only issue with that is that it’ll also detect just a change of the title or description.

Another method would be, that you use DS:OnUpdate(“PlaceVersion”,compareVersionAndReset)
Everytime a new server is started, sees it hasn’t the same version as in a StringValue in ServerStorage,
it does DS:SetAsync(“PlaceVersion”,newVersion), triggering the servers resetting.
It won’t happen by changing a description or title.

(Another method requires “Studio API Access” to be enabled, and let the plugin directly SetAsync while in studio)

But I like your system very much

[quote] Can’t you use the MarketplaceService:GetProductInfo() to use the “Updated”-field instead of a Http-thingy?
The only issue with that is that it’ll also detect just a change of the title or description.

Another method would be, that you use DS:OnUpdate(“PlaceVersion”,compareVersionAndReset)
Everytime a new server is started, sees it hasn’t the same version as in a StringValue in ServerStorage,
it does DS:SetAsync(“PlaceVersion”,newVersion), triggering the servers resetting.
It won’t happen by changing a description or title.

(Another method requires “Studio API Access” to be enabled, and let the plugin directly SetAsync while in studio)

But I like your system very much [/quote]
The problem isn’t detecting that the place was updated. As you pointed out, we could use the [tt]Updated[/tt] field of [tt]GetProductInfo[/tt]. The problem is I need the asset version id so I can use LoadAssetVersion on the latest version of the place. LoadAsset caches so once it is called once it will always return the same results.

1 Like

Just want to check- does this still work? I’d like to use it for Orb Arena