Godot Version
4.4.1
Question
I have no clue why this fails only after it gets run through steam.
I’m posting the whole file for visibility but the real culprit is the “save_achieve_data”, “save_endings_data”, “load_acheivements_data”, and “load_endings_data” functions.
Running the game through Godot DEBUG or even as the exported .exe works just fine. As you can see below “achievements.dat” and “endings.dat” are created.
The problem is, once I upload it to Steam it no longer wants to work. It refuses to create these files, and it won’t read them if they happen to already be in there.
What’s weird is I checked the path as a print through ProjectSettings.globalize_path(Achievements.achieve_save_path) and I just get null, only when through Steam of course.
“item_save_info.save” is created in pretty much the exact same way in a different script, but it is created and read just fine.
I’m kind of at a loss for what to do here, as I have no clue what this could be happening.
extends Node
const achieve_save_path = "user://achievements.dat"
var achievement_save_data: Dictionary = {
"Completed": [],
"InProgressCount": []
}
var numachievements: int = 10
var achievementName: Array = []
var achievementUnlockdesc: Array = []
var achievementCountneeded: Array = []
var achievementCountresetonrun: Array = []
const ACHIEVE_JSON_DATA = "res://data/Achievements.json"
const ending_save_path = "user://endings.dat"
var ending_save_data: Array = [false, false, false, false]
func _ready() -> void:
init_json_data()
await get_tree().physics_frame
load_acheivements_data()
load_endings_data()
await get_tree().create_timer(0.3).timeout
initialize_steam()
func load_json(path: String):
var file = FileAccess.get_file_as_string(path)
var json
if file != null:
json = JSON.parse_string(file)
else:
print("error importing file")
return json
func init_json_data() -> void:
var json = load_json(ACHIEVE_JSON_DATA)
if json != null:
numachievements = json.size()
initialize_tables()
await get_tree().physics_frame
for i in range(0, numachievements):
parse_json(i, json[str(i)])
else:
print("error initalizing Items.json")
func parse_json(ID: int, json: Dictionary):
achievementName[ID] = json["NAME"]
achievementUnlockdesc[ID] = json["UNLOCKDESCR"]
achievementCountneeded[ID] = json["COUNTNEEDED"]
achievementCountresetonrun[ID] = json["RESETCOUNTSONRUN"]
func initialize_tables():
achievementName.resize(numachievements)
achievementName.fill("name")
achievementUnlockdesc.resize(numachievements)
achievementUnlockdesc.fill("descr")
achievementCountneeded.resize(numachievements)
var count: int = 0
achievementCountneeded.fill(count)
achievementCountresetonrun.resize(numachievements)
achievementCountresetonrun.fill(false)
func load_acheivements_data():
if not FileAccess.file_exists(achieve_save_path):
var starting_ID: int = 0
create_achieve_save_data(starting_ID)
return
var file = FileAccess.open(achieve_save_path, FileAccess.READ)
achievement_save_data = file.get_var(true)
file.close()
#print(item_data)
check_completed_achievements()
if achievement_save_data["Completed"].size() < numachievements:
print("achievement counts dont match")
var starting_ID: int = achievement_save_data["Completed"].size()
create_achieve_save_data(starting_ID)
#print(achievement_save_data)
func load_endings_data():
#Endings
if not FileAccess.file_exists(ending_save_path):
save_endings_data()
return
var file2 = FileAccess.open(ending_save_path, FileAccess.READ)
ending_save_data = file2.get_var(true)
file2.close()
func save_achieve_data():
var file = FileAccess.open(achieve_save_path, FileAccess.WRITE)
file.store_var(achievement_save_data,true)
file.close()
func save_endings_data():
var file = FileAccess.open(ending_save_path, FileAccess.WRITE)
file.store_var(ending_save_data,true)
file.close()
func create_achieve_save_data(starting_ID: int):
#print("create")
for i in range(starting_ID, numachievements):
achievement_save_data["Completed"].append(false)
achievement_save_data["InProgressCount"].append(0)
#var path = ProjectSettings.globalize_path(achieve_save_path)
#DirAccess.make_dir_recursive(path)
save_achieve_data()
await get_tree().physics_frame
initialize_steam()
func check_completed_achievements():
for itemID in range(Items.numitems):
if Items.itemLocked[itemID]:
var achieveID: int = Items.itemAchieveID[itemID]
#print(achieveID)
if achievement_save_data["Completed"][achieveID]:
Items.itemLocked[itemID] = false
func get_item_achieve_completed(itemID: int):
var achieveID: int = Items.itemAchieveID[itemID]
return achievement_save_data["Completed"][achieveID]
func get_item_achieve_count(itemID: int):
var achieveID: int = Items.itemAchieveID[itemID]
return achievement_save_data["InProgressCount"][achieveID]
func item_increase_achieve_count(itemID: int):
var achieveID: int = Items.itemAchieveID[itemID]
if not achievement_save_data["Completed"][achieveID]:
achievement_save_data["InProgressCount"][achieveID] = achievement_save_data["InProgressCount"][achieveID] + 1
save_achieve_data()
if achievement_save_data["InProgressCount"][achieveID] >= achievementCountneeded[achieveID]:
unlock_achievement(itemID)
func reset_run_dependant_item_counts():
for ID in range(numachievements):
if achievementCountresetonrun[ID]:
achievement_save_data["InProgressCount"][ID] = 0
save_achieve_data()
func item_decrease_achieve_count(itemID: int):
var achieveID: int = Items.itemAchieveID[itemID]
if not achievement_save_data["Completed"][achieveID]:
achievement_save_data["InProgressCount"][achieveID] = achievement_save_data["InProgressCount"][achieveID] - 1
save_achieve_data()
func item_reset_achieve_count(itemID: int):
var achieveID: int = Items.itemAchieveID[itemID]
achievement_save_data["InProgressCount"][achieveID] = 0
save_achieve_data()
func unlock_achievement(itemID: int, bypass_console_lock: bool = false):
if !Globals.can_unlock_achievements and !bypass_console_lock:
return
var achieveID: int = Items.itemAchieveID[itemID]
if not achievement_save_data["Completed"][achieveID]:
print("Achievement '"+achievementName[achieveID]+"' Unlocked")
achievement_save_data["Completed"][achieveID] = true
Items.unlock_item(itemID)
save_achieve_data()
$AchievementNotification.activate(itemID, achieveID)
if Globals.can_unlock_achievements:
var Acheive_API_Name: String = "ACHIEVEMENT_" + str(achieveID)
set_steam_achievement(Acheive_API_Name)
func is_ending_discovered(endingID: int):
return ending_save_data[endingID-1]
func unlock_ending(endingID: int):
#if !Globals.can_unlock_achievements:
#return
if !is_ending_discovered(endingID):
ending_save_data[endingID-1] = true
save_endings_data()
var Acheive_API_Name: String = "ENDING_" + str(endingID)
set_steam_achievement(Acheive_API_Name)
func is_save_completed():
pass
#STEAM API
func initialize_steam() -> void:
var initialize_response: Dictionary = Steam.steamInitEx()
print("Did Steam initialize?: %s" % initialize_response)
if initialize_response['status'] > Steam.STEAM_API_INIT_RESULT_OK:
print("Failed to initialize Steam: %s" % initialize_response['status'])
return
load_steam_achievements()
# Process achievements
func load_steam_achievements() -> void:
for achieveID in range(achievement_save_data.size()):
var Acheive_API_Name: String = "ACHIEVEMENT_" + str(achieveID)
var steam_achievement: Dictionary = Steam.getAchievement(Acheive_API_Name)
# Does the achievement actually exist in the Steamworks back-end?
if not steam_achievement['ret']:
print("Steam does not have this achievement, defaulting to local value: %s" % achievementName[achieveID])
continue
if achievement_save_data["Completed"][achieveID] == steam_achievement['achieved']:
print("Steam achievements match local file, skipping: %s" % achieveID)
continue
set_steam_achievement(Acheive_API_Name)
print("Steam achievements loaded")
#reset_achievement("ACHIEVEMENT_15")
func set_steam_achievement(Acheive_API_Name: String) -> void:
return
#if not achievements.has(Acheive_API_Name):
#print("This achievement does not exist locally: %s" % this_achievement)
#return
#achievements[this_achievement] = true
if not Steam.setAchievement(Acheive_API_Name):
print("Failed to set achievement: %s" % Acheive_API_Name)
return
print("Set acheivement: %s" % Acheive_API_Name)
store_steam_data()
func store_steam_data() -> void:
if not Steam.storeStats():
print("Failed to store data on Steam, should be stored locally")
return
print("Data successfully sent to Steam")
func reset_achievement(Acheive_API_Name: String) -> void:
print("Resetting achievement %s" % Acheive_API_Name)
if not Steam.clearAchievement(Acheive_API_Name):
print("Failed to reset achievement: %s" % Acheive_API_Name)

