Wegen dieser Problematik hatte vor langer Zeit mal versucht ein eigenes Speichern/Laden zu implementieren. Ich hatte damals den Code so gestaltet, dass sich erstellte Objekte und wichtige Structs in einem großen Managerstruct registriert haben und ihre Pointer in diesem in Form von Listen/Hashmaps etc. gespeichert wurden.
Dann brauchst du für das Speichern und Laden jeweils eine Funktion, die in einer großen Schleife alles abarbeitet. Zum erstellen des "Spielstands" habe ich ein SQL-Plugin verwendet, weil es aufgrund der tabellarischen Speicherform sehr flexibel und überschaubar bleibt - zB beim Debuggen etc...
Ich weiß nicht wie effektiv das ganze ist, aber ich meine in dunkler Erinnerung zu haben, dass ich aus Spaß Tests mit 100000 Objekten gemacht hatte und das Speichern etwa 10-30Sek, das Laden aber seeeehr viel weniger Zeit gebraucht hatte.

Nur mal so als Idee/Erfahrungsbericht wink
Viel Erfolg weiterhin!