InstanceDataStore-V2 (PRE-UPDATE) | Save any instance easily

InstanceDataStore-V2

View github repro


Always wanted to create a building game? A sandbox game? If you did then you might though already in the beginning on this question: “How can I save instances?”.

And this is not easy, you can not simply write SetAsync(workspace) or SetAsync (anyOtherInstance), that is exactly why I made this. You can do exactly that with this module!


Features

  • Save any instance (the size of the instance does not matter)
  • Fast loading and saving (without lags (when you configurate the speed correctly))
  • Configurable (add animations, async loading and saving …)
  • Saving attributes
  • Efficient saving

For example, it can easily save things like that:


(These objects in the image are free models and not made by me)


That sounds great but I wanna see an example

Example

In this video, it serialized and saved it, deleted it and loaded it again in a really short time.

(These objects in the video are free models and not made by me)


Stats

  • 4130 parts
  • 3-4
  • ~ 34 lines code
  • Only 390652 characters

Documentation

It is recommended that you already can use the DataStoreService.

You can view the documentation here

Information

    Services

    Services can not be created so only the content of the service can be saved and loaded to the service.
  1. Saving

    Saving player data with game:GetService("Players").PlayerRemoving will not work in roblox studio because the game closes before it completes the saving procces.

    (Infinity yielding bug by roblox)

    Please try it in game and also I recommend using game:BindToClose, more information here, and for testing in studio (you can find that out with RunService), I simply recommend you implementing auto-saving. But you can also implement autosaving for the normal game too.

    Read here more about saving player data per se https://developer.roblox.com/en-us/articles/Saving-Player-Data.

    More information on the FAQ page


How can I install it?

View instructions on how to install it here.

Licence

It is under the GNU Affero General Public License v3.0 (GNU AGPLv3).
Read more: GNU Affero General Public License v3.0 | Choose a License


22 Likes

Awesome! I think it would be cool to implement this with ProfileService so that you have session locking or create your own implementation, especially since the save time is significantly longer than simply saving already serialized values.

9 Likes

I would love to use this but I do agree with @twinqle’s reply. I use profile Service and it would be great if you can integrate it with your module so there would be duplication of instances.

I am currently working on an implementation to ProfileService and I will make my own version too. It will maybe take some time because I never used ProfileService and also because I do not have a lot time.

2 Likes

Can you make any tutorial because nothing worked yet

What did not work, could you give me the error message please? Also there is a documentation that explains how to use it.

In order to use it you must enable “Enable Studio Access to API Services” (like for normal datastores too) and you should also allow http requests.



Here are some examples:

Example scripts
local serverStorage = game:GetService("ServerStorage")
local tweenService = game:GetService("TweenService")

require(serverStorage.InstanceStore.InstanceDataStore).implement()

local dataStoreService = game:GetService("DataStoreService")

local instanceDataStore = dataStoreService:GetInstanceDataStore("Test")

local instance = workspace:WaitForChild("Pine Tree")

instanceDataStore:SetAsync("myKey", instance, {
	["Use"] = {
		["Destroy"] = true
	},
	["Animate"] = {
		["Destroy"] = function(part)
			if part:IsA("BasePart") then
				tweenService:Create(part, TweenInfo.new(1), {
					Transparency = 1
				}):Play()
			end
		end,
	},
	["Async"] = true
})

local savedInstance = instanceDataStore:GetAsync("myKey", nil, {
	["Async"] = true,
	["Hide"] = true
})

savedInstance.Parent = workspace

And here is an even more simple one:

local serverStorage = game:GetService("ServerStorage")
local tweenService = game:GetService("TweenService")

require(serverStorage.InstanceStore.InstanceDataStore).implement()

local dataStoreService = game:GetService("DataStoreService")

local instanceDataStore = dataStoreService:GetInstanceDataStore("Test")

local instance = workspace:WaitForChild("Pine Tree")

instanceDataStore:SetAsync("myKey", instance)

local savedInstance = instanceDataStore:GetAsync("myKey")

savedInstance.Parent = workspace

And I also made another example place (un-copy locked): datastoreTestPlace - Roblox

Hmm, normally this type of thing is handled by a game maker. Also, the reason why this type of module did not exist before is that it is inefficient. Saving every property for an instance will cause you to hit the 4 million bytes character limit quickly, which is why people normally just save properties that need to be saved. Example: if every block in a game is 1x1, there is no need to save that in a data store. But, maybe it would be important to save the color.

What I am saying is I can see this hitting the 4 million byte limit rather quickly, and most of the time people handle this themselves to make it efficient based on their situation.

Also, do the data store calls need to be in pcalls or no? In the example I don’t see one, but I dunno.

Yes, you should use pcalls, this is just an example.


It does so much things to minimize the size, for example from a really normal part will only get changed properties saved, every default one is ignored and it also converts the property names into numbers, so that it saves every property is incorrect.

It also “bypasses” the limit by using multiple keys if it is so big that it is needed, even 10000 parts from trees can be saved without any big problems. (6507675 characters long, but it only taken around 5 seconds to load)

Do you have this built in? Do you have any type of retry logic or a cool down of any kind? Do you keep track of your datastore write budget?

Yes, it is built in, and it also has a cool down in it. And yes, in a lot cases should it be handled by a game maker.

Also it doesn’t say explicitly, but you can use this for any instance right? Also you can’t modify the source code of a script, it is a protected string. Also caching shouldn’t be one of your goals, profileservice does it for you

Does it work then I save something in Place1 and load it in Place2?

Can you save more than 1 instances under 1 key?

What do you mean by one instance? You can make one parent instance for all children instances. So you can save multiple instances as descendants

Ah ok, thanks.

Also, how dow you unload the data from :GetAsync()? Does it do it automatically?

It does not do it automatically, in the documentation stands how GetAsync must be used. It automatically decodes the instance into the specified parent

This is awesome! However, I have one question. Can this save/load attributes? I would really appreciate it because I have structures that need to be saved/loaded with attributes confirming what team they belong to.

Is this ready yet? ___________