How to sort a random DateTime array from oldest to newest?

I found this plugin, which has among many other things, a function to sort by date and time (and reverse) an array containing random out of order DateTimes. It works great:

However I wanted to do the same thing using blueprint nodes, so I don’t have to rely on third party plugins that could possibly be discontinued or unsupported.

How can I do so?

Learn how to implement bubble sort and rebuild it in blueprint.
There are hundreds of sort algorithm tutorials in the internet.

Bubble sort is the algorithm which will do it.

There’s a DateTime comparision node

image

You basically have to run through the array and find the lowest one and put that in a new array. Then repeat.

That’s a bubble sort.

Very non-glamourous, but here’s a function to find the lowest

and here’s a function to apply that

And how to call the whole thing

Tested, very slightly, it’s more the concept…

2 Likes

thank you. I searched for bubble sorting and was trying to apply it, and came up with this:

but it doesn’t really do anything other than swapping two entries (maybe) and returning a lot of errors.

let me try your suggestion real quick

Length should definitely be replaced with Last Index. The +1 is also not correct, it will go out of bounds. Not sure about the rest.

yeah it’s a mess, didn’t really put too much thought into it. @ClockworkOcean’s solution is way better, it actually works just as it should!

Only one question remains, how can I invert the order? the plugin’s function has a handy dandy “reverse” toggle, but I think I’m missing some pre existing nodes that would make that an easy task perhaps?

I think there’s a REVERSE array node?

I saw the other thread for this and you’re going to be using this for a save system, right? If you are, then you don’t need to sort anything because all saves are already going to be played in chronological order, so you’ll always know which is the most recent. Basically, the most recent save is just the one that was played last, and the one that was played last is the one that is being played currently (i.e. the one that the player picks).

So all you have to do is put the save that is being playing currently at the top of the array (index 0), and it’ll already be sorted.

Example (Newest to Oldest)

NewGame → Save0
SaveArray = {Save0}

NewGame → Save1
SaveArray = {Save1, Save0}

NewGame → Save2
SaveArray = {Save2, Save1, Save0}

LoadGame → Save0
SaveArray = {Save0, Save2, Save1}

NewGame-> Save3
Save Array = {Save3, Save0, Save2, Save1}

LoadGame → Save2
SaveArray = {Save2, Save3, Save0, Save1}

And to have it oldest to newest, you would either (A) add them at the end of the array, or (B) read the array in reverse.

right in front of my nose, ouch.

thank you though! it works just like how I imagined.

this is interesting… let me see if I follow, so every time you create a new save, save into an existing save or load a save game you add it to an array?

wouldn’t it add duplicates? and if I us AddUnique will it update the array order?

I guess I need a bit more practice with arrays

Doesn’t the for each loop cut out after a few sec of execution like the for loop does?

I would seriously suggest doing the sort in a c++ blueprint usable function where you just plug the array in and the returned pin is the sorted value of it…

When adding a new save, you just add it to the beginning of the array (index 0):
image

And when loading a save, you move the save to the beginning of the array:

Here’s what that looks like (displaying time only); notice how it always stays sorted:

Also, you can see that the date isn’t even used, so this works without storing the date. All we are doing is moving the save that the player chooses to the top; the sorting happens naturally.

3 Likes

Intriguing, never thought of doing it that way. Well I actually didn’t know you could insert elements into the beginning of an array and rearrange the rest of them. This should simplify this whole setup! I should actually go ahead and try to find some more in depth vids on arrays cuz I really lack some knowledge on handling them I suppose.

I’ll go ahead and mark ClockworkOrange’s reply as a solution for this as it’s what I’m asking on the title, but if you want to copy and paste your answer into my other thread, it is definitely a better solution than my own over there

thanks a lot!

1 Like

If I may add a follow up question though, the way I store existing save slots into my array right now is by looping through numbers 1 to 99 and checking if a slot named that number exists, and if they do I add them to the array, that way it’s always created ordered by slot number.

How would you handle saving the array in order as you save them in your example, would you just create a separate save game blueprint just to keep that array stored between sessions?

Yes, exactly. You just have a single save game blueprint dedicated to listing the saves only, and when the player selects one, you load the full save. The save game array is where you would store metadata about the saves (ex. character name, level completion, save date, and thumbnail).

So it would look like this:

  1. LoadGameFromSlot(“SaveGameArray”)
  2. Show all saves to player
  3. Player selects “Save 5”
  4. LoadGameFromSlot(“Save 5”)
1 Like

Wouldn’t the thumbnail create the risk of having a huge save file?
Let’s say, player saves 1000 times, hence 1000 thumbnails of 3Mb each, for example. That would turn into 3Gb to load just when starting the game, right?

Depends on how you do it.
If you paginete things and load only when required then no.

1 Like

Do you mean you can load only parts of a save file.
I meant having all thumbnails and metadata in one save file.

Usually the save files aren’t saved within the save file itself.
Each save you make is a new file, each file can have a thumbnail.

In other words, a proper system wont really have a saved list in a save game like they state above, but a much simpler file I/O based read of the save folder, which allows for sorting the array you pull from disk however you see fit any time you refresh/reload/call the reading folder process again.

You can see stuff like it on games that somewhat partially suck like Minecraft, The Long Dark, i mean, it is rather basic so it is almost everywhere even if handled slightly different.

If you work for the PS5/sony stuff you have to handle it with their internal savefile stuff.
If you work Switch you have to use their internal stuff.

Direct File I/O is only going to fly for a PC release, a Mac release, or an Android release.

IOS may end up allowing you to do the same via objectiveC, but apple frowns on direct file I/O or flat out stops it. So you probably have to work around it by using the dedicated file system saving stuff that only writes in the restricted app data folder.

In the end, it’s not rocket science, its just different for every distribution due to the system requirements of the distribution.

And no:
Usually you wouldnt do it in Blueprint or on anything other than straight up code. Mostly because blueprint doesn’t have I/O stuff in kismeth you can access (at least it didn’t), but even if it did, you wouldn’t precisely because you generally want to code cusrom bits in for specific platforms…

Back to the hacky way above:
You can make multiple lists files, then list the list files in another list file, which is contained in another file with lists of files. Etc.
And basically make pagination that doesn’t require loading all bijillion things in memory to access a single save file.

  • but i suggest you go the proper way about it instead ?
1 Like