0.6.1: Emberwild is now Cinderwild (the old name's taken on Steam). Saves, identity and settings are copied across from the Emberwild folder on first start; the site moves to cinderwild.psbailey.uk; same protocol (18), so 0.6.0 and 0.6.1 play together

This commit is contained in:
Paul Bailey
2026-11-07 16:14:11 +00:00
parent 04b9d17826
commit c2c86b5f78
36 changed files with 262 additions and 173 deletions

View File

@@ -2,16 +2,17 @@ extends Node
## Autoload "Boot", first in the list: one-off start-up housekeeping that has
## to happen before anything reads user://.
##
## The game was called "Valheimlike" until it became "Emberwild". Godot names
## the user-data folder after the project, so the rename moved it from
## .../app_userdata/Valheimlike to .../app_userdata/Emberwild. The first time
## Emberwild starts, this copies saved worlds, your identity (key, name, look)
## and server settings across. It copies rather than moves, so the old folder
## stays as a backup, and it never overwrites anything already in the new
## folder. Test folders (test_*) and logs are skipped.
## The game has been renamed twice: "Valheimlike", then "Emberwild" (0.1.0 to
## 0.6.0), now "Cinderwild". Godot names the user-data folder after the
## project, so each rename moved it (.../app_userdata/<name>). The first time
## Cinderwild starts, this copies saved worlds, your identity (key, name,
## look), settings and server settings across from the newest old folder there
## is (it already holds what came from the one before). It copies rather than moves, so the old folders stay
## as a backup, and it never overwrites anything already in the new folder.
## Test folders (test_*) and logs are skipped.
const OLD_NAME := "Valheimlike"
const MARKER := "migrated_from_valheimlike.txt"
const OLD_NAMES := ["Emberwild", "Valheimlike"] ## newest first
const MARKER := "migrated_from_%s.txt"
const SKIP := ["logs", "shader_cache", "vulkan", "test_worlds", "test_net"]
var copied := 0
@@ -22,14 +23,25 @@ func _enter_tree() -> void:
## Returns the number of files copied (0 if there was nothing to do).
func migrate_user_data() -> int:
var new_dir := OS.get_user_data_dir()
var old_dir := new_dir.get_base_dir().path_join(OLD_NAME)
for old_name in OLD_NAMES:
var old_dir := new_dir.get_base_dir().path_join(old_name)
if DirAccess.dir_exists_absolute(old_dir) and old_dir != new_dir:
# Only the newest: it already holds whatever came across from the
# one before (a world deleted since shouldn't come back).
return migrate_from(old_dir, new_dir, old_name)
return 0
## Copies `old_dir` into `new_dir` once (a marker file in `new_dir` says it's
## been done). Returns the number of files copied.
func migrate_from(old_dir: String, new_dir: String, old_name: String) -> int:
if new_dir == old_dir or not DirAccess.dir_exists_absolute(old_dir):
return 0
if FileAccess.file_exists(new_dir.path_join(MARKER)):
var marker := new_dir.path_join(MARKER % old_name.to_lower())
if FileAccess.file_exists(marker):
return 0
copied = 0
_copy_tree(old_dir, new_dir)
var f := FileAccess.open(new_dir.path_join(MARKER), FileAccess.WRITE)
var f := FileAccess.open(marker, FileAccess.WRITE)
if f != null:
f.store_string("Copied %d files from %s on %s. The old folder was left as it was.\n" % [
copied, old_dir, Time.get_datetime_string_from_system()])
@@ -43,6 +55,8 @@ func _copy_tree(from: String, to: String) -> void:
if da == null:
return
for f in da.get_files():
if f.begins_with("migrated_from_"):
continue # (the old folder's own markers)
var dst := to.path_join(f)
if not FileAccess.file_exists(dst) and DirAccess.copy_absolute(from.path_join(f), dst) == OK:
copied += 1

View File

@@ -1,6 +1,6 @@
extends RefCounted
## Report a bug (0.6.0, the playtest; pause menu): opens a new issue on the
## Emberwild repo in your browser, already filled in with a title to edit,
## Cinderwild repo in your browser, already filled in with a title to edit,
## a few questions to answer, and the details we'd ask for anyway (version,
## computer, single-player or online, which land, the day and time, where you
## are). You read it, add what happened, and press Create Issue: nothing is
@@ -46,7 +46,7 @@ static func mode(world: Node) -> String:
## The details, one per line (what's in the issue, and what "Copy" copies).
static func details(world: Node) -> Dictionary:
var d := {
"Version": "Emberwild %s (protocol %d)" % [String(ProjectSettings.get_setting("application/config/version", "?")), int(_al("Net").PROTOCOL)],
"Version": "Cinderwild %s (protocol %d)" % [String(ProjectSettings.get_setting("application/config/version", "?")), int(_al("Net").PROTOCOL)],
"Computer": "%s %s" % [OS.get_name(), OS.get_version()],
"Graphics": "%s (%s)" % [RenderingServer.get_video_adapter_name(), RenderingServer.get_current_rendering_method()],
"Mode": mode(world),

View File

@@ -1,13 +1,13 @@
extends Node
## The update check (docs/ROADMAP.md, M4 "Updates", first step): is there a
## newer Emberwild than this one? Asked once at start-up, of the feed in
## Project Settings (`emberwild/updates/feed`). The feed is either
## newer Cinderwild than this one? Asked once at start-up, of the feed in
## Project Settings (`cinderwild/updates/feed`). The feed is either
## - a release API answer (Gitea, Forgejo or GitHub `releases/latest`): its
## `version.json` asset is fetched next, and its other assets are the
## downloads, by file name; or
## - a `version.json` itself:
## {"version": "0.2.0", "protocol": 13, "notes": "...", "page": "https://...",
## "downloads": {"macos": {"file": "Emberwild-0.2.0-macos.zip", "sha256": "...",
## "downloads": {"macos": {"file": "Cinderwild-0.2.0-macos.zip", "sha256": "...",
## "size": 61164958, "url": "(optional; else the asset)"},
## "windows": {...}}}
## tools/export.sh writes that file next to the zips, for the release.
@@ -22,7 +22,7 @@ signal checked(state: String)
const TIMEOUT := 10.0
var version: String = String(ProjectSettings.get_setting("application/config/version", "0.0.0"))
var feed: String = String(ProjectSettings.get_setting("emberwild/updates/feed", ""))
var feed: String = String(ProjectSettings.get_setting("cinderwild/updates/feed", ""))
var prefs_path := "user://updates.json"
var enabled := true
## idle | off | checking | current | available | failed
@@ -101,7 +101,7 @@ func _finish(s: String) -> void:
if s == "failed":
print("[updates] couldn't check for updates: ", error)
elif s == "available":
print("[updates] Emberwild %s is out (this is %s)" % [latest_version(), version])
print("[updates] Cinderwild %s is out (this is %s)" % [latest_version(), version])
checked.emit(s)
func _get_json(url: String) -> Variant:
@@ -112,7 +112,7 @@ func _get_json(url: String) -> Variant:
var http := HTTPRequest.new()
http.timeout = TIMEOUT
add_child(http)
var err := http.request(url, ["Accept: application/json", "User-Agent: Emberwild/" + version])
var err := http.request(url, ["Accept: application/json", "User-Agent: Cinderwild/" + version])
if err != OK:
http.queue_free()
error = "couldn't ask %s (%d)" % [url, err]