ID:2126685
 
Code:
mob
verb
Save()
var/savefile/F=new("Players/[src.ckey].Save")
Write(F)
src<<"Character Saved!"


mob
Write(savefile/F)
..()
F["mob"] << src
F["x"]<<x
F["y"]<<y
F["z"]<<z
F["dir"]<<dir
Read(savefile/F)
..()
F["mob"] >> src
F["x"]>>x
F["y"]>>y
F["z"]>>z
F["dir"]>>dir
src.loc=locate(src.x,src.y,src.z)


Problem description:
It makes you login twice for some reason.
I want a simple small save and read system like this, but one that works...
Please help!
1. You shouldn't be loading into "src". Write() and Read() by default save and load all the modified variables of an object, without saving the object itself. By saving and loading the mob itself, you're creating a new mob and getting logged into it because it has your key.

This also means you would need to avoid saving any other reference to src, including those in objects contained by src. This can be avoided by not calling Read() and Write() directly, but saving and loading the object itself.

2. dir is saved automatically.

3. Loading x, y, and z individually won't do anything, and neither will setting loc to locate(x, y, z), since they would originally be equal.

The simple save-and-load, plus location-saving, without preventing icon-saving, and without any kind of future-proofing:
mob
proc
GetSavePath()
return "Players/[ckey].sav"

verb
save()
Write(new /savefile (GetSavePath()))
src << "Character saved!"

load()
var save_path = GetSavePath()
if(fexists(save_path))
Read(new /savefile (save_path))
src << "Character loaded!"
else src << "No character to load!"

Write(savefile/Save)
..()
Save["x"] = x
Save["y"] = y
Save["z"] = z

Read(savefile/Save)
..()
loc = locate(Save["x"], Save["y"], Save["z"])

mob/proc
Menu()
MAINMENU
switch(input(src,"Welcome to [world.name]","Game Menu",text) in list ("Create New","Load","Delete"))
if("Create New")
if(fexists("Players/[src.ckey].Save"))
alert("You already have a player on this server!","[world.name]")
goto(MAINMENU)
else
src.Names()
sleep(5)
switch(alert(src, "Choose Gender" , "Gender Select","Male","Female"))
if ("Male")
src.icon = 'person.dmi'
src.icon_state = "Boy Hero 1"
if ("Female")
src.icon = 'person.dmi'
src.icon_state = "Girl Hero 1"
src.loc=locate(59,64,2)
src.Give_Name()
src.GiveVerbs()
src.ADMIN()
src.login=1
world<<output("<b><font color=red><u>System Info:</u></font> <font color=green>[src.name] has created a character!</font>", "output2")
if("Load")
if(fexists("Players/[src.ckey].Save"))
src.load()
src.GiveVerbs()
src.Stuff()
else
alert(usr,"No file found")
goto(MAINMENU)
if("Delete")
if(fexists("Players/[src.ckey].Save"))
fdel("Players/[src.ckey].Save")
alert(src,"Save file deleted.")
del(src)
else
alert(usr,"No file found")
goto(MAINMENU)

THANK YOU SO MUCH. but i got another question how to implement it with my game menu. please note im still learning how to code. keep that in mind.
In response to Kaiochao
The simple save-and-load, plus location-saving, without preventing icon-saving, and without any kind of future-proofing

The slightly-better save-and-load involves an intermediate mob type intended for your title or character select screen.

This particular so-called "character management system" includes a couple guidelines:
* You can only save a character as that character. Makes sense.
* You can only load a character while you're in the lobby. No worries, though. If you're in-game, just save and go back to the lobby.

world
mob = /mob/lobby

client
proc
SavePlayer(Path)
if(istype(mob, /mob/player))
var savefile/save = new (Path)
save << mob
return TRUE
return FALSE

LoadPlayer(Path)
if(fexists(Path))
var savefile/save = new (Path)
save >> mob
return TRUE
return FALSE

mob/lobby
Login()
src << "Entered the lobby."

Logout()
src << "Left the lobby."

verb/load()
if(client.LoadPlayer(GetSavePath()))
client << "Loaded!"
else client << "Load failed!"

verb/create()
var mob/player/player = new (GetPlayerSpawnLocation())
player.name = name
player.gender = gender
player.save_path = GetSavePath()
client.mob = player

proc/GetSavePath()
// If you want multiple save slots, return a variable here instead
// that contains the path to that particular save.
return "Players/[ckey].sav"

proc/GetPlayerSpawnLocation()
// return some atom, such as a turf, where you want new players to spawn

mob/player
var
save_path

Login()
src << "Entered the game."

Logout()
src << "Left the game."
// You probably want to delete the player at this point.

verb/save()
if(client.SavePlayer(save_path))
src << "Saved!"

verb/return_to_lobby()
save()
client.mob = new /mob/lobby

Write(savefile/Save)
// Prevent icon, overlays, and underlays from bloating the save file with junk
// by (temporarily) setting them to default, causing them to not be saved.
// Remember what they were so they can be restored.
var
old_icon = icon
old_overlays = overlays
old_underlays = underlays
icon = initial(icon)
overlays = initial(overlays)
underlays = initial(underlays)

// Do the default behavior of Write(), which is to write all modified variables
// to the save file (excluding icon, overlays, and underlays).
..()

// Save the player's coordinates.
Save["x"] = x
Save["y"] = y
Save["z"] = z

// Restore icon, overlays, and underlays to what they were before saving.
icon = old_icon
overlays = old_overlays
underlays = old_underlays

Read(savefile/Save)
..()
// Load the player's coordinates.
loc = locate(Save["x"], Save["y"], Save["z"])

RebuildAppearance()

proc/RebuildAppearance()
// Set icon, overlays, and underlays appropriately
// because they were not allowed to be loaded.
In response to Louisthe10
Your current Menu proc is incompatible with the "slightly-better" character management system because it depends on the same mob object to be present the entire time.

You're going to need to move some things around.

/mob/lobby is where you should put things such as a welcome screen, character selection, and character creation.

A welcome screen in your case is the first input() that asks if you want to "Create New" (enter character creation), "Load" (enter character selection), or "Delete" (I haven't provided this, but I can if I have the time and you don't figure it out yourself).

Character creation is where you should put things such as gender selection and name selection, as well as initial spawn point. Modify /mob/lobby/verb/create() to implement other choices.

Character selection, if you don't allow more than 1 player, just involves calling /mob/lobby/verb/load(). Otherwise, you'd change /mob/lobby/proc/GetSavePath() to return a character-specific path.

Gender selection in your case is the alert() that results in... gender being selected. By the way, it's a built-in variable.

Name selection in your case probably involves whatever your Names() is.

Initial spawn point in your case would be returning locate(59, 64, 2) in /mob/lobby/proc/GetPlayerSpawnLocation():
mob/lobby
proc/GetPlayerSpawnLocation()
return locate(59, 64, 2)


/mob/player is where you should put things such as building the appearance, building the verbs list, and checking admin privileges.

Building the appearance in your case is setting the player's icon and icon_state according to their gender, which was chosen during character creation.
icon = 'person.dmi'
switch(gender)
if(MALE) icon_state = "Boy Hero 1"
if(FEMALE) icon_state = "Girl Hero 1"


Checking admin privileges is pretty self-explanatory.

Building the verbs list probably involves whatever your GiveVerbs() and ADMIN() are.

In response to Kaiochao
im trying to use the one from the first post and incorporate it into my game menu and im lost :/
but thank you for trying to help me.

runtime error: BYOND Error: bad mob
proc name: Read (/mob/Read)
usr: null
src:
call stack:
Read(Players/louisthe10.Save (/savefile))
load()
Menu()
Menu (5,9,1) (/turf/Menu): Click(Menu (5,9,1) (/turf/Menu), "Main.map1", "icon-x=30;icon-y=8;left=1;scre...")