Particle order is sometimes very useful. For example, this is my ball:
It takes 4 frames to move itself once (1 frame to push the whole ball without the push part, 1 frame to use CRAY to delete that PSTN generated, 2 frames to use PSTN to pull the push part onto the ball)
With a correct particle order the whole thing can be done within 1 frame. And use CONV to make constant spark, we can even get the ball move every frame.
Particle order breaks when saved as a stamp or uploaded to the server. The particle is reordered.
Now onto the suggestion. My idea is to change the save format, and when you save a stamp or upload a simulation, it will ask 'Keep particle order?' If you keep the particle order, those things can be done with only one frame. If you don't keep the particle order. it will upload/save a smaller file.
That would make saves far too big.
Originally, the current save format stored x and y coordinates for each particle, and kept particle order the same. However, this made the data compress very poorly, making save files much larger than they needed to be.
When loading a save, TPT deduces the position of each particle from the order in which the particles appear in the save data, so they have to be ordered according to their position instead of the order in which you created them. Just after loading a save, particle order is left to right, top to bottom.
Avoid relying on particle order if you can, it's liable to break unexpectedly.
It is a great idea, however I agree with @jacksonmj (View Post)
That would make saves far too big.
How do you define 'far too big'? I think 100KB isn't much.
But you can put particle ID instead of X and Y, only used the same size as X and Y. Also just use a kind of tree to store all the particles. I'm sure it won't be larger than the current save format. (I hope developers are clever and know what is tree)
100KB isn't too much?I need 40s to download it from powdertoy.co.uk .(I hate China Telecom LOL)
New save format?Simon didn't want to break any saves.
My current speed is 200KB/s, however most computers have 10KB/s. Also most saves won't use the partcle order thing.
Also new save format never break any saves, because the save format is ALWAYS changing every version.
My speed is almost 1MB/s, but I have only 2.5KB/s speed at powdertoy.co.uk .
Actually, save format changed only a little.
For destroyable city 5, save size is:
35225 bytes for the current format, with no changes.
203373 bytes with x and y saved separately using two bytes each, and no partsPosData.
224267 bytes with x and y saved using y*XRES+x stored in three bytes, and no partsPosData.
217257 bytes with particle index saved in three bytes, position stored using partsPosData as in the unchanged current format.
There are over 965000 saves on this server (plus some old versions of each save, for the save history feature). If we take the size difference for destroyable city as being typical for other saves, that adds up to a lot of wasted space.
I don't really see how a tree would help. The saving code is in src/client/GameSave.cpp serialiseOPS() if you wish to look at it. A short explanation follows.
The particle data is mostly stored in two arrays of bytes.
First, partsData. This contains all particle properties except position, and they are stored for each particle in order of the particle position (left to right, top to bottom).
Second, partsPosData. For each coordinate, it stores the number of particles in that position. It contains three bytes for each coordinate. So for a save the size of the entire screen, this is 612*384*3 = 705024 bytes. However, since this is typically 0 or 1 for the majority of positions in most saves, the entropy is low and it compresses well. If storing positions or particle indexes, these have a much larger range of values and much higher entropy, so don't compress so well.
partsData and partsPosData are combined with the other save data (such as walls and signs) into one large array of bytes using the BSON format. This is then compressed using bzip2 and written to a file or sent to the server.
partsData: Byte 1 is the type of the first particle. Bytes 2 and 3 are the field descriptor, indicating which other properties are stored for that particle. Then come the other particle properties - temperature, ctype, tmp, dcolour etc. The number of bytes used for these and how to interpret these bytes back into property values can be deduced from the field descriptor.
The byte following all the property data is the type of the second particle. Then two bytes for the field descriptor for the second particle, and so on. This repeats for all particles.
partsPosData: When loading a save, TPT loops through each coordinate, left to right and top to bottom. The number of particles in that position is found from partsPosData, and that number of particles are read from partsData and placed in that position. The pointer to the current position in partsData is also incremented by that number of particles.
No, a new save format would not break saves. Only new versions would be able to read it, of course, but that's the case even for saves created in a newer version with the same save format (to prevent saves with new elements being loaded in an old version where the elements do not exist). New versions can always read old save formats. For example, destroyable city 5 was last saved from version 47 using the old PSv save format, yet still loads fine in version 88.1.
There is no way to compress the saves until they are brought up again?
What do you mean? If you're talking about compressing saves further when stored on the server, and decompressing when loaded, then no that wouldn't really help. Saves are already compressed. Trying to apply a second layer of compression to something already compressed using a decent algorithm will give either a minimal decrease, or an increase in size.