Save models in datastores

We have this old SaveInstance() function but it’s deprecated so I’m wondering if we can get it for datastores.

It’d use the same super-efficient saving format (binary-something?) and it’d make a lot of things easier for us developers. I’ve made maybe 4 individual games where I saved entire models using just 6 characters (X,Y,Z Rotation, Name Index) but it doesn’t work so well when I let players build complex structures out of 1x1x1 bricks where I can run into a lot of issues quickly with joints, states, custom data (density, power, etc…) which would eat up my save size quite quickly.

I’d like to get a SaveInstance() type of thing for DataStores where we can put a single instance tree in and get it back whenever we want.

10 Likes

No matter how efficient roblox makes a SaveInstance implementation it’s going to be less efficient than you could do on your own.

5 Likes

What constraint would prevent roblox from implementing it efficiently?

ROBLOX has to save the complete object. As a developer, I can say “Oh, I know this model is made up by 5 wood_blocks and all I have to store is an integer ID for wood_blocks and their CFrame”. You already know what a wood_blocks is, so you don’t need to store it again in the DataStore.

5 Likes

It would be stored using the same datastore methods the developers can use, as in they will only be able to use 128 characters to serialize the instances just like you. And roblox doesn’t know specific implementation details that the developer can use to optimize. For example scripton’s parts are all 1x1x1 so he doesn’t need to save size. Presumably he also doesn’t need to save surface types or parameters. Since they’re on a grid he can save their position as a cell index instead of 3 explicit axes. He doesn’t need to store rotation data either.

1 Like

It may be handy, but if “efficiency” is the only goal, it’s worthless, like everyone mentioned already.

Only “fun” thing I can think of is doing:

DS:SetAsync("huehuehue","<roblox blabla>LocalScript<Source>CODE</Source></roblox>")
-- (assuming that would be valid .rbxmx, which it definitely isn't, but you get the idea)
local ls = DS:GetInstanceAsync("huehuehue")
-- huehuehue, got a LocalScript with the Source we want

but obviously that’s not what this feature should be used for.

@ScriptOn for your problem, you could learn (a bit) from how MC saves things. I don’t know the details, but it would be something like your 6-character format followed by custom data, e.g. joints. For referencing an object, you can just use the index of the position the referenced object appears in the 6-format-string (divided by 6, if you were thinking string.sub-wise). Other things are also “easy” to implement, it’s just a lot of work in the beginning for figuring out a good format. (could even go all-out and add reusing of vectors, states, … and compress in other ways)

Roblox has up-to-date access to the reflection metadata, unlike us, so it would be more efficient for Roblox to implement something like this.

Why would that matter? The only thing Roblox could do that we can’t is start saving new properties the moment they’re out. If we use a custom format (that doesn’t save that property), it just means that property doesn’t interest us (yet).

2 Likes

I guess.

This is exactly why I want to just save the model. I think it’s a bit too much work when developers have to come up with gamecube-era compression algorithms just to save something decently complex. I really liked the old SaveInstance feature we used to have 4(?) years ago.

I’ll be able to split this up into multiple datastores if needed quite easily, but that’s extra calls that we wouldn’t have to make (or wait for).

Btw for anyone looking to save integers more efficiently, try converting to a higher base. You’ll be able to store more information per character.

1 Like

Is 10 the most efficient for my 1x1x1 voxels? I save 0/90/180/270 rotations as 0/1/2/3

Base 10 is probably fine for your rotations if you’re using enums (of values 0-9), but you could probably store positions in something a bit higher like hex to get it down to a single character per axes. Another good idea might be to do a position indexing system like @Sharksie mentioned.

If you had a XYZ coordinate or position index of 1492 (base 10) that could be converted into) 5D4 (base 16 / hex). While you’re only saving one character in this case, you’ll get better returns with higher bases and bigger numbers.

I’m saving vehicles. Making one that’s more than just 50-units away from 0,0,0 is probably going to be impossible.

I’m a little confused. Wouldn’t I be saving XYZ? Meaning that the highest value they’d get to is 50,50,50 so I’d never have to save the number ‘125000’

Not 100% understanding it but it looks pretty neat.

I’m trying to keep it simple because it’s going to get really complicated really fast with joints as well as their properties.

Note: Below, I always use the notation (x,y,z) as I’m too lazy (and don’t have enough space) to add Vector3.new in front of it. (and adding that would in some cases of pseudo-code look very weird)

He means that you do one of those 2 options:

  • Have an array with all possible positions
    {(0,0,0),(0,0,1,),...,(50,50,50)}
    for x=0,50 do for y=0,50 do for z=0,50 do table.insert(array,(x,y,z)) end
  • Use some algorithm that represents X,Y and Z in one number
    num = (X*50+Y)*50+Z thus (1,2,3) = 2603
    X,Y,Z = math.floor(num/2500),math.floor(num%2500/50),num%50
    e.g. X,Y,Z = math.floor(2603/2500),math.floor(2603%2500/50),2603%50 = (1,2,3)

Both result in a number, which points to one value. For the first, it’s the index of that table, for the second, it’s the number from that equation. In this example, both numbers would be the same, except for 1 off. (e.g. (0,0,0) is thatTable[1] and 0 in the equation, while (1,2,3) is 2604|2603)

Like I said, it’s a bit of work, but in the end, it’s (probably) the most efficient.

Serializing entire models sounds like a weird way of doing a game. I’d just have prefabs with properties. Could easily save these in a manner that would be much more efficient than serializing a model.

Example: A game were you build stuff. You probably don’t care about any property except for size, color and material.