Okay I got to the point where I wanted to test my game on an Android device and it runs fine the first time I start it but after I close the game and try to reopen it will crash everytime the loadgameworld function gets called.
The problem is this only happens on Android and not on Windows.
I don’t know if your plugin supports Android but I hope you can point me in the right direction to fix this.
Android Crashlog
08-28 04:10:07.577 1786 1786 F DEBUG : Build fingerprint: 'samsung/dream2ltexx/dream2lte:9/PPR1.180610.011/G955FXXSBDTJ1:user/release-keys'
08-28 04:10:07.577 1786 1786 F DEBUG : Revision: '10'
08-28 04:10:07.577 1786 1786 F DEBUG : ABI: 'arm'
08-28 04:10:07.577 1786 1786 F DEBUG : pid: 1424, tid: 1586, name: PoolThread 3 >>> com.*******.******* <<<
08-28 04:10:07.577 1786 1786 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb74eda84
08-28 04:10:07.577 1786 1786 F DEBUG : r0 b74eda80 r1 00000000 r2 00000001 r3 00006a80
08-28 04:10:07.577 1786 1786 F DEBUG : r4 b74e7000 r5 ceb83ec0 r6 00006a80 r7 00000060
08-28 04:10:07.577 1786 1786 F DEBUG : r8 b74eda80 r9 eb465ce0 r10 ceb84048 r11 caf0b068
08-28 04:10:07.577 1786 1786 F DEBUG : ip c622f33c sp caf0b030 lr c0340744 pc c034074c
08-28 04:10:07.733 1786 1786 F DEBUG :
08-28 04:10:07.733 1786 1786 F DEBUG : backtrace:
08-28 04:10:07.733 1786 1786 F DEBUG : #00 pc 06e2774c /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (FMallocBinned::Private::FreeInternal(FMallocBinned&, void*)+412)
08-28 04:10:07.733 1786 1786 F DEBUG : #01 pc 06e749a0 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (FMallocPoisonProxy::Free(void*)+108)
08-28 04:10:07.733 1786 1786 F DEBUG : #02 pc 06e3381c /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (FMemory::Free(void*)+180)
08-28 04:10:07.733 1786 1786 F DEBUG : #03 pc 05b79830 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (FSaviorRecord::~FSaviorRecord()+144)
08-28 04:10:07.733 1786 1786 F DEBUG : #04 pc 05bb1694 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (_ZN12TSparseArrayI11TSetElementI6TTupleIJ5FName13FSaviorRecordEEE21TSparseArrayAllocatorI22TSizedDefaultAllocatorILi32EE25FDefaultBitArrayAllocatorEE5EmptyEi+356)
08-28 04:10:07.733 1786 1786 F DEBUG : #05 pc 05bb33b0 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (_ZN12TSparseArrayI11TSetElementI6TTupleIJ5FName13FSaviorRecordEEE21TSparseArrayAllocatorI22TSizedDefaultAllocatorILi32EE25FDefaultBitArrayAllocatorEEaSERKSB_+44)
08-28 04:10:07.733 1786 1786 F DEBUG : #06 pc 05b947c0 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (USavior3::SetSlotData(FSlotData const&)+176)
08-28 04:10:07.733 1786 1786 F DEBUG : #07 pc 05b74b7c /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (USavior3::ShadowCopySlot(USavior3*, USavior3*, ESaviorResult&)+296)
08-28 04:10:07.733 1786 1786 F DEBUG : #08 pc 05bcdb54 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000)
08-28 04:10:07.733 1786 1786 F DEBUG : #09 pc 05bcd6b0 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (FAutoDeleteAsyncTask<TASK_DeserializeGameWorld>::DoWork()+780)
08-28 04:10:07.733 1786 1786 F DEBUG : #10 pc 06e3ded8 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (FQueuedThread::Run()+2200)
08-28 04:10:07.733 1786 1786 F DEBUG : #11 pc 06e363dc /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (FRunnableThreadPThread::Run()+152)
08-28 04:10:07.733 1786 1786 F DEBUG : #12 pc 06d3be44 /data/app/com.*******.*******-Ng8-7o9V9t9mKcw1C7Usjw==/lib/arm/libUE4.so (offset 0x5a7f000) (FRunnableThreadPThread::_ThreadProc(void*)+80)
08-28 04:10:07.733 1786 1786 F DEBUG : #13 pc 00064899 /system/lib/libc.so (__pthread_start(void*)+140)
08-28 04:10:07.733 1786 1786 F DEBUG : #14 pc 0001e329 /system/lib/libc.so (__start_thread+24)
LoadGameWorld node is only being called once from the gamemode. I switched it to the Sync instead of Async and that didn’t make a difference.
Below is the GameMode graph. The last image is the create slot instance function.
@MrMightyErik apparently your device doesn’t like a call to System->Reset() on Savior.cpp line 325.
I don’t know yet what to do about this, need to learn more, but if you know how to edit source code and rebuild DLLs, you might want to try commenting that line out and see if that helps you.
After some tests, I am submitting an update with that line commented out along other minor changes.
Let me know if that is resolved for you once Epic process the new source files.
Updating to the latest version from the marketplace has fixed my game crashing on my android device.
So if anyone else has the same problem just update the plugin to the latest version.
Both 4.26 and 4.27 versions work.
Im trying to save a soft reference to another dynamic actor in a dynamic actor. On the On Prepare To Save event, I convert the hard reference to a soft reference, after which there should be a save from the savior. After loading on the On Loaded event, I try to get back a hard referenjce with a soft one but I get None. Both dynamic actors have SGUIDs and a Procedural interfaces. In this case, the savior in the logs does not give errors or warnings. I save and load the save with the Save / Load Game World (Async) command. SaveGame flag on variable is seted. What could be the problem?
2)Is it possible to somehow determine the sequence of loading / respawning of the actors? For example, I have actors who have a Child Actor, and a Child Actor on BeginPlay receive a reference to their Parent Actor and then interact with him. And apparently during loading, they are loaded chaotically, since I periodically observe that the Child Actor returns None when receiving the Parent Actor reference, so it turns out that the child was created earlier than the parent. Of course, i can send a command to the child actor after end of the spawn of the parent actor using an interface or an event, but it’s rather dreary to think over your own BeginPlay and Load events for each such case. Is it possible to define the sequence of loading the actors by classes or otherwise, except to manually load them?
Ok. As for streams and their effect on loading, I understood. What about the soft reference load? I’m trying to get a soft reference in the same actor. And threads, as I understand it, do not affect it. All other data such as int, bool, Enum are saved and loaded successfully only soft reference after loading is None.
Apparently I have not correctly explained what I am trying to do or I am trying to use soft reference for other purposes.
I have a pump in the game that pumps fluids. The pump is connected to tanks and has In and Out directions. When the pump turns on, it is pumping liquid (resource) from Out to In. The pump is dynamic. The player can buy or sell it, move it, etc. And so, when the pump is running, something like this happens:
(ref) TankOut.Liquid = (ref) TankOut.Liquid - 1;
(ref) TankIn.Liquid = (ref) TankIn.Liquid + 1;
And after loading, I need to restore links to TankOut and TankIn in order for the pump to work correctly. Initially, the TankOut and TankIn refernces are assigned when the player connects the hose.
And I cannot assign In and Out tanks during the respawn event, because tanks may be 0, or maybe 1000, and which one will be In or Out i don’t know, it all depends on the player. I need to restore the link to those tanks that the player previously assigned.
The only way that I see is to assign an ID to each actor for which you need to restore the reference, then after the respawn do “get all actor of class” and check each one for the desired ID. Save the ID with the help of the savior.
In a case like that, I would store in Player two properties of type ‘Guid’ marked SaveGame and, after loading world from save, I would pick the CurrentIn and CurrentOut Guid values and reassign the references searching actors by SGUID values:
In a case like that, I would store in Player two properties of type ‘Guid’ marked SaveGame and, after loading world from save, I would pick the CurrentIn and CurrentOut Guid values and reassign the references searching actors by SGUID values:
Thanks for the help. And one last little question. Based on all this, I understand that it is impossible to directly save the actor reference and the actor soft reference and they must be restored in some other way. This is true? I want to understand UE4 a little more from the side of game saves.
The issue there is caused by Async loading.
You could change the slot to synchronous task, but doing that would freeze the game (waiting for all actors to respawn) to mitigate the result you see, but doing that would still NOT avoid the property (ref) being read from slot before target actor exists… because your actors are dynamically spawned, so the plug-in cannot predict which property is going to be restored before the referenced actor was respawned.
Hi. The variable is not saved, I created a variable of type bool and on the On Prepare To Save event I write data to it (true) after which I expect it to be saved by the plugin. The event fires. But when loaded, the variable is set to default (false). In the save file, the variable has the desired value (true), what could be the problem?
I found a problem, but I don’t know how to solve it, maybe you can tell me…
As I understand it, the actor is loading too fast, unlike the loaded plugin data. I added a 1 second delay and the data was loaded completely. I tried different events,On Begin Play, On Begin Respawn, On Finish Respawn and everywhere the data was lost but with a delay everything loaded. I tried On Loaded, but as I understand it, it only works when the actor is already in the world and does not spawn while loading game. How do I get the event when the actor has received 100% of the data from the plugin?
It would be nice if you updated the event documentation to accurately describe how they work.
Also, a small question, if I save the SGUID for later restoring the dynamic Actor Reference, do I need to use Generete Once: SGUID or still use Make SGUID?
You will only be certain that everything was respawned, and all properties were read from file, from the Finished Load Callback of an Async Load Game World node:
Then you should start reading values, the callback is the last thing to be executed once the async task is complete.