ID:2116246
 
(See the best response by Lummox JR.)
Code:
runtime error: Cannot create objects of type null.
proc name: Load (/mob/proc/Load)
usr: (src)
src: SoulGamesProductions(/mob)
src.loc: Turf (653,6,4) (/turf/Grass)
call stack:
SoulGamesProductions(/mob): Load()
SoulGamesProductions(/mob): cLoad Character()
proc
Save()
if(In_Game)
var/savefile/S = new("Savefiles/[uppertext(copytext(key,1,2))]/[key].sav")
Write(S)
Load()
if(!In_Game)
var/savefile/S = new("Savefiles/[uppertext(copytext(key,1,2))]/[key].sav")
Read(S)
for(var/obj/Items/A in src.Inventory)
A.InInv = 1
usr.BankInUse = 0
usr.isingame = 1
loc = locate(Last_X,Last_Y,Last_Z)
cLoad_Character()
set hidden = 1
if(In_Game)return
if(fexists("Savefiles/[uppertext(copytext(key,1,2))]/[key].sav"))
winset(src,"Default","is-visible=true")
winset(src,"Login","is-visible=false")
winset(src,"NewChar","is-visible=false")

winset(src,"Login","is-default=false")
winset(src,"NewChar","is-default=false")
winset(src,"Default","is-default=true")

winset(src,"MapI","is-default=true")
winset(src,"MapII","is-default=false")
Load()


Problem description:Some players get rollback on the game and it just happens some times. Like there has a auto-save every 5 minutes and then the mob log-out it saves but they still back to the save of 3 days ago. What could it be?

Best response
This is actually a common problem with savefiles. But first:

No put usr in proc. Ungh.

With that out of the way, let's talk about rollbacks. What's happening here is that your players' mobs are saving more than you actually want them to: They're saving other players' mobs.

This usually happens when you save a turf instead of specific x,y,z vars; the turf saves, and if a mob is standing on it, the mob is included in the savefile. Such a var should be /tmp so that it doesn't save.

There are other ways for this to happen too. For instance, if your mob is carrying an obj that has a var pointing to its original owner instead of a key--surprise, you just saved the original owner too. If your mob has a datum pointing to their party, and the datum has a list of party members, and that datum saves, then every mob in the list saves too.

The good news is you don't have to do a pwipe to be rid of this. But you do have to go through your savefiles and rid them of excess mobs, by opening them up in a savefile editor. I would suggest looking through the biggest ones first, since they'll be the most broken. You should take a look at which vars are saving the extra mobs, and then take care to change those vars to /tmp so they don't save.

You can also override Read() so that before reading the mob, you Remove() any of those vars that shouldn't be saving (or, load only the parts you need; like for instance for a turf you could just grab its coordinates). If that's done properly, the old broken saves can still be used because they'll eventually be purged of all the data you don't want.
In response to Lummox JR
"There are other ways for this to happen too. For instance, if your mob is carrying an obj that has a var pointing to its original owner instead of a key--surprise, you just saved the original owner too."
I think that is the problem,but I tried to look for a bit.
mob/var
list
Inventory = list()
obj/Items
verb
Get()
usr.Inventory.Add(src)
Move(usr)
Drop()
loc:Inventory.Remove(src)


Is this the cause of rollback? Because it add to usr Inventory,not by a key.
No.

Like Lummox said, you'll need to find one of the affected savefiles, export it using ExportText(), and look over the results to find the variable that contains another mob reference.

If you can't grasp that basic concept you're probably getting ahead of yourself and need to take a step back and review basic programming debugging and testing.
In response to Nadrew
I opened the biggest save files using save filer editor ( I belive they are the same of ExportText() ) And I dont found another mob reference. That means the problem not is a object?

(If you able please take a look,I tried to look 7 save files,with 500kb,200kb,300,.. and all looks the same! I uploaded a 200kb one because if I update the 500kb one it would take a lot lines of icon overlay,http://www.filedropper.com/tsuboiryotaro)
I tried my key and another admin key with ExportText() but nothing wrong.
You're saving a great deal of unnecessary icon data in your savefiles, which is worth looking at, but that file is clearly not one of the problem files. One of them is, however, so just keep looking until you find it. You're going to have to go through all of your savefiles to root this out, unless you implement the remove-on-read strategy I mentioned above. But either way you'll still need to figure out which var is saving other mobs, and put a stop to it.

Just looking at your savefile, I can come up with some good guesses. IgnoreList is a likely culprit, if you're putting mobs in that list instead of keys. (You also shouldn't be initializing that list until it's needed.) A list like that should always go by key, not by mob. Maybe it is; since it's empty I have no way to tell.

Also, while this isn't connected to your issue, what in the world is that InInv var for? There's no point to it. You shouldn't have to maintain an inventory list separate from the contents list anyway--if they're not the same thing, something is wrong. Yet you have a mix of both skills and inventory items in your contents, which isn't right.
In response to Lummox JR
I looked a lot vars,there had a var called "Target" used by monsters,I just add tmp on Target var. There has any chance of mob/var/Target causes this to saves?
InInv var is for bank deposit,because some itens has weight and if they are banked they should not add weight to the mob.
Also the ignore list may be the culprit! I just was looking at it and saw
        Ignore()
var/list/Players = new()
for (var/mob/M in world)
if (!src.IgnoreList.Find(M))
Players += M
if (!M.client)
Players -= M
Players += "Cancel"
var/choice = input ("Ignore who?", null) in Players
if (choice != "Cancel")
src.IgnoreList += choice
src << output("[choice] is now ignored!","Global") //confirmation message

Then if I take off M and place M.key the problem may be fixed? :D
The target var should definitely be /tmp, because it makes no sense to save it.

The ignore list also needs to be a list of keys, not mobs, because 1) when the player logs out and back in they'll have a different mob, and 2) you don't want those mobs to save, but only the keys.

The mobs being in a list might make it difficult to use Read() to avoid pwipes. You might be able to simply wipe old ignore lists by saving a version number.

#define SAVE_VERSION 2

mob/var/save_version = SAVE_VERSION

mob/Read(savefile/F)
var/version
F["save_version"] >> version
F.Remove("Target")
if(version < 2)
F.Remove("IgnoreList")
. = ..()
In response to Lummox JR
Wow thanks for the help.
I feel like I improved with your help,I really appreciate it.
best helper of all times
In response to Lummox JR
last question plase,how I can not save unnecessary icon data? I use icon_add and Blend.
What you need to do to avoid saving icons is clear out those vars before saving, or call Remove() after you write them. (Although Remove() won't free up space that was allocated for the icons.) Then you'd recreate the icons on load. Similarly you'd want to clear overlays/underlays out of the savefile and rebuild them as needed.

None of that is mission-critical, though; they won't impact the rollback issue.
In response to Lummox JR
Thanks,I was working on whole game and saw something ,can you say me if this can cause rollback problem also please?
var
Enterants = list()
mob/Npc/Tournament
verb
Talk()
Enterants.Add(usr)

It is a game var but I want to be sure if that cause problem.
Only if you save that variable somewhere. You don't really seem to understand any of this...