ID:1873676
 
(See the best response by Kaiochao.)
Loading Code:
client
proc
Client_Load()
if(fexists("System Save Files/Client Save Files/[src.key]/[src.mob.Username].sav"))
var/savefile/L = new("System Save Files/Client Save Files/[src.key]/[src.mob.Username].sav")

L["Username"] >> src.mob.Username
L["Password"] >> src.mob.Password
L["Icon"] >> src.mob.icon
L["Name"] >> src.mob.name
L["Hair"] >> src.mob.Hair
L["Hair Color"] >> src.mob.Hair_Color
L["Overlays"] >> src.mob.overlays
L["Last X"] >> src.mob.x
L["Last Y"] >> src.mob.y
L["Last Z"] >> src.mob.z

L["Ryo"] >> src.mob.Ryo
L["Skill Tokens"] >> src.mob.Stat_Tokens
L["Roleplay Tokens"] >> src.mob.Roleplay_Tokens
L["Sensei Progression Tokens"] >> src.mob.Sensei_Progression_Tokens
L["Tracking Progression Tokens"] >> src.mob.Tracking_Progression_Tokens
L["Independance Progression Tokens"] >> src.mob.Independance_Progression_Tokens
L["Assassination Progression Tokens"] >> src.mob.Assassination_Progression_Tokens
L["Intel_Gathering_Progression Tokens"] >> src.mob.Intel_Gathering_Progression_Tokens

var/mob/Player = new/mob
Player.Username = src.mob.Username
Player.Password = src.mob.Password
Player.icon = src.mob.icon
Player.name = src.mob.name
Player.Hair = src.mob.Hair
Player.Hair_Color = src.mob.Hair_Color
Player.overlays += src.mob.overlays
Player.loc = locate(src.mob.x,src.mob.y,src.mob.z)

Player.Ryo = src.mob.Ryo
Player.Stat_Tokens = src.mob.Stat_Tokens
Player.Roleplay_Tokens = src.mob.Roleplay_Tokens
Player.Sensei_Progression_Tokens = src.mob.Sensei_Progression_Tokens
Player.Tracking_Progression_Tokens = src.mob.Tracking_Progression_Tokens
Player.Independance_Progression_Tokens = src.mob.Independance_Progression_Tokens
Player.Assassination_Progression_Tokens = src.mob.Assassination_Progression_Tokens
Player.Intel_Gathering_Progression_Tokens = src.mob.Intel_Gathering_Progression_Tokens

src.mob.Load(Player)

mob
proc
Load(var/mob/Player)
src.client.mob = Player


Saving Code:
client
proc
Client_Save()
var/savefile/S = new("System Save Files/Client Save Files/[src.key]/[src.mob.Username].sav")

S["Username"] << src.mob.Username
S["Password"] << src.mob.Password
S["Icon"] << src.mob.icon
S["Name"] << src.mob.name
S["Hair"] << src.mob.Hair
S["Hair Color"] << src.mob.Hair_Color
S["Overlays"] << src.mob.overlays
S["Last X"] << src.mob.x
S["Last Y"] << src.mob.y
S["Last Z"] << src.mob.z

S["Ryo"] << src.mob.Ryo
S["Skill Tokens"] << src.mob.Stat_Tokens
S["Roleplay Tokens"] << src.mob.Roleplay_Tokens
S["Sensei Progression Tokens"] << src.mob.Sensei_Progression_Tokens
S["Tracking Progression Tokens"] << src.mob.Tracking_Progression_Tokens
S["Independance Progression Tokens"] << src.mob.Independance_Progression_Tokens
S["Assassination Progression Tokens"] << src.mob.Assassination_Progression_Tokens
S["Intel_Gathering_Progression Tokens"] << src.mob.Intel_Gathering_Progression_Tokens


Problem description:
First off, i have never posted a problem post on here before, so i'm not even sure if this is the right place to post it but my guess is it probably is.

For some strange reason, when i load the save file, the username is coming across as null. Everything else is loading perfectly. I'm confused as to why this is happening. I know this probably doesn't help much, but i'll try my best to answer any questions to help find a solution for this.

If you need any other bits of code or whatever, just ask. Any help would be greatly appreciated! Thanks.

Best response
Is it possible that Username is being reset at since point after loading? You could output the loaded value and see if you are setting Player.Username successfully before something else messes it up.

Also, you might as well load those variables directly into Player, rather than having to duplicate all that code. Or you could just save the mob itself and not save/load each individual variable.
In response to Kaiochao
Kaiochao wrote:
Is it possible that Username is being reset at since point after loading? You could output the loaded value and see if you are setting Player.Username successfully before something else messes it up.

It doesn't get reset at all after the file is loaded. Although, i failed to mention that i had "L["Username"]" output to the user directly before "L["Username"] >> src,mob.Username" in the loading coding, which in turn fixed the problem. It's like "L["Username"]" has been layered with a blank value, and once used, it gains the saved value that it should have. If that makes sense?

Also, you might as well load those variables directly into Player, rather than having to duplicate all that code. Or you could just save the mob itself and not save/load each individual variable.

I understand what you mean. I've always written the load proc like this, i've never thought to load them straight to Player. I suppose it would be easier.

Thanks for the reply!
I wouldn't recommend making the savefile named after src.mob.Username. In case events where username becomes null, you won't load it at all because there's no such file as "null.sav".

I use the "slot" method. This is how I current do it:
        deleteCharacter(slot as num)
if(fexists("#SAVE/[src.ckey]/[slot].sav"))
src.client.clearPreview(src, slot)
fdel("#SAVE/[src.ckey]/[slot].sav")

saveCharacter(slot as num)
var/savefile/save_file = new("#SAVE/[src.ckey]/[slot].sav")
save_file["mob"] << src
save_file["name"] << src.name
save_file["preview_icon"] << src.icon
save_file["preview_overlays"] << src.overlays
save_file["preview_underlays"] << src.underlays

loadCharacter(slot as num)
if(fexists("#SAVE/[src.ckey]/[slot].sav"))
var/savefile/save_file = new("#SAVE/[src.ckey]/[slot].sav")
save_file["mob"] >> src
if(!src.Move(locate(save_file["loc_x"], save_file["loc_y"], save_file["loc_z"])))
src.loc = locate(save_file["loc_x"], save_file["loc_y"], save_file["loc_z"])
checkAdministration(src.key, src)


(The "preview_" variables are for my loading system that shows previews of the saved characters. The reason these are saved seperate is because I want to load the variables and icons w/overlays+underlays, without actually loading the /mob)
My problem isn't with the save file path, it's with "L["Username"]". As i stated in my reply to Kaiochao, it's like this has been layered with a blank value, once it gets used it gains the correct save value(Not sure if this is making sense at all xD). Anyhow, my problem is merely with "L["Username"]" and that only, everything else loads perfectly. :/
In response to Goku2oo7
Debug it. Put a sanity check in before saving the Username and output to a .html or log or world, whatever have you (I personally use a html debug logger like so:
#define DEBUG_MODE
var/debugger/debug_system = new

/*
debug_system.debug(line, file, message)
Example: debug_system.debug(12, "var_mob", "[src].Testing(), message = [message]")
Which will come out and look like this in the .html file:

6-13-15 , (FILE) : var_mob.dm , (LINE) : 12
Maximus_Alex2003.Testing(), message = Hello world.

*/

debugger
proc
debug(line, file, message)
#ifdef DEBUG_MODE
var
checkYear = text2num(time2text(world.realtime,"YY"));
checkMonth = text2num(time2text(world.realtime,"MM"));
checkDay = text2num(time2text(world.realtime,"DD"));
time_stamp = "[checkMonth]-[checkDay]-[checkYear]"
debug_file = file("#DEBUG/[time_stamp]/[file].html")
end_message = "<b>[time_stamp]</b> , (FILE) : <b>[file]</b>.dm , (LINE) : <b>[line]</b><br>[message]<br><br>"
if(line && file && message && end_message) debug_file << end_message
else debug_file << "<b>[time_stamp]</b><br><b>Error</b>: Unable to log debug."
#endif


But any sort of logging will work for you. Either way, put a log in and see what Username is before, and Username is after saving/loading. Once you find where it's gone missing, you can debug into it more. It's probably in another part of code.
You know, if you just do something like savefile << mob to save and savefile >> Player to load, you don't have to save and load each variable manually, and variables marked as tmp will automatically be skipped. Too many people don't know this and end up writing way more than they have to in their character handling systems.
In response to Kaiochao
Kaiochao wrote:
You know, if you just do something like savefile << mob to save and savefile >> Player to load, you don't have to save and load each variable manually, and variables marked as tmp will automatically be skipped. Too many people don't know this and end up writing way more than they have to in their character handling systems.

This is true, unless you want to access a variable without loading the /mob. Like, saving a player's name and then showing that name instead of "Would you like to load Slot#1?" you can do "Would you like to load [save_file["preview_name"]]?"

Either way, I agree. /mob should be saved since it contains the variables anyways. Saving the /mob and each variable separate would just cause save-file size increases. I've seen YuGiOh fan-games where each individual card was saved on top of the /mob's contents. The save-files went to be 300+KB.
In response to Maximus_Alex2003
You can load the name of the saved mob without having to save the name specifically.
I'll try use the debugger and see if i can see where the Username is getting lost.

And yeah, i find saving each variable individually easier so i can access them when i need to without actually loading the whole file. I do see your point, though, about loading the file straight to the Player, rather than to the mob and then to the Player.
So i used the debugger, and i'm still confused as to how the Username is getting lost.

I had the debugger check the Username after the game saved at logout. The username was still evident at this time. So i had it check the Username when the client loads, and this is what it's showing:

Login Code:
mob
verb
Client_Login()
set category = null
var/Username = winget(usr,"LoginWindow.Username","text")
var/Password = winget(usr,"LoginWindow.Password","text")

if(fexists("System Save Files/Client Save Files/[src.key]/[src.key].sav"))
if(fexists("System Save Files/Client Save Files/[src.key]/[Username].sav"))
var/savefile/L = new("System Save Files/Client Save Files/[src.key]/[Username].sav")
L["Username"] >> src.Username
L["Password"] >> src.Password

if(!Password)
ShowAlert("AlertShadow",286,202,"Alert",286,202,"Invalid Password","Please provide a password.","OK","CloseAlert","Red","","","Gray","LoginWindow")
return
if(Password != src.Password)
ShowAlert("AlertShadow",286,202,"Alert",286,202,"Invalid Password","Your password doesn't match the one on our records.","Try Again","CloseAlert","Red","Retrieve Account","Retrieve-Account","Red","LoginWindow")
return
else
if(Remembered_Clients.Find("[src.key]"))
Remembered_Clients.Add("[src.Username]")
Remembered_Clients.Remove("[src.key]")
Remembered_Client_Save()

winset(usr,"LoginWindow","is-visible=false")
winset(usr,"MainWindow","is-visible=true")
src.client.Details_Save()
debug_system.debug(62,"Guest Login","[src].Client_Login() - Username = [L["Username"]]")
src.client.Client_Load()
return

Image: Login Debugger Image

And then i had the debugger check the details in the loading code:

Client Load Code:
client
proc
Client_Load()
if(fexists("System Save Files/Client Save Files/[src.key]/[src.mob.Username].sav"))
var/savefile/L = new("System Save Files/Client Save Files/[src.key]/[src.mob.Username].sav")

debug_system.debug(13,"Loading","[src].client.Client_Load() - Username = [L["Username"]] | Password = [L["Password"]] | Name = [L["Name"]]")
L["Username"] >> src.mob.Username
L["Password"] >> src.mob.Password
L["Icon"] >> src.mob.icon
L["Name"] >> src.mob.name

Image: Client Load Debugger Image

Client_Load() loads everything else perfectly fine, the value that "L["Username"]" holds has the correct value before Client_Load() is called. For some reason, when Client_Load() is called it loses it's value and gets masked with a blank value? I'm honestly just so confused!?

Thanks for the help everyone up until, but if anyone could help me figure this out that would be great!
If anyone could give me an answer for this that would be great! ++
Can you manually open the save file and check if the Username is there? Use a savefile editor in the Developers section ( http://www.byond.com/developer/?text=save+edit&sort=date ) or build your own. I don't believe Username is being saved. Is Username a 'tmp' variable somewhere?
Username isn't a tmp variable, and it is being saved. I even used debug() when the mob was saved at logout. Also, as you can see in the Login Code, and Login Debugger Image above, Username isn't blank before Client_Load() is called. It, for some reason, becomes blank during Client_Load(). None of the other variables act like this, everything else loads perfectly. :/

I suppose i could try a save file editor, but i don't think it's a saving issue. I'm unsure of what the issue is, but Username has the correct value, until Client_Load() is called.
I noticed you put debugging in, but not enough; you're not actually checking what Username is for the new client mob directly after Client_Load() is called.

In fact I see no code posted that shows how you're coming to the conclusion that Username is empty. Where are you finding Username is empty?

My strong suspicion is that because you've setup the load in a weird indirect way (Why are you not simply saving and loading the mob directly?), you're not accounting for issues with Login() and Logout() when a client changes mobs.