In response to Ter13
I see what you are saying, however I cannot find anything to substitute for what I already had and even when I changed your items I still end up with a loop.
mob/other/choosing_character/proc/CreateNewCharacter()

var/prompt_title = "Character Creation"
var/help_text = "What is your name?"
var/default_value = ""
var/char_name
var/list/characters = CharacterList()
do
char_name = input(src, "What is your name?","New Character") as null|text
if(!char_name)
return

if (ckey(char_name) in characters)
alert("This name cannot pass.")
char_name = null
while(!char_name)


help_text = "What race do you wish to be?"
var/list/races = list("Human")
default_value = "Human"
var/char_race = input(src, help_text, prompt_title, default_value) in races
var/mob/new_mob
switch(char_race)
if("Human")
new_mob = new/mob/characters/Human()
new_mob.icon = "Human.dmi"

I can see how you did it with fill in the blank, but how would it be done with select the following options?
Ah, the stack structure. It harkens back to my Computer Architecture course I took oh so long ago (two semesters ago.) Between the frustration of building a compiler and using the Intel assembly language, I am very proud I passed that class.

But I digress. Good stuff, Ter--I learned lots. Remind me to buy you a beer if we ever meet in real life.
I'd like to see your whole character creation process, TBH. I can't know what I'm working with unless I see the whole structure.
In response to Ter13
mob/Login()
src.loc=locate(45,38,1)
src.icon_state = ""
src.sight = 0
client.eye = src
client.perspective = MOB_PERSPECTIVE
src << output("<font color = red>Welcome to One Punch Man, we owe no affiliation to one punch man so don't sue us XD</font>","chatbox")
world << output("<tt><font color = red>{-><font color = blue>[src] has logged in!<font color = red><-}</tt>","chatbox")
world
mob = /mob/other/choosing_character
//name = "One Punch Man"
name = "One Punch Man"
mob/Logout()
del(src)

client/proc/SaveMob()
var/firstletter=copytext(src.ckey, 1, 2)
var/savefile/F = new("players/[firstletter]/[src.ckey].sav")
var/char_ckey = ckeyEx(src.mob.name)
F["/[ckey]/[char_ckey]"]<<src.mob

client/proc/LoadMob(char_ckey)
var/firstletter=copytext(src.ckey, 1, 2)
var/savefile/F = new("players/[firstletter]/[src.ckey].sav")
F["/[ckey]/[char_ckey]"]>>src.mob

client/Del()
if (istype(src.mob, /mob/other/choosing_character))
return ..()

src.SaveMob()
return ..()


mob/other/choosing_character
Login()
client.eye = locate(rand(1,150),rand(1,150),1)
client.perspective = EYE_PERSPECTIVE
spawn()
ChooseCharacter()

proc
ChooseCharacter()
while(client)
var/list/menu = src.CharacterList() + "New Character" + "Delete Character"

var/result=input("Choose an option", "One Punch Man") as anything in menu
switch(result)
if("New Character")
CreateNewCharacter()
if("Delete Character")
DeleteCharacter()
else
src.client.LoadMob(result)

CharacterList()
var/firstletter=copytext(src.ckey, 1, 2)
var/savefile/F = new("players/[firstletter]/[src.ckey].sav")
F.cd = "/[ckey]"
var/list/characters = F.dir
return characters

DeleteCharacter()
var/firstletter=copytext(src.ckey, 1, 2)
var/savefile/F = new("players/[firstletter]/[src.ckey].sav")

F.cd = "/[ckey]"
var/list/characters = F.dir

var/CancelCharacterDeletion = "Decline"
var/list/menu = new()
menu += characters
menu += CancelCharacterDeletion

var/result = input("Delete character", "Character Creation") in menu

if (result)
F.cd = "/[ckey]"
F.dir.Remove(result)
if (result == CancelCharacterDeletion)
src.ChooseCharacter()
else
src.ChooseCharacter()

mob/other/choosing_character/proc/CreateNewCharacter()

var/default_value = ""
var/char_name
var/list/characters = CharacterList()
do
char_name = input(src, "What is your name?","New Character") as null|text
if(!char_name)
return

if (ckey(char_name) in characters)
alert("This name cannot pass.")
char_name = null
while(!char_name)


var/help_text = "What race do you wish to be?"
var/list/races = list("Human")
default_value = "Human"
var/char_race = input(src, help_text, default_value) in races
var/mob/new_mob
switch(char_race)
if("Human")
new_mob = new/mob/characters/Human()
new_mob.icon = "Human.dmi"

mob
Login()
..()
if (!istype(src, /mob/other/choosing_character))
sample_report()

Write(savefile/F)
..()

F["last_x"] << x
F["last_y"] << y
F["last_z"] << z

Read(savefile/F)
..()

var/last_x
var/last_y
var/last_z
F["last_x"] >> last_x
F["last_y"] >> last_y
F["last_z"] >> last_z
loc = locate(last_x, last_y, last_z)

proc
sample_report()
src << "<b><font size = 1><font color = silver><center>By: Dragonpear321"
src << "<b>Beta Testing One Punch Man"
world
mob = /mob/other/choosing_character
//name = "One Punch Man"
name = "One Punch Man"

var/list/_races = list("Human"=/mob/characters/human,"Elf"=/mob/characters/elf) //obviously, modify this to suit your races.

client
proc
Save()
if(mob.savable)
var/savefile/savefile = new("players/[copytext(ckey, 1, 2)]/[ckey].sav")
savefile["/[ckey]/[ckey(mob.name)]"] << mob

mob/other/choosing_character
var
list/characters = list()
savefile/savefile
Login()
client.eye = locate(rand(1,150),rand(1,150),1)
client.perspective = EYE_PERSPECTIVE
spawn()
ChooseCharacter()

proc
ChooseCharacter()
//we don't need to reload the savefile more than once. Store it and keep the chars list around
savefile = new("players/[copytext(ckey, 1, 2)]/[ckey].sav")
savefile.cd = "/[ckey]"
characters = savefile.dir
var/list/menu //it's best to define these outside of a loop where possible. There are reasons.
var/result
while(client)
menu = characters + "New Character" + "Delete Character"

result=input("Choose an option", "One Punch Man") as anything in menu
switch(result)
if("New Character")
CreateNewCharacter()
if("Delete Character")
DeleteCharacter()
else
LoadCharacter(result)

DeleteCharacter()
var/result = input("Delete character", "Character Creation") as null|anything in characters

if (result)
savefile.dir.Remove(result)
characters -= result

CreateNewCharacter()
var/char_name
do
char_name = input(src, "What is your name?","New Character") as null|text
if(!char_name)
return
if (ckey(char_name) in characters)
alert("This name cannot pass.")
char_name = null
while(!char_name)

var/char_race = input(src, "What race do you wish to be?", "New Character", "Human") in _races
var/rtype = _races[char_race]
var/mob/new_mob = new rtype()

new_mob.client = client //after creating the new character, you need to set the new mob's client to end the character creation process and suspend the loop.
new_mob.savable = 1
savefile[ckey(char_name)] << new_mob //save the character in the savefile before this mob is garbage collected.

LoadCharacter(char)
var/mob/m
savefile[char] >> m
m.savable = 1 //shouldn't be necessary, but in case you don't want to purge your savefiles.
if(client) m.client = client //this should never happen, but just in case something goes wrong we'll put it here anyway to be safe


mob
var
savable = 0

Login()
src.loc=locate(45,38,1)
src.icon_state = ""
src.sight = 0
client.eye = src
client.perspective = MOB_PERSPECTIVE
src << output("<font color = red>Welcome to One Punch Man, we owe no affiliation to one punch man so don't sue us XD</font>","chatbox")
world << output("<tt><font color = red>{-><font color = blue>[src] has logged in!<font color = red><-}</tt>","chatbox")
sample_report()

Logout()
if(client)
client.Save()
del src

Write(savefile/F)
if(!savable) return
..()

F["last_x"] << x
F["last_y"] << y
F["last_z"] << z

Read(savefile/F)
..()

var/last_x
var/last_y
var/last_z
F["last_x"] >> last_x
F["last_y"] >> last_y
F["last_z"] >> last_z
loc = locate(last_x, last_y, last_z)

proc
sample_report()
src << "<b><font size = 1><font color = silver><center>By: Dragonpear321"
src << "<b>Beta Testing One Punch Man"


I changed a few things. The major problems was that during character creation, you were never actually assigning the client to the created mob. You need to do that to kill the menu loop, which depends on the creating character mob having an assigned client.

I also reduced the number local of variables you are using. If a value doesn't change, it shouldn't be a variable. It should be a constant.

Another thing that I fixed was your mob/Login() proc. You were using a look-down inheritance model to stop sending sample_report() if the mob's type was a character creation thing. Instead, I took advantage of polymorphic overrides and simply fully overrode the behavior that would display that message and didn't perform a supercall.

I removed your client/LoadMob function because I'd much prefer to keep the savefile open for the duration of time that it's being manipulated. This is faster and has less chance for failure. The character creation mob will take care of loading mobs and will also perform an initial save after creation is completed.

Another thing that I added was a variable called "savable" to the mobs. This will ensure that only character mobs ever wind up getting saved. These are set to 1 whenever a player loads or creates a new character from the character creation menu, but are set to 0 for every other character.
In response to Ter13
Sir you are a byond genius. Not only did you modify it or me you also gave me an explanation as to so I do not do it again, I dont know how I would ever repay you.
Not only did you modify it or me you also gave me an explanation as to so I do not do it again

You didn't actually do anything overly wrong. You just have some unnecessary habits, and are learning. You are doing more than fine.

I dont know how I would ever repay you.

Keep bringing me interesting problems and keep learning to program so your problems can start stumping me and challenging me to learn more.

Deal?
In response to Ter13
Deal! Also I have one question, after I modified your code to suit my needs I compiled it and I got errors with F.cd and F.dir, I must wonder what does the F. stand for and contribute?
Edited. F was supposed to have been changed to savefile. Minor typos.
In response to Ter13
These errors popped up when I tried to create new character and I cannot make sense of it o.o
runtime error: list index out of bounds
proc name: CreateNewCharacter (/mob/other/choosing_character/proc/CreateNewCharacter)
usr: (src)
src: Dragonpearl123 (/mob/other/choosing_character)
src.loc: null
call stack:
Dragonpearl123 (/mob/other/choosing_character): CreateNewCharacter()
Dragonpearl123 (/mob/other/choosing_character): ChooseCharacter()
Dragonpearl123 (/mob/other/choosing_character): Login()

Edit/:Upon further inspection I saw that the runtime error only occurs whenever I create a new character and the only list associated to new characters is the pick races, because it goes to the type my name part right.
Fixed another minor typo in the global _races list. I accidentally put one too many equals signs in it. It should be fixed now.
In response to Ter13
Finally! I want to say thanks for the help and Happy New Years, and for a present I found one stumping problem. Every time I want to use the char name for anything I use the brackets [char_name], and I get the following error, 119:error: char_name: undefined var. Using this code,
world << output("<font color=purple><b>[char_name] has joined the ranks</b></font>", "chatbox")
and I can't add it to my OOC code because I get the same error
world << output("<font color=blue>{[rank]}</font><font color=red>{[usr.name]}</font>: <i><font color=white>[t]</font>","chatbox")
Surely by now you get the point it is really frustrating I spent a better part of my day doing it, since I didn't want to disturb you on this merry day, then I thought what better new years present than this.

Edit/bonus: I feel like this is also preventing me from viewing the admins tab, but I also assume its because i'm playing solo and It is not being hosted at the moment. If youre interested all the code/verbs I have for the admins are
mob/Login()
..()
if(src.ckey=="Dragonpearl123", "Jamarcus mosley")
src.verbs += typesof(/mob/admin/verb)

mob/admin/verb
Rename(mob/M in world, name as text)
set category = "Admin"
src << "You rename [M]."
M.name = "[name]"
src << "The new name is [M]."

mob/admin/verb
Reboot()
set category="Admin"
switch(input("Reboot the world?")in list("Yes","No"))
if("Yes")
world.Reboot()

Edit Edit/ Bonus Bonus:This is the last one I promise, this one is short too. The save file saves char name but that is about it. All the stats that are attached to mob are supposed to be save together aren't they? Even the location doesn't get saved.
src.ckey=="Dragonpearl123", "Jamarcus mosley"

You've got a bit of an error here. The comma is invalid. Also, ckey is all lowercase and has spaces removed. You will want to use key instead of ckey or "==" won't ever work.

A better approach is to use an associative list for admins:

var
list/admins = list("Dragonpearl123"=1,"Jamarcus mosley"=1)
mob
Login()
..()
if(admins[key])
verbs += typesof(/mob/admin/verb)


119:error: char_name: undefined var. Using this code,

An undefined variable means that the variable of that name has not been properly defined in the scope you are attempting to use it. char_name was a local variable within CharCreate() it won't continue to exist outside of that function because local variables are tied to the function themselves.

You should read up on "variable scope". It's an important concept.


The save file saves char name but that is about it. All the stats that are attached to mob are supposed to be save together aren't they? Even the location doesn't get saved.

Well, only variables that have actually been changed from their default value, and aren't marked temporary will be saved.
In response to Ter13
Again thank you for you have proven your wisdom. How would I define char_name outside of CharCreate() without prompting user twice for a name? or would it be a new var and make it equal to char_name. No that wouldnt work because you cant define it outside of CharCreate()
Atoms already have a variable called name. during character creation, you will want to assign the mob you are creating for the character the name the player entered and was stored in char_name.
In response to Ter13
Atoms already have a variable called name. during character creation, you will want to assign the mob you are creating for the character the name the player entered and was stored in char_name.
How would I do that without defining it inside the variable, all solutions I visualize wouldn't work.
Well, only variables that have actually been changed from their default value, and aren't marked temporary will be saved.
It doesnt even save movement which is not supposed to be temp unless it is default temp, if so is there a guide into where I can read up on how to make a variable stay changed from default value.
In response to Ter13
world
mob = /mob/other/choosing_character
name = "One Punch Man"
hub_password = "omolewa"
view = 7
fps = 10
version = 1.0
status = "<B><font size = -2><font color = green>One Punch Man</font> <font color = purple>{Version Beta 1.0}</font>"
hub = "Dragonpearl123.onepunchman"
sleep_offline = 0
map_format = TOPDOWN_MAP
icon_size = 32



var/list/_races = list("Human"=/mob/characters/Human, "Mage"=/mob/characters/Mage) //obviously, modify this to suit your races.

client
proc
Save()
if(mob.savable)
var/savefile/savefile = new("players/[copytext(ckey, 1, 2)]/[ckey].sav")
savefile["/[ckey]/[ckey(mob.name)]"] << mob

mob/other/choosing_character
var
list/characters = list()
savefile/savefile
Login()
client.eye = locate(rand(1,150),rand(1,150),1)
client.perspective = EYE_PERSPECTIVE
spawn()
ChooseCharacter()

proc
ChooseCharacter()
//we don't need to reload the savefile more than once. Store it and keep the chars list around
savefile = new("players/[copytext(ckey, 1, 2)]/[ckey].sav")
savefile.cd = "/[ckey]"
characters = savefile.dir
var/list/menu //it's best to define these outside of a loop where possible. There are reasons.
var/result
while(client)
menu = characters + "New Character" + "Delete Character"

result=input("Choose an option", "One Punch Man") as anything in menu
switch(result)
if("New Character")
CreateNewCharacter()
if("Delete Character")
DeleteCharacter()
else
LoadCharacter(result)

DeleteCharacter()
var/result = input("Delete character", "Character Creation") as null|anything in characters

if (result)
savefile.dir.Remove(result)
characters -= result

CreateNewCharacter()
var/char_name
do
char_name = input(src, "What is your name?","New Character") as null|text
if(!char_name)
return
if (ckey(char_name) in characters)
alert("This name isn't acceptable.")
char_name = null
while(!char_name)

var/char_race = input(src, "What race do you wish to be?", "New Character", "Human", "Mage") in _races
var/rtype = _races[char_race]
var/mob/new_mob = new rtype()
if(prob(10))
src<<"You were born with some of saitamas bloos inside of you, giving you the potential to be like him!"
src.potential = "All"
else
src<<"You were born as a commoner, tough luck!"
src.potential = "???"
play_cutscene()
new_mob.client = client //after creating the new character, you need to set the new mob's client to end the character creation process and suspend the loop.
new_mob.savable = 1
new_mob.name = char_name
savefile[ckey(char_name)] << new_mob //save the character in the savefile before this mob is garbage collected.

LoadCharacter(char)
var/mob/m
savefile[char] >> m
m.savable = 1 //shouldn't be necessary, but in case you don't want to purge your savefiles.
if(client) m.client = client //this should never happen, but just in case something goes wrong we'll put it here anyway to be safe


mob
var
savable = 0

Login()
src.loc=locate(44,39,1)
src.icon_state = ""
src.sight = 0
client.eye = src
client.perspective = MOB_PERSPECTIVE
src << output("<b><font color = red>Welcome to One Punch Man The Game, we owe no affiliation to one punch man so don't sue us XD</font>","system")
world << output("<font color=purple><b>[usr.name] has joined the ranks</b></font>", "chatbox")
sample_report()

Logout()
if(client)
client.Save()
del src

Write(savefile/F)
if(!savable) return
..()

F["last_x"] << x
F["last_y"] << y
F["last_z"] << z

Read(savefile/F)
..()

var/last_x
var/last_y
var/last_z
F["last_x"] >> last_x
F["last_y"] >> last_y
F["last_z"] >> last_z
loc = locate(last_x, last_y, last_z)

proc
sample_report()
src << output("<b><font size = 1><font color = silver><center>By: Dragonpear321","system")
src << output("<b>Beta Testing One Punch Man","system")
All of a sudden it stopped saving it doesnt save location, level stats or nothing!
Page: 1 2