Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5be9ff4862 | ||
|
|
c1bbfa06d5 | ||
|
|
375a2a54fc | ||
|
|
8057ba9a09 | ||
|
|
952895f359 | ||
|
|
c3726f7af5 | ||
|
|
967bd58f00 |
No files matched your search
@@ -6,10 +6,11 @@ Live site: https://justinoros.github.io/sotf-modloader/
|
|||||||
|
|
||||||
## For players
|
## For players
|
||||||
|
|
||||||
The site offers two ways to install:
|
The site offers three ways to install:
|
||||||
|
|
||||||
1. **Windows app (recommended).** Download `SotfModLoader.exe` from the site and run it. It finds your game through Steam, including installs inside Program Files, and installs RedLoader and mods with one click.
|
1. **Windows app (recommended).** Download `SotfModLoader.exe` from the site and run it. It finds your game through Steam, including installs inside Program Files, and installs RedLoader and mods with one click.
|
||||||
2. **Zip download.** One zip with RedLoader and every mod. Extract it into your Sons of the Forest folder, the one that contains `SonsOfTheForest.exe`.
|
2. **Zip download.** One zip with RedLoader and every mod. Extract it into your Sons of the Forest folder, the one that contains `SonsOfTheForest.exe`.
|
||||||
|
3. **PowerShell scripts.** Each mod has a **Copy PowerShell install** button on the site. Paste the command into PowerShell to install that mod, plus RedLoader if needed. Run it again to update.
|
||||||
|
|
||||||
Close the game before installing or updating.
|
Close the game before installing or updating.
|
||||||
|
|
||||||
|
|||||||
+34
-19
@@ -32,31 +32,44 @@ function link(href, text) {
|
|||||||
return el("a", { href, target: "_blank", rel: "noopener" }, text);
|
return el("a", { href, target: "_blank", rel: "noopener" }, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function optionCard(number, title, text, action, note, recommended) {
|
||||||
|
return el("div", { class: recommended ? "get-card recommended" : "get-card" },
|
||||||
|
el("p", { class: "get-option" }, recommended ? `Option ${number} (Recommended)` : `Option ${number}`),
|
||||||
|
el("h3", {}, title),
|
||||||
|
el("p", {}, text),
|
||||||
|
action,
|
||||||
|
note ? el("p", { class: "get-note" }, note) : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function renderGet() {
|
function renderGet() {
|
||||||
const node = $("get");
|
const node = $("get");
|
||||||
const { app, bundle } = state.manifest;
|
const { app, bundle, mods } = state.manifest;
|
||||||
const cards = [];
|
const options = [];
|
||||||
if (app) {
|
if (app) {
|
||||||
cards.push(
|
options.push((n) => optionCard(n, "Windows app",
|
||||||
el("div", { class: "get-card" },
|
"Finds your game automatically. Installs, updates and removes RedLoader and mods with one click.",
|
||||||
el("h2", {}, "Windows app"),
|
el("a", { class: "button primary", href: app.url }, `Download app (${formatSize(app.size)})`),
|
||||||
el("p", {}, "Finds your game automatically, even inside Program Files, and installs RedLoader and mods with one click."),
|
`Version ${app.version}. If Windows shows a warning, click More info, then Run anyway.`,
|
||||||
el("a", { class: "button primary", href: app.url }, `Download the app (${formatSize(app.size)})`),
|
true));
|
||||||
el("p", { class: "get-note" }, `Version ${app.version}. If Windows shows a warning, click More info, then Run anyway.`),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (bundle) {
|
if (bundle) {
|
||||||
cards.push(
|
options.push((n) => optionCard(n, "Zip download",
|
||||||
el("div", { class: "get-card" },
|
"RedLoader and every mod in one zip. Extract it into your game folder, the one with SonsOfTheForest.exe.",
|
||||||
el("h2", {}, "Zip download"),
|
|
||||||
el("p", {}, "RedLoader and every mod in one zip. Extract it into your Sons of the Forest folder, the one that contains SonsOfTheForest.exe."),
|
|
||||||
el("a", { class: "button secondary", href: bundle.url, download: "sotf-mods.zip" }, `Download zip (${formatSize(bundle.size)})`),
|
el("a", { class: "button secondary", href: bundle.url, download: "sotf-mods.zip" }, `Download zip (${formatSize(bundle.size)})`),
|
||||||
),
|
"Download it again to update. Remove mods by deleting them from the Mods folder."));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
node.hidden = !cards.length;
|
if ((mods || []).some((mod) => mod.installCommand)) {
|
||||||
node.replaceChildren(...cards);
|
options.push((n) => optionCard(n, "PowerShell scripts",
|
||||||
|
"Install one mod at a time. Copy a mod's command from the list below and paste it into PowerShell.",
|
||||||
|
el("a", { class: "button secondary", href: "#mods" }, "Go to the mod list"),
|
||||||
|
"Installs RedLoader too if needed. Run the command again to update."));
|
||||||
|
}
|
||||||
|
node.hidden = !options.length;
|
||||||
|
node.replaceChildren(
|
||||||
|
el("div", { class: "block-head" }, el("h2", { id: "get-title" }, "Choose how to install")),
|
||||||
|
el("div", { class: "get-grid" }, options.map((make, i) => make(i + 1))),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderRedloader() {
|
function renderRedloader() {
|
||||||
@@ -70,7 +83,7 @@ function renderRedloader() {
|
|||||||
el("li", { class: "row" },
|
el("li", { class: "row" },
|
||||||
el("div", {},
|
el("div", {},
|
||||||
el("h3", {}, link(rl.repo, "RedLoader")),
|
el("h3", {}, link(rl.repo, "RedLoader")),
|
||||||
el("p", { class: "desc" }, "Every mod on this page runs on RedLoader. The app and the zip include it."),
|
el("p", { class: "desc" }, "Every mod on this page runs on RedLoader. All three install options include it."),
|
||||||
el("p", { class: "meta" }, el("span", {}, `Latest ${rl.version}`), link(rl.releaseUrl, "Release notes")),
|
el("p", { class: "meta" }, el("span", {}, `Latest ${rl.version}`), link(rl.releaseUrl, "Release notes")),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -146,6 +159,8 @@ function renderFooter() {
|
|||||||
? el("p", {}, "RedLoader by ToniMacaroni, redistributed unmodified under the ",
|
? el("p", {}, "RedLoader by ToniMacaroni, redistributed unmodified under the ",
|
||||||
link(`${redloader.repo}/blob/main/LICENSE.md`, "Apache License 2.0"), ".")
|
link(`${redloader.repo}/blob/main/LICENSE.md`, "Apache License 2.0"), ".")
|
||||||
: null,
|
: null,
|
||||||
|
el("p", {}, "Free code signing provided by ", link("https://about.signpath.io", "SignPath.io"),
|
||||||
|
", certificate by ", link("https://signpath.org", "SignPath Foundation"), "."),
|
||||||
el("p", {}, `Mod list updated ${updated}.`),
|
el("p", {}, `Mod list updated ${updated}.`),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -15,9 +15,9 @@
|
|||||||
<main class="page">
|
<main class="page">
|
||||||
<header class="masthead">
|
<header class="masthead">
|
||||||
<h1>Sons of the Forest mod loader</h1>
|
<h1>Sons of the Forest mod loader</h1>
|
||||||
<p class="lede">Install, update and remove Sons of the Forest mods with one click.</p>
|
<p class="lede">A one-stop shop to install, update or remove my Sons of the Forest mods. Choose an option below.</p>
|
||||||
</header>
|
</header>
|
||||||
<section id="get" class="get" aria-label="Ways to install" hidden></section>
|
<section id="get" class="block get" aria-labelledby="get-title" hidden></section>
|
||||||
<section id="redloader" class="block" aria-labelledby="redloader-title" hidden></section>
|
<section id="redloader" class="block" aria-labelledby="redloader-title" hidden></section>
|
||||||
<section id="mods" class="block" aria-labelledby="mods-title"></section>
|
<section id="mods" class="block" aria-labelledby="mods-title"></section>
|
||||||
<p id="status" class="status" role="status" aria-live="polite"></p>
|
<p id="status" class="status" role="status" aria-live="polite"></p>
|
||||||
|
|||||||
+22
-9
@@ -52,7 +52,7 @@ a:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
max-width: 54rem;
|
max-width: 62rem;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: clamp(2.5rem, 7vw, 5rem) clamp(1.25rem, 4vw, 2.5rem) 2rem;
|
padding: clamp(2.5rem, 7vw, 5rem) clamp(1.25rem, 4vw, 2.5rem) 2rem;
|
||||||
}
|
}
|
||||||
@@ -74,32 +74,44 @@ a:hover {
|
|||||||
font-size: 1.15rem;
|
font-size: 1.15rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.get {
|
.get-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
margin-top: 2.75rem;
|
margin-top: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.get-card {
|
.get-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
padding: 1.35rem 1.5rem 1.4rem;
|
padding: 1.25rem 1.35rem 1.35rem;
|
||||||
background: var(--bark);
|
background: var(--bark);
|
||||||
border: 1px solid var(--bark-line);
|
border: 1px solid var(--bark-line);
|
||||||
|
border-top: 5px solid var(--bark-line);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.get-card:first-child {
|
.get-card.recommended {
|
||||||
border-top: 5px solid var(--flare);
|
border-top-color: var(--flare);
|
||||||
}
|
}
|
||||||
|
|
||||||
.get-card h2 {
|
.get-card .get-option {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
color: var(--lichen);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.get-card.recommended .get-option {
|
||||||
|
color: var(--flare);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.get-card h3 {
|
||||||
|
margin: 0.15rem 0 0;
|
||||||
font-family: var(--display);
|
font-family: var(--display);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 1.75rem;
|
font-size: 1.65rem;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +135,7 @@ a.button {
|
|||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.button.primary {
|
a.button.primary {
|
||||||
|
|||||||
Reference in new issue
Block a user