I'm not seeing where save_deck() is called from your main save routine, and I don't see any load routine for decks--which is odd because that's the routine you say is having the actual problem.
the save deck isn't called by the main save, it's the other way around.

Saving your deck will cause the main save to be called as well.


When a player saves their deck, those changes are saved to the save file. But a player can make other changes where they wouldnt necissarily need to save their decks again. Like changing their icon or their name.

And the loading of the save and checking decks are both called by the login proc.
This has nothing to do with old save files.

This isn't a matter of a player not being around for a while, me moving some cards since they've been gone, and then then them coming back and the card's type paths being changed.

We have 2 servers being hosted right now. 1 is being hosted on a windows server and the other is being hosted on a linux server.

They're both hosting the same version of the game, and both using up to date versions of byond.

If I load my save file on the windows server, it will load fine. If I load my save file on the linux server, it will give me type path errors.

It's not a problem with this specific server either because I've tried to host personally on a linux server and gotten the same issues, as well as several other players who have tried to help out the game by providing hosting.

It's not an error with a specific card. 2 people can log in using the same cards in their decks but get entirely different type path errors. But the errors aren't random because the same person will always get the same type path errors.

As in... Player 1 and Player 2 both have cards A B and C in their deck. Player 1 will always have Card B give them an error every time they log in, but Player 2 gets problems with Card A.
But where is the deck loading code? I see player loding; I do not see deck loading. Where is that happening?
On reviewing release notes, the specific bug I fixed with TextToType() (the internal routine that handles text2path() and also is used in savefile loads) only impacted mob types; that fix is in 511.1355.

I really don't see how this routine could fail for a type path lookup from a savefile, especially how it could differ between the two platforms (unless somehow newline characters were being interpreted incorrectly).

Also if this has been going on since 2012, then 508 and 509 are not free of the problem. Nothing changed in 510 that should impact this negatively, and I know this problem was around for longer than that.
mob/Login()
world.log << "[src.key] logging in..."
var/rsc_f = list(
'bracket.dmi',
'win_victory_ico.png',
'stat_d_free.png','stat_d_full.png','stat_d_rank.png',
'vs_battle.png','vs_p.png','exodia.dmi',
'ex_decal_l.png','ex_decal_r.png','g_duel.png','t_duel.png',
'chain_txt.png',
'options_button_dpj.png','options_button_dpj_off.png','options_button_atk_jp.png','options_button_atk_us.png',
'pflag_australia.png','pflag_belgium.png','pflag_canada.png','pflag_china.png','pflag_england.png',
'pflag_estonia.png','pflag_france.png','pflag_germany.png','pflag_japan.png','pflag_korea.png','pflag_netherlands.png',
'pflag_uk.png','pflag_usa.png','pflag_new_zealand.png','pflag_denmark.png','pflag_wales.png','pflag_ireland.png','pflag_puerto_rico.png',
'pf_deck_count_01.png','pf_deck_count_02.png',
'blank_01.png','blank_02.png','blank_03.png',
'pb_inventory_gold.png','pb_inventory_grey.png','pb_badge.png','pb_badge_g.png','tg_synchro.png',
'dsc_lt.png','dsc_north.png','dsc_rt.png','dsc_west.png','dsc_east.png','dsc_lb.png','dsc_south.png','dsc_rb.png',

'p_dsc_lt.png','p_dsc_north.png','p_dsc_rt.png','p_dsc_west.png','p_dsc_east.png','p_dsc_lb.png','p_dsc_south.png','p_dsc_rb.png',

'full_mark.png', 'full_mark_draw.png', 'full_mark_draw_2.png', 'dark_sign_draw.png',
'blank_badge_bg.png',
'head_bg.png','head_name_bg.png','head_badge_bg.png','head_about_bg.png',
'tail_bg.png','tail_name_bg.png','tail_badge_bg.png','tail_about_bg.png',
'foot_bg.png','foot_name_bg.png','foot_badge_bg.png','foot_about_bg.png',
'wing_bg.png','wing_name_bg.png','wing_about_bg.png',
'hand_bg.png','hand_name_bg.png','hand_about_bg.png',
'heart_bg.png','heart_name_bg.png','heart_about_bg.png',
'condor_bg.png','condor_name_bg.png','condor_about_bg.png',
'giant_bg.png','giant_name_bg.png','giant_about_bg.png',
'hummingbird_bg.png','hummingbird_name_bg.png','hummingbird_about_bg.png',
'lizard_bg.png','lizard_name_bg.png','lizard_about_bg.png',
'monkey_bg.png','monkey_name_bg.png','monkey_about_bg.png',
'spider_bg.png','spider_name_bg.png','spider_about_bg.png',
'whale_bg.png','whale_name_bg.png','whale_about_bg.png',


'save_icon.png',
'restricted_list_title.png','forbidden_title.png','limited_title.png','semilimited_title.png',
'dcard_n.png','attack_decal.png','flip_fd.png',
'A_CONTINUOUS.png','A_COUNTER.png','A_EQUIP.png','A_FIELD.png','A_QUICK-PLAY.png','A_RITUAL.png',
'level_star.png','rank_star.png','level_star_s.png','rank_star_s.png','dark_star.png','dark_star_s.png',
'p_scale_blue.png','p_scale_red.png',
'ico_dark.png','ico_divine.png','ico_earth.png','ico_magic.png',
'ico_trap.png','ico_water.png','ico_wind.png','ico_fire.png','ico_light.png',
'blue_card_bg.png','blue_card_bg_h.png','red_card_bg.png','red_card_bg_h.png','yell_card_bg.png','yell_card_bg_h.png',
'normal_card_bg.png','normal_card_bg_h.png','effect_card_bg.png','effect_card_bg_h.png','fusion_card_bg.png','fusion_card_bg_h.png',
'ritual_card_bg.png','ritual_card_bg_h.png','synchro_card_bg.png','synchro_card_bg_h.png','xyz_card_bg.png','xyz_card_bg_h.png','dsynchro_card_bg.png','dsynchro_card_bg_h.png',
'spell_card_bg.png','spell_card_bg_h.png','spell_card_bg_seal.png','trap_card_bg.png','trap_card_bg_h.png','token_card_bg.png','token_card_bg_h.png',
'txt_dname_stat.png','txt_grfg_stat.png','txt_hde_stat.png','txt_lp_stat.png','options_cback_disabled.png',
'dd_bc02.png','dd_select.png','dd_select_no.png','dd_locked.png',
'p_effect_card_bg.png','p_normal_card_bg.png','p_xyz_card_bg.png','p_synchro_card_bg.png','p_fusion_card_bg.png',
'zarc_card_bg.png','zarc_card_bg_h.png')

for(var/v in rsc_f) src << browse_rsc(v,"[v]")

winset(src, "_load.fixed_ver", {"text="[_ver(world.version)]""})

if(loc)

if(istype(src,/mob/NPC)) return null

overlays -= typesof(/obj/overlays/emote/logout)

if(!rod_key) rod_key = src.key

if(isduel)

for(var/client/M) if(M.mob) if(src in M.mob.SeeDuel)

M << output({"<center><font color=green><i>[src.name] ([src.key]) has reconnected.</i></font></center>"}, "chat_duel.output")

if(src.Opponents.len) if(M.mob == src || src.Opponents.Find("[M.mob.name] ([M.mob.key])")) // LOG FOR OPPONENT AND PLAYER ONLY
M.mob.d_log += "<font color=#4972d0>[time2text(world.timeofday,"DD MMM, hh:mm:ss")] - [usr.name] - Reconnected to the Duel.</font>"

switch(dir)
if(EAST) client.eye = locate(src.x+3,src.y,src.z)
if(WEST) client.eye = locate(src.x-3,src.y,src.z)
if(NORTH) client.eye = locate(src.x,src.y+3,src.z)
if(SOUTH) client.eye = locate(src.x,src.y-3,src.z)

winset(src, "_main", "statusbar=true;menu=duel_m")
winset(src, "info_.header", "left=info_duel")
winset(src, "_main", "macro=duel_g")

if(src.tag_)
winset(usr, "chat.func", "tabs='+chat_tag'")

winset(src, "chat.func", "current-tab='chat_duel'")

HUD()
Make_Deck_Obj()
Make_Hand_Cards()

client.screen += dOBJ

isclick = 0
isbusy = 0
talk = 0

else

winset(src, "_main", "statusbar=true;menu=main_m")
winset(src, "_main", "macro=normal")

if(isedit)

usr.UpdateDeck()
usr.UpdateExtra()
usr.UpdateSide()
usr.UpdateSearch()
usr.UpdateSet()

usr.center_win("_search","_dedit")
winset(usr, "dedit_sets.tabs", "current-tab=grid_set")
winset(usr, "dedit_main.deckname", "text=\"New Deck\"")
winset(usr, "cinfo.info", "left=blank")
winset(usr, "_dedit", "is-visible=true")

winset(src, "_main", "macro=normal")

if(!winexists(src, "_cerror"))
winclone(src, "_dialog", "_cerror")
winset(src, "_cerror.ok", {"command='.winset \"_cerror.is-visible=false\"'"})

if(!winexists(src, "_cdrop"))
winclone(src, "_dialog", "_cdrop")
winset(src, "_cdrop.ok", {"command='.winset \"_cdrop.is-visible=false\"'"})

winset(src, "_main.m", "left=lpane;right=rpane")
winset(src, "_map.map1", "icon-size=32")

else

// PASSWORD START

if(global.keyword) if(!IsAdmin() && !IsMaster())

winset(src, "_load.password", "is-visible=true")
winset(src, "_load.code", "is-visible=true")
winset(src, "_load.hi", {"text="Time Left: 200"})
src << output("Enter password....", "_load.info")

var/getkey = winget(src,"_load.code","text")
var/ticktock = 1

while(getkey != keyword)

if(ticktock>200)
src<<output("Timed out.", "_load.info")
del src

getkey = winget(src,"_load.code","text")

ticktock++

winset(src, "_load.hi", {"text="Time Left: [200-ticktock]"})

sleep(1)

// PASSWORD END

if(IsHost())

if(!GM.Find(key)) GM += key

host = key

client.Load()
client.Get_Hub()

sleep(-1)

dir = SOUTH
tag = "[ckey]"

winset(src, "_load.progress", "value=100")
src << output("Loading world....", "_load.info")
sleep(50)


// WARP

density = 0

if(isnew) Move(locate(14,16,2))

else if(lastloc.len == 3 && lastloc[3] == 1 && lastv >= world.version)

var/turf/T = locate(lastloc[1],lastloc[2],lastloc[3])

if(isnull(T)) Move(locate(pick(74,75,76,77,78,79,70),76,1))
else if(istype(T,/turf/DUEL) || T.density) Move(locate(pick(74,75,76,77,78,79,70),88,1))
else if(lastloc[1] == 7 && lastloc[2] == 82 && lastloc[3] == 1) Move(locate(lastloc[1],lastloc[2]+2,lastloc[3]))
else Move(locate(lastloc[1],lastloc[2],lastloc[3]))

else switch(rand(1,4))
if(1) Move(locate(pick(74,75,76,77,78,79,70),88,1))
if(2) Move(locate(71,82,1))
if(3) Move(locate(83,82,1))
if(4) Move(locate(pick(74,75,76,77,78,79,70),76,1))

if(lastv < world.version)
avatar = pick('a_red.dmi','a_blue.dmi')
Config -= Config["avatar"]
Config["crdsize"] = 12

density = 1

print_name()

if(!isnum(Config["hud"])) switch(Config["hud"])
if("Duelist Kingdom") Config["hud"] = 1
if("Battle City") Config["hud"] = 2
if("Card Professor") Config["hud"] = 3
if("Yusei Disk") Config["hud"] = 6

// WARP END

if(!CName(name)) name = key

IconCheck()

CheckTrunk(src)

if(!hub_favgame(src)) src << {"<br><center><b><font size=1>Please consider supporting "[world.name]" by adding it as a favorite.</font></b></center><br>"}

if(isnew&&!sp)
world << "<font color=#649B7A><b>CARDinal:</b> [name] ([key]) has just arrived in Domino City.</font>"
src << "<center>Remember to take a few moments to visit the Forum. It contains lots of useful information on the game, including a few player made guides.<br>You will also find help for any issues you may encounter.</center>"

var/mob/NPC/N = locate("npcsolomon")
flick("Solomon Talk",N)
src<<{"<IMG SRC=\ref[N.avatar] width="24" height="24"><b>[N.name]: </b>Welcome to Domino City [name]. You look new here, perhaps you should take a look at some of our Starter Decks and familiarize yourself with your Duel Disk. If you need any more help getting started you can always visit the forum at <b>http://www.gamerscripts.com/dmg</b>."}

else world << "<font color=#6F6F6F><b>CARDinal:</b> [name] ([key]) has entered Domino City.</font>"
//if(IsMaster()) world << "<font color=#E0A3A9><b>Yui-MHCP001:</b></font> Mama?"

for(var/client/C) if(C.mob)
if(C.key != key) if(C.computer_id == client.computer_id)
world<<"<font color=#8D4A4A><b>CARDinal:</b> [name] ([key]) has entered Domino City. Suspicious activity detected, [C.mob.name] ([C.mob.key]) is also using their terminal.</font>"
log_gm(time2text(world.timeofday,"DD MMM, hh:mm:ss"),name,key,"Multikeying",{"Connected as [C.mob.name] ([C.key])."},"BB86CE")

log_c(time2text(world.timeofday,"DD MMM, hh:mm"),name,key,client.computer_id,client.address)

verbs += typesof(/mob/hud_verb/verb)

//if(lastv<world.version && !motd)
// whatsnew(lastv)

//if(motd)
// show_motd()

if(isnew)

show_options()

sleep(-1)

set_pf()

// START OF SKIN ADJUSTMENTS

winset(src, "_main", "menu=main_m")
winset(src, "_main.m", "left=lpane;right=rpane")
winset(src, "_map.map1", "icon-size=32")

if(!winexists(src, "_cerror"))
winclone(src, "_dialog", "_cerror")
winset(src, "_cerror.ok", {"command='.winset \"_cerror.is-visible=false\"'"})

if(!winexists(src, "_cdrop"))
winclone(src, "_dialog", "_cdrop")
winset(src, "_cdrop.ok", {"command='.winset \"_cdrop.is-visible=false\"'"})

winset(src, "_main", "statusbar=true;menu=main_m")
winset(src, "info_.header", "left=info_profile")
winset(src, "_main", "macro=normal")

Text["atktxt"] = rand(1,2)

if(!Config["cback"]) Config["cback"] = 1

var/mob/NPC/mokuba/K = locate("npcmokuba") /// NPC ITEM RETURN

if(K && K.items.len) for(var/obj/items/I in K.items) if(I.owner == src.key) if(!K.evil)
src.items += I
K.items -= I
I.Move(src)

//if(locator) make_locators(src)

winset(src, "options_m.map", "value=[msize]")
usr << output("[round(usr.msize*32)] x [round(usr.msize*32)]", "options_m.mres")

switch(pixel_c)
if(6) winset(src, "options_m.hand", "value=0")
if(12) winset(src, "options_m.hand", "value=50")
if(32) winset(src, "options_m.hand", "value=100")

if(!chat)
winset(src, "_messages.toggle", "background-color=#E40E49")
winset(src, "_messages.toggle", {"text="Busy""})
else
winset(src, "_messages.toggle", {"text="Available""})
winset(src, "_messages.toggle", "background-color=#0CBA63")

if(Config["f"]) winset(src, "chat_global.filter", "text=\"Filter On\"")
else winset(src, "chat_global.filter", "text=\"Filter Off\"")

// TM & RM MEDAL START

if(!IsMaster())

if(world.GetMedal("Game Administrator", key))

if(!GA.Find(key)) GA += key

if(TM.Find(key)) TM -= key
if(GM.Find(key)) GM -= key
if(RM.Find(key)) RM -= key
if(IC.Find(key)) IC -= key

else if(world.GetMedal("Tournament Moderator", key))

if(!TM.Find(key)) TM += key

if(GM.Find(key)) GM -= key
if(RM.Find(key)) RM -= key
if(GA.Find(key)) GA -= key

else if(world.GetMedal("Rule Moderator", key))

if(!RM.Find(key)) RM += key

if(TM.Find(key)) TM -= key
if(GA.Find(key)) GA -= key


else if(world.GetMedal("Icon Contributor", key))

if(!IC.Find(key)) IC += key


else

GA -= key
TM -= key
RM -= key

// TM & RM MEDAL END

sleep(-1)

KillGM()
MakeGM()

//if(sp) last_online()

..()


//IceFire2050 - Icon Correction for Armor Overlays if a player saved during a duel.
if(usr.icon_state == "*Armor Head")
usr.icon_state = "Doma 4"

world.log << "...[src.key] login successful."
return


That's our login code.

client.Load()

is called and then a bit farther down we have

CheckTrunk(src)


which is....

proc/CheckTrunk(mob/M)

var/list/colors = icon_states('decks.dmi')
var/list/ntrunk = list()

for(var/obj/decks/C in M.trunk) if(C)

if(!C.name)
M.trunk -= C
del(C)
continue

if(!colors.Find(C.icon_state)) C.icon_state = "Black"
if(!C.code) C.code = makeobjcode(M)
if(C.name != "[TxtCheck("D",C.name)]") C.name = "Deck [C.code]"

C.main = Check_Objs(M,C.main,C.name)
C.side = Check_Objs(M,C.side,C.name)
C.extra = Check_Objs(M,C.extra,C.name)

ntrunk += C

M.trunk.Cut()

M.trunk = ntrunk

return


Which is where the Check_Objs code i posted earlier is called.
Whoa there. You have usr abuse going on in Login(). It's unrelated to your issue, but you should still fix it.
In response to Lummox JR
Lummox JR wrote:
usr abuse

byond linter when?
Page: 1 2