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

@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Emberwild's own sounds: the music, the ambience beds and the sound effects
"""Cinderwild's own sounds: the music, the ambience beds and the sound effects
that the Kenney CC0 packs don't cover, all synthesised here (no samples, no
third-party audio), so they're ours to release under CC0 too.

View File

@@ -4,9 +4,9 @@
# tools/export.sh # macOS and Windows
# tools/export.sh macOS # just one ("macOS" or "Windows")
#
# build/Emberwild-<version>-macos.zip the .app (universal: Apple silicon + Intel),
# build/Cinderwild-<version>-macos.zip the .app (universal: Apple silicon + Intel),
# ad-hoc signed, not notarised
# build/Emberwild-<version>-windows.zip Emberwild.exe + Emberwild.pck (+ a console
# build/Cinderwild-<version>-windows.zip Cinderwild.exe + Cinderwild.pck (+ a console
# wrapper), unsigned
#
# Needs the Godot export templates for this Godot's version (Editor > Manage
@@ -29,21 +29,21 @@ mkdir -p build
if [ "$which" = all ] || [ "$which" = macOS ]; then
rm -rf build/macos && mkdir -p build/macos
"$GODOT" --headless --path . --export-release "macOS" build/macos/Emberwild.zip > build/export-macos.log 2>&1
if [ -f build/macos/Emberwild.zip ]; then
mv build/macos/Emberwild.zip "build/Emberwild-$VERSION-macos.zip"
echo "built build/Emberwild-$VERSION-macos.zip"
"$GODOT" --headless --path . --export-release "macOS" build/macos/Cinderwild.zip > build/export-macos.log 2>&1
if [ -f build/macos/Cinderwild.zip ]; then
mv build/macos/Cinderwild.zip "build/Cinderwild-$VERSION-macos.zip"
echo "built build/Cinderwild-$VERSION-macos.zip"
else
echo "macOS export failed: see build/export-macos.log"; exit 1
fi
fi
if [ "$which" = all ] || [ "$which" = Windows ]; then
rm -rf build/windows && mkdir -p build/windows/Emberwild
"$GODOT" --headless --path . --export-release "Windows" build/windows/Emberwild/Emberwild.exe > build/export-windows.log 2>&1
if [ -f build/windows/Emberwild/Emberwild.exe ]; then
(cd build/windows && rm -f "../Emberwild-$VERSION-windows.zip" && zip -qr "../Emberwild-$VERSION-windows.zip" Emberwild)
echo "built build/Emberwild-$VERSION-windows.zip"
rm -rf build/windows && mkdir -p build/windows/Cinderwild
"$GODOT" --headless --path . --export-release "Windows" build/windows/Cinderwild/Cinderwild.exe > build/export-windows.log 2>&1
if [ -f build/windows/Cinderwild/Cinderwild.exe ]; then
(cd build/windows && rm -f "../Cinderwild-$VERSION-windows.zip" && zip -qr "../Cinderwild-$VERSION-windows.zip" Cinderwild)
echo "built build/Cinderwild-$VERSION-windows.zip"
else
echo "Windows export failed: see build/export-windows.log"; exit 1
fi
@@ -58,7 +58,7 @@ out = {"version": version, "protocol": protocol, "date": datetime.date.today().i
if notes:
out["notes"] = notes
for plat in ("macos", "windows"):
f = "build/Emberwild-%s-%s.zip" % (version, plat)
f = "build/Cinderwild-%s-%s.zip" % (version, plat)
if os.path.exists(f):
h = hashlib.sha256(open(f, "rb").read()).hexdigest()
out["downloads"][plat] = {"file": os.path.basename(f), "sha256": h, "size": os.path.getsize(f)}

View File

@@ -20,12 +20,12 @@ AUTH="Authorization: token $GITEA_TOKEN"
git ls-remote --exit-code origin "refs/tags/$TAG" >/dev/null || { echo "push the tag first: git push origin $TAG"; exit 1; }
BODY=$(python3 -c "import json,sys; print(json.dumps({'tag_name': sys.argv[1], 'name': 'Emberwild ' + sys.argv[2], 'body': sys.argv[3], 'draft': False, 'prerelease': False}))" "$TAG" "$VERSION" "$NOTES")
BODY=$(python3 -c "import json,sys; print(json.dumps({'tag_name': sys.argv[1], 'name': 'Cinderwild ' + sys.argv[2], 'body': sys.argv[3], 'draft': False, 'prerelease': False}))" "$TAG" "$VERSION" "$NOTES")
ID=$(curl -s -H "$AUTH" -H "Content-Type: application/json" -d "$BODY" "$API/releases" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id') or ''); sys.stderr.write(d.get('message','') + '\n') if not d.get('id') else None")
[ -n "$ID" ] || { echo "couldn't create the release (above)"; exit 1; }
echo "release $TAG created (id $ID)"
for f in version.json "Emberwild-$VERSION-macos.zip" "Emberwild-$VERSION-windows.zip"; do
for f in version.json "Cinderwild-$VERSION-macos.zip" "Cinderwild-$VERSION-windows.zip"; do
[ -f "build/$f" ] || { echo "missing build/$f"; exit 1; }
R=$(curl -s -H "$AUTH" -F "attachment=@build/$f" "$API/releases/$ID/assets?name=$f")
echo "$R" | grep -q '"browser_download_url"' && echo " uploaded $f" || { echo " upload of $f failed: $R"; exit 1; }
@@ -34,7 +34,7 @@ done
# Check what anyone downloads is what was built.
REPO=${API%/api/v1/repos/*}/$(echo "$API" | sed 's#.*/repos/##')
for p in macos windows; do
f="Emberwild-$VERSION-$p.zip"
f="Cinderwild-$VERSION-$p.zip"
want=$(python3 -c "import json,sys; print(json.load(open('build/version.json'))['downloads'][sys.argv[1]]['sha256'])" $p)
got=$(curl -s -L "$REPO/releases/download/$TAG/$f" | shasum -a 256 | cut -d' ' -f1)
[ "$want" = "$got" ] && echo " $f: checksum ok" || { echo " $f: CHECKSUM MISMATCH"; exit 1; }

View File

@@ -1,11 +1,11 @@
## Getting started {#getting-started}
Emberwild drops you on a wooded island ringed by mountains, with a lake in the middle and sea cliffs on one side. You start with nothing: everything comes from the island.
Cinderwild drops you on a wooded island ringed by mountains, with a lake in the middle and sea cliffs on one side. You start with nothing: everything comes from the island.
### Installing
- **Mac:** unzip and move Emberwild to Applications. It isn't notarised by Apple, so the first time, right-click it and choose **Open** (or System Settings > Privacy & Security > Open Anyway).
- **Windows:** unzip and run `Emberwild.exe`. Keep `Emberwild.pck` in the same folder or the game won't start. It's unsigned, so if SmartScreen says "Windows protected your PC", choose **More info**, then **Run anyway**.
- **Mac:** unzip and move Cinderwild to Applications. It isn't notarised by Apple, so the first time, right-click it and choose **Open** (or System Settings > Privacy & Security > Open Anyway).
- **Windows:** unzip and run `Cinderwild.exe`. Keep `Cinderwild.pck` in the same folder or the game won't start. It's unsigned, so if SmartScreen says "Windows protected your PC", choose **More info**, then **Run anyway**.
### The title screen
@@ -430,11 +430,11 @@ The music follows what's happening: calm by day, a night theme after dark, a sto
### Reporting a bug
**Report a bug** in the pause menu opens a new issue on Emberwild's [Gitea page](https://git.psbailey.uk/Admin/Emberwild/issues) in your browser, already filled in with your version, computer, mode, land, the in-game time and where you are. Say what happened and how to make it happen again, then press **Create Issue** (you'll need to be signed in there). Nothing is sent from the game itself. **Copy the details** puts the same details on your clipboard instead, and **Show the log file** opens the folder with `godot.log`: attach it for a crash or an error.
**Report a bug** in the pause menu opens a new issue on Cinderwild's [Gitea page](https://git.psbailey.uk/Admin/Emberwild/issues) in your browser, already filled in with your version, computer, mode, land, the in-game time and where you are. Say what happened and how to make it happen again, then press **Create Issue** (you'll need to be signed in there). Nothing is sent from the game itself. **Copy the details** puts the same details on your clipboard instead, and **Show the log file** opens the folder with `godot.log`: attach it for a crash or an error.
### Updates
With the update check on, the title screen tells you when a newer Emberwild is out and offers a **Download** button or the release page.
With the update check on, the title screen tells you when a newer Cinderwild is out and offers a **Download** button or the release page.
## Tips for your first days {#tips}

View File

@@ -3,12 +3,12 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Emberwild: a self-hosted co-op survival game</title>
<meta name="description" content="Emberwild is a low-poly survival game: gather, hunt, build a home and hold out through the night, then dig through the sea cliffs to the Cove. Alone, or with friends on your own server.">
<title>Cinderwild: a self-hosted co-op survival game</title>
<meta name="description" content="Cinderwild is a low-poly survival game: gather, hunt, build a home and hold out through the night, then dig through the sea cliffs to the Cove. Alone, or with friends on your own server.">
<meta name="theme-color" content="#15110d">
<meta property="og:type" content="website">
<meta property="og:url" content="{{SITE_URL}}/">
<meta property="og:title" content="Emberwild">
<meta property="og:title" content="Cinderwild">
<meta property="og:description" content="Survive the island. Build a home. Self-hosted co-op survival for Mac and Windows.">
<meta property="og:image" content="{{SITE_URL}}/poster.jpg">
<meta name="twitter:card" content="summary_large_image">
@@ -137,7 +137,7 @@
<nav class="top" aria-label="Site">
<div class="wrap">
<a class="brand" href="#">EMBERWILD</a>
<a class="brand" href="#">CINDERWILD</a>
<a class="l opt" href="#trailer">Trailer</a>
<a class="l opt" href="#world">The game</a>
<a class="l" href="guide.html">Guide</a>
@@ -148,7 +148,7 @@
<header class="hero">
<div class="wrap">
<span class="pill">Version {{VERSION}} · playtest</span>
<h1>EMBERWILD</h1>
<h1>CINDERWILD</h1>
<p class="tag">Survive the island. Build a home. Find what lies beyond.</p>
<p class="sub">A low-poly survival game for Mac and Windows. Gather, hunt and build, hold out
through wolf moons and hard winters, then dig down through the sea cliffs to the Cove.
@@ -168,7 +168,7 @@
<h2 id="trailer-title">The trailer</h2>
<p class="lead">Under a minute, recorded in the game.</p>
<div class="video">
<video controls preload="metadata" poster="poster.jpg" aria-label="Emberwild trailer">
<video controls preload="metadata" poster="poster.jpg" aria-label="Cinderwild trailer">
<source src="trailer.mp4" type="video/mp4">
Your browser can't play this video. <a href="trailer.mp4">Download the trailer</a>.
</video>
@@ -216,6 +216,7 @@
<p class="lead">The Cove gets its own. This is a playtest build: thanks for trying it.</p>
<div class="new">
<ul class="ticks">
<li>A new name: Emberwild is now Cinderwild (another game already had the old one). Your worlds come with you.</li>
<li>A wreck on the Cove's beach, with a treasure map in the captain's sea chest for each player.</li>
<li>Your own X on your map: dig up the pirate chest for a ship's compass, a spyglass, a cutlass and gold.</li>
<li>The drowned crew rise to guard it. Dig by day if you're wise.</li>
@@ -271,7 +272,7 @@
<h3>Windows <span class="yours">· your computer</span></h3>
<p class="meta">64-bit · {{WIN_SIZE}}</p>
<a class="btn" href="{{WIN_URL}}">Download for Windows</a>
<p class="note">Unzip, then run <code>Emberwild.exe</code>. If SmartScreen warns,
<p class="note">Unzip, then run <code>Cinderwild.exe</code>. If SmartScreen warns,
choose <b>More info</b> &gt; <b>Run anyway</b> (it isn't signed yet).</p>
</div>
</div>
@@ -300,7 +301,7 @@
</tbody>
</table>
<p class="note">A spare computer can run a dedicated server from the same download:
<code>Emberwild --headless -- --server</code>.
<code>Cinderwild --headless -- --server</code>.
<a href="guide.html#multiplayer">More in the guide</a>.</p>
</div>
</section>
@@ -314,7 +315,7 @@
<a href="{{REPO_URL}}/issues">Report a bug</a>
<a href="{{REPO_URL}}">Source</a>
</nav>
<span>Emberwild {{VERSION}}. Made with Godot.</span>
<span>Cinderwild {{VERSION}}. Made with Godot.</span>
</div>
</footer>

View File

@@ -221,8 +221,8 @@ PAGE = """<!doctype html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Emberwild guide: everything in the game</title>
<meta name="description" content="How to play Emberwild: controls, survival, food, building, weather, wildlife, hunting, fishing, iron, the Old Stag, the journey to the Cove and multiplayer, with every item, recipe and creature.">
<title>Cinderwild guide: everything in the game</title>
<meta name="description" content="How to play Cinderwild: controls, survival, food, building, weather, wildlife, hunting, fishing, iron, the Old Stag, the journey to the Cove and multiplayer, with every item, recipe and creature.">
<style>
:root { --bg: #15110d; --panel: #221b14; --line: #3a2e22; --text: #f1e8da; --dim: #b8a892;
--ember: #e8833a; --ember-hi: #f6a35c; --mark: #5a3a14; }
@@ -262,7 +262,7 @@ PAGE = """<!doctype html>
<a class="skip" href="#content">Skip to the guide</a>
<div class="layout">
<nav class="toc" aria-label="Guide contents">
<a class="home" href="index.html">EMBERWILD</a>
<a class="home" href="index.html">CINDERWILD</a>
<label for="q" class="group" style="display:block;margin:0 0 6px">Search the guide</label>
<input id="q" type="search" placeholder="wolves, bed, iron..." autocomplete="off">
<ol>
@@ -273,12 +273,12 @@ PAGE = """<!doctype html>
</ol>
</nav>
<main id="content">
<h1>The Emberwild guide</h1>
<p class="lead">Everything in Emberwild {VERSION}: how to play, what can happen, and every item, recipe and
<h1>The Cinderwild guide</h1>
<p class="lead">Everything in Cinderwild {VERSION}: how to play, what can happen, and every item, recipe and
creature. <a href="index.html">Download the game</a>.</p>
<p id="none" class="none hidden" role="status">Nothing matches that.</p>
{SECTIONS}
<footer>Emberwild {VERSION}. The reference tables are made from the game's own data each time this page is built.</footer>
<footer>Cinderwild {VERSION}. The reference tables are made from the game's own data each time this page is built.</footer>
</main>
</div>
<script>

View File

@@ -15,16 +15,16 @@
cd "$(dirname "$0")/../.." || exit 1
REPO=${REPO:-https://git.psbailey.uk/Admin/Emberwild}
SITE=${SITE:-https://emberwild-95k.pages.dev} # (where the page is served: for link previews)
SITE=${SITE:-https://cinderwild.psbailey.uk} # (where the page is served: for link previews)
SHOTS="meadow hut wolves winter cove treasure crabs"
[ -f build/version.json ] || { echo "no build/version.json: run tools/export.sh first"; exit 1; }
[ -f build/Emberwild-trailer.mp4 ] || { echo "no trailer: run tools/trailer/make_trailer.sh first"; exit 1; }
[ -f build/Cinderwild-trailer.mp4 ] || { echo "no trailer: run tools/trailer/make_trailer.sh first"; exit 1; }
for s in $SHOTS; do
[ -f "build/shots/$s.jpg" ] || { echo "no build/shots/$s.jpg: run tools/site/make_shots.sh first"; exit 1; }
done
rm -rf build/site && mkdir -p build/site
cp build/Emberwild-trailer.mp4 build/site/trailer.mp4
cp build/Cinderwild-trailer.mp4 build/site/trailer.mp4
cp build/trailer/poster.jpg build/site/poster.jpg
mkdir -p build/site/shots
for s in $SHOTS; do cp "build/shots/$s.jpg" build/site/shots/; done

View File

@@ -2,7 +2,7 @@
# Records the test trailer (tools/trailer/trailer.gd) with Godot's Movie
# Maker and encodes it, with a generated music pad under the game's sound:
#
# tools/trailer/make_trailer.sh # -> build/Emberwild-trailer.mp4 (+ poster.jpg)
# tools/trailer/make_trailer.sh # -> build/Cinderwild-trailer.mp4 (+ poster.jpg)
#
# Needs ffmpeg. Takes about a minute: the shots are rendered frame by frame
# at 30 fps whatever the machine's speed, so the result never stutters.
@@ -13,7 +13,7 @@ command -v ffmpeg >/dev/null || { echo "needs ffmpeg (brew install ffmpeg)"; exi
mkdir -p build/trailer
RAW=build/trailer/raw.avi
OUT=build/Emberwild-trailer.mp4
OUT=build/Cinderwild-trailer.mp4
rm -f "$RAW"
"$GODOT" --path . --resolution 1280x720 --fixed-fps 30 --write-movie "$RAW" \
--script tools/trailer/trailer.gd -- --no-creatures > build/trailer/render.log 2>&1

View File

@@ -182,7 +182,7 @@ func _clock(hours: float) -> void:
# --- the shots -------------------------------------------------------------------------
func _shot_dawn() -> void:
big.text = "EMBERWILD"
big.text = "CINDERWILD"
sub.text = "Survive the island. Build a home."
var c := Vector3(0, 0, -10)
await _shot(7.5, func(t: float, k: float):
@@ -335,7 +335,7 @@ func _shot_cove() -> void:
_park_player(Vector3(pier.start.x, pier.start.y + 1.0, pier.start.z)), "Find what lies beyond.")
func _shot_end() -> void:
big.text = "EMBERWILD"
big.text = "CINDERWILD"
sub.text = "Self-hosted co-op survival · %s" % String(ProjectSettings.get_setting("application/config/version", ""))
# Rising over the Cove's bay, looking back at the land.
var pier: Node3D = world.pier