Trailer tool (Movie Maker + ffmpeg) and a static download page built per release
This commit is contained in:
117
tools/site/index.html
Normal file
117
tools/site/index.html
Normal file
@@ -0,0 +1,117 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<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, alone or with friends on your own server.">
|
||||
<meta property="og:title" content="Emberwild">
|
||||
<meta property="og:description" content="Survive the island. Build a home. Self-hosted co-op survival.">
|
||||
<meta property="og:image" content="poster.jpg">
|
||||
<style>
|
||||
:root {
|
||||
--bg: #15110d; --panel: #221b14; --line: #3a2e22;
|
||||
--text: #f1e8da; --dim: #b8a892; --ember: #e8833a; --ember-hi: #f6a35c;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body { margin: 0; background: var(--bg); color: var(--text);
|
||||
font: 17px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
|
||||
a { color: var(--ember-hi); }
|
||||
a:focus-visible, button:focus-visible { outline: 3px solid var(--ember-hi); outline-offset: 3px; }
|
||||
.wrap { max-width: 980px; margin: 0 auto; padding: 0 20px; }
|
||||
header { padding: 48px 0 20px; text-align: center; }
|
||||
h1 { font-size: clamp(44px, 9vw, 84px); letter-spacing: .06em; margin: 0; font-weight: 600; }
|
||||
.tag { color: var(--dim); font-size: 20px; margin: 6px 0 0; }
|
||||
.video { margin: 28px 0 0; border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
|
||||
background: #000; aspect-ratio: 16 / 9; }
|
||||
.video video { width: 100%; height: 100%; display: block; }
|
||||
section { margin: 44px 0; }
|
||||
h2 { font-size: 26px; margin: 0 0 14px; font-weight: 600; }
|
||||
.downloads { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
|
||||
.dl { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 20px; }
|
||||
.dl.mine { border-color: var(--ember); }
|
||||
.dl h3 { margin: 0 0 4px; font-size: 20px; }
|
||||
.dl p { margin: 0 0 14px; color: var(--dim); font-size: 15px; }
|
||||
.btn { display: inline-block; background: var(--ember); color: #1a120a; text-decoration: none;
|
||||
font-weight: 600; padding: 11px 20px; border-radius: 8px; }
|
||||
.btn:hover { background: var(--ember-hi); }
|
||||
.note { color: var(--dim); font-size: 14px; margin-top: 12px; }
|
||||
.note code { color: var(--text); }
|
||||
ul.features { columns: 2 260px; padding-left: 20px; margin: 0; }
|
||||
ul.features li { margin: 0 0 6px; break-inside: avoid; }
|
||||
footer { border-top: 1px solid var(--line); padding: 24px 0 40px; color: var(--dim); font-size: 14px; }
|
||||
@media (prefers-reduced-motion: reduce) { * { scroll-behavior: auto; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="wrap">
|
||||
<h1>EMBERWILD</h1>
|
||||
<p class="tag">Survive the island. Build a home.</p>
|
||||
<div class="video">
|
||||
<video controls preload="metadata" poster="poster.jpg" aria-label="Emberwild trailer">
|
||||
<source src="trailer.mp4" type="video/mp4">
|
||||
Your browser can't play this video. <a href="trailer.mp4">Download the trailer</a>.
|
||||
</video>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="wrap">
|
||||
<section aria-labelledby="dl-title">
|
||||
<h2 id="dl-title">Download version {{VERSION}}</h2>
|
||||
<div class="downloads">
|
||||
<div class="dl" data-os="mac">
|
||||
<h3>macOS</h3>
|
||||
<p>Apple silicon and Intel · {{MAC_SIZE}}</p>
|
||||
<a class="btn" href="{{MAC_URL}}">Download for Mac</a>
|
||||
<p class="note">First launch: right-click the app and choose <b>Open</b>
|
||||
(it isn't notarised by Apple yet).</p>
|
||||
</div>
|
||||
<div class="dl" data-os="win">
|
||||
<h3>Windows</h3>
|
||||
<p>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, choose <b>More info</b> > <b>Run anyway</b> (it isn't signed yet).</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="note">Released {{DATE}}. {{NOTES}} The game tells you on its title
|
||||
screen when a newer version is out.
|
||||
<a href="{{RELEASES_URL}}">All releases and checksums</a>.</p>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="what-title">
|
||||
<h2 id="what-title">What it is</h2>
|
||||
<ul class="features">
|
||||
<li>Gather, craft and cook; keep warm, fed and dry.</li>
|
||||
<li>Hunt deer, boar and rabbits; fish the lake.</li>
|
||||
<li>Build a home from floors, walls and roofs that snap together.</li>
|
||||
<li>Wolves move in, and every seventh night the moon turns red.</li>
|
||||
<li>Weather that matters: storms, blizzards and hard winters.</li>
|
||||
<li>A bear, a barrow, and the Old Stag at the standing stones.</li>
|
||||
<li>Play alone, or host a server for friends on your own machine.</li>
|
||||
<li>A guided tutorial with Old Tam the hermit.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="host-title">
|
||||
<h2 id="host-title">Playing with friends</h2>
|
||||
<p>Choose <b>Host Game</b> on the title screen, and friends choose <b>Join Game</b>
|
||||
with your address (UDP port 24242). Everyone needs the same version. A spare
|
||||
computer can run a dedicated server from the same download:
|
||||
<code>Emberwild --headless -- --server</code>.</p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="wrap">Emberwild {{VERSION}}. Made with Godot.</footer>
|
||||
|
||||
<script>
|
||||
// Point out the download for the visitor's own computer (it still works without this).
|
||||
(function () {
|
||||
var ua = navigator.userAgent;
|
||||
var os = /Mac/i.test(ua) && !/iPhone|iPad/i.test(ua) ? "mac" : /Win/i.test(ua) ? "win" : "";
|
||||
var card = os && document.querySelector('.dl[data-os="' + os + '"]');
|
||||
if (card) { card.classList.add("mine"); card.parentNode.insertBefore(card, card.parentNode.firstChild); }
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
45
tools/site/make_site.sh
Executable file
45
tools/site/make_site.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
# Builds the download page into build/site/ for the release in
|
||||
# build/version.json (made by tools/export.sh):
|
||||
#
|
||||
# tools/site/make_site.sh
|
||||
#
|
||||
# build/site/index.html the page, with this release's download links
|
||||
# build/site/poster.jpg the trailer's title frame
|
||||
# build/site/trailer.mp4 the trailer (tools/trailer/make_trailer.sh)
|
||||
#
|
||||
# Copy the folder to any static web host. Gitea itself won't serve HTML, so
|
||||
# the page lives elsewhere and links to the files on the Gitea release.
|
||||
# Rebuild it after each release (the links name the version).
|
||||
|
||||
cd "$(dirname "$0")/../.." || exit 1
|
||||
REPO=${REPO:-https://git.psbailey.uk/Admin/Emberwild}
|
||||
[ -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; }
|
||||
|
||||
rm -rf build/site && mkdir -p build/site
|
||||
cp build/Emberwild-trailer.mp4 build/site/trailer.mp4
|
||||
cp build/trailer/poster.jpg build/site/poster.jpg
|
||||
python3 - "$REPO" <<'EOF'
|
||||
import html, json, sys
|
||||
repo = sys.argv[1].rstrip("/")
|
||||
v = json.load(open("build/version.json"))
|
||||
tag = "v" + v["version"]
|
||||
def dl(plat):
|
||||
d = v["downloads"].get(plat)
|
||||
if not d:
|
||||
return repo + "/releases", "see all releases"
|
||||
return "%s/releases/download/%s/%s" % (repo, tag, d["file"]), "%.0f MB" % (d["size"] / 1e6)
|
||||
mac_url, mac_size = dl("macos")
|
||||
win_url, win_size = dl("windows")
|
||||
page = open("tools/site/index.html").read()
|
||||
for k, val in {
|
||||
"VERSION": v["version"], "DATE": v.get("date", ""), "NOTES": v.get("notes", ""),
|
||||
"MAC_URL": mac_url, "MAC_SIZE": mac_size, "WIN_URL": win_url, "WIN_SIZE": win_size,
|
||||
"RELEASES_URL": repo + "/releases",
|
||||
}.items():
|
||||
page = page.replace("{{%s}}" % k, html.escape(str(val), quote=True))
|
||||
assert "{{" not in page, "a placeholder was left unfilled"
|
||||
open("build/site/index.html", "w").write(page)
|
||||
print("built build/site/ for %s:\n %s\n %s" % (v["version"], mac_url, win_url))
|
||||
EOF
|
||||
Reference in New Issue
Block a user