You have arrived at the camp.
<<nobr>>
<<script>>
UIBar.unstow().show();
<</script>>
<<if Cycle.get('time').check('morning')>>
The sun is rising, and the birds are singing.
<<set $locationImage to "media/locations/camp_morning_unlit.webp">>
<<elseif Cycle.get('time').check('noon')>>
The sun is high in the sky, and the camp is bustling with activity.
<<set $locationImage to "media/locations/camp_day_unlit.webp">>
<<elseif Cycle.get('time').check('evening')>>
The sun is setting, casting a warm glow over the camp.
<<set $locationImage to "media/locations/camp_evening_unlit.webp">>
<<elseif $timeIndex is 3>>
The fire is warm, and the stars are bright.
<<set $locationImage to "media/locations/camp_night_unlit.webp">>
<</if>>
<</nobr>>
Hunger: <<showcycle 'hunger'>>
Thirst: <<showcycle 'thirst'>>
Sleep: <<showcycle 'sleep'>>
[[Sleep]] [[TestDialog]] [[TestGeneration]] [[TestMap]] [[TestFight]]
<<button "Refresh Page" "DebugCamp">><</button>>
<<customButton "Refresh Page" "This is the move button" "DebugCamp" "move-btn" "media/icons/farmer.svg" "normal" "move button pressed">><</customButton>>
<<customButton "Refresh Page" "This is the interact button" "DebugCamp" "interact-btn pulse-animation" "media/icons/farmer.svg" "large" "interact button pressed">><</customButton>>
<<customButton "Refresh Page" "This is the action button" "DebugCamp" "action-btn" "media/icons/farmer.svg" "large" "action button pressed">><</customButton>>
<<if $placesArray.last()>>[[Go Explore|either($placesArray)]]<<else>> You have no unexplored areas. <</if>>
<<print $placesArray>>
<<nobr>>
<<for _i to 0; _i lt $exploredPlaces.length; _i++>>
<<capture _i>>
[[$exploredPlaces[_i]]]
<</capture>>
<</for>>
<</nobr>>
<<set $playerX = 57>>
<<set $playerY = 53>>
<<set $location to "DebugCamp">><<set _faceSvg = loadAndColorSvg('media/faces/face_1.svg', '#FFFFFF', '#034DF2', '#FFFFFF')>>
<<set _overlaySvg = loadAndColorSvg('media/faces/eyes_1.svg', '#000000', '#CCCCCC', '#00AA00')>>
<div class="svg-layer-container">
<div class="svg-layer base-layer">
<<print _faceSvg>>
</div>
<div class="svg-layer overlay-layer">
<<print _overlaySvg>>
</div>
</div><<conversation
left1:$profileImage $first_name $last_name
left2:$units[1].image Archer
right1:$enemy.image Goblin Leader
right2:$units[0].image Goblin
right4:$units[0].image Goblin
right3:$units[0].image Goblin
>>
<<fadeConversationImage in "left-1" "0s">>
<<fadeConversationImage in "right-1" "0s">>
<<dialogText center>>
<i>You see a goblin!</i>
<</dialogText>>
<<timed 50ms>>
<<highlightConversationImage left-1>>
<<setConversationImageOpacity right-1 0.8>>
<</timed>>
<<dlg "dlg" 0 "➤">>
<<level 0>>
<<line "Hello">>
<<dialogText left left-1>>
Hello.
<</dialogText>>
<<highlightConversationImage right-1>>
<<dialogText right right-1>>
Grr I am a goblin!
<</dialogText>>
<<timed 2s>>
<<fadeConversationImage in "right-2" "1s">>
<<highlightConversationImage right-2>>
<<dialogText center>>
<i>Another goblin appears</i>
<</dialogText>>
<<next>>
<<highlightConversationImage left-2>>
<<fadeConversationImage in "left-2" "1s">>
<<dialogText center>>
<i>Your reinforcements arrive...</i>
<</dialogText>>
<<next>>
<<dialogText left left-2>>
Let me at them!
<</dialogText>>
<<highlightConversationImage left-1>>
<</timed>>
<</line>>
<</level>>
<<level 1>>
<<line "Come on then!">>
<<highlightConversationImage right-3>>
<<dialogText left left-1>>
Come on then!
<</dialogText>>
<<timed 1s>>
<<fadeConversationImage in "right-3" "1s">>
<<dialogText center>>
<i>Yet another goblin appears!</i>
<</dialogText>>
<</timed>>
<</line>>
<br>
<<line "Gotta go!">>
<<highlightConversationImage left-1 remove>>
<<dialogText left left-1>>
I need to leave!
<</dialogText>>
<<timed 1s>>
<<fadeConversationImage out "left-1" "1s">>
<</timed>>
<</line>>
<</level>>
<</dlg>>
<</conversation>>
<<link "Back to Camp" "DebugCamp">>
<</link>><<set $combatIntro to "You found a $enemy.name!">>
<<done>>
<<script>>window.startCombat('TestFight', 'TestFight', 'TestFight', false, false, true);<</script>>
<</done>>
<<include "CombatUI">>
<br>
[[Back|TestFight]]<<link "FIGHT" "TestFightUI">>
<<script>>
generateEnemies([
{ type: 'goblin', armor: "none", weapon: "stone", name: "Stone Goblin", peonData: {
race: "goblin",
skintone: "golden",
ethnicity: "nordic",
gender: "Male",
age: "Adult",
recruitmentChance: 1
},
weights: {attack: 1.0, defend: 0.0, focus: 0.0}},
{ type: 'goblin', armor: "none", weapon: "club", name: "Club Goblin", weights: {attack: 0.0, defend: 1.0, focus: 0.0}},
{ type: 'goblin', armor: "none", weapon: "stick", name: "Stick Goblin", attributes: { constitution: 1, defense: 2}, weights: {attack: 0.0, defend: 0.0, focus: 1.0}}
]);
generateAllies([
{ type: 'goblin', armor: "none", weapon: "stone", name: "Stone Goblin", weights: {attack: 1.0, defend: 0.0, focus: 0.0}},
{ type: 'goblin', armor: "none", weapon: "club", name: "Club Goblin", weights: {attack: 0.0, defend: 1.0, focus: 0.0}},
{ type: 'goblin', armor: "none", weapon: "stick", name: "Stick Goblin", attributes: { constitution: 1, defense: 2}, weights: {attack: 0.0, defend: 0.0, focus: 1.0}}
]);
<</script>>
Combat stats:
Speed: Turn order + if 2x speed, 2x turns etc
Agility: Anti Critical Strike chance
Perception: Critical Strike chance (Crit when Perception - Agility > 0 & roll dice (+ luck?))
Defense: Blocks against Strength and Precision
Strength: Damages against Defense (melee) (Damage done: Strength - Defense [+- dice damage])
Constitution: Sets Stamina level
Precision: Damages against Defense (ranged) (Damage done: Precision - Defense [+- dice damage])
Luck: Higher luck = wins ties
Loss when Stamina reaches 0. Let make decision if enemy loss.
If player loss, enemy can hurt or spare randomly weighted based on type.
Lose state: time passes, player is moved to another story point.
<</link>>
<<link "Camp">>
<<goto "CraterCamp">>
<</link>><dialogue-wheel id="myWheel" style="display: block; margin: 0 auto;"></dialogue-wheel>
<<done>>
<<script>>
const wheel = document.getElementById('myWheel');
wheel.options = [
{ text: "Stagger toward the pod", color: "#00785E" },
{ text: "Stagger toward the river", color: "#019e5c" },
{ text: "Stagger toward the forest", color: "#D8F5EF" },
{ text: "Stagger toward the lake", color: "#00c9a7" }
];
wheel.wheelRadius = 95;
wheel.ringThickness = 60;
wheel.perspectiveAngleX = 20;
wheel.fontSizeScale = 1.5;
wheel.bevelIntensity = 0.5;
wheel.ringExtrusion = 22;
wheel.disabledOpacity = 0.5;
wheel.disabledSaturation = 0.25;
wheel.disableAffectsText = false;
// Listen for selection events
wheel.addEventListener('option-selected', (event) => {
debugLog('Selected:', event.detail.option);
// Example: Update some UI element
// const selectionDisplay = document.getElementById('selectionInfo');
// if (selectionDisplay) {
// selectionDisplay.textContent = `Selected: ${event.detail.option.text}`;
// }
});
<</script>>
<</done>>
<br>
<div id="peonList">
<h3>Existing Peons:</h3>
</div>
<<script>>
$(document).ready(function () {
function renderPeon(peon) {
return '<div class="peon" style="border:1px solid #ccc; padding:10px; margin:10px;">' +
'<h4>' + peon.Name.First + ' ' + peon.Name.Last + '</h4>' +
'<ul>' +
'<li>Race: ' + peon.Race + '</li>' +
'<li>Ethnicity: ' + peon.Ethnicity + '</li>' +
'<li>Gender: ' + peon.Gender + '</li>' +
'<li>Age: ' + peon.Age + '</li>' +
'<li>Body Type: ' + peon.BodyType + '</li>' +
'<li>Skin: ' + peon.Skintone + ' (' + peon.HexColor + ')</li>' +
'<li>Distinctive Feature: ' + peon.Distinctive + '</li>' +
'</ul>' +
'</div>';
}
if (!State.variables.peons) {
State.variables.peons = {};
}
Object.values(State.variables.peons).forEach(peon => {
$('#peonList').append(renderPeon(peon));
});
const newPeons = [
peonGenerator.generatePeon(1),
peonGenerator.generatePeon(1, {
race: "human",
age: "Elder",
hairStyle: "Bald",
skintone: "light",
firstName: "TestNameFirstOnly"
}),
peonGenerator.generatePeon(1, {
race: "orc",
hexColor: "#2F4F4F",
bodyType: "Hulking",
distinctive: "Ritual Scarring"
})
].flat();
newPeons.forEach(peon => {
State.variables.peons[peon.UUID] = peon;
$('#peonList').append(renderPeon(peon));
});
});
<</script>>
<br>
[[DebugCamp]]<img src="media/locations/riverine_forest_map_no_camp.webp" usemap="#image-map" style="max-height: 90vh; max-width: 90vh;">
<map name="image-map">
<area alt="River" title="River" data-passage="River" coords="0,1699,260,1694,463,1488,658,1276,750,1269,920,1262,1042,1267,1132,1269,1201,1256,1271,1245,1331,1211,1387,1155,1445,1041,1492,940,1516,807,1516,697,1496,599,1442,491,1400,413,1405,350,1476,339,1583,317,1691,288,1765,263,1872,230,1961,201,2042,181,2042,8,1925,8,1883,60,1805,106,1731,106,1628,102,1525,124,1384,136,1326,194,1264,239,1268,324,1263,391,1254,462,1227,528,1248,584,1279,615,1337,657,1364,707,1333,794,1295,865,1248,957,1192,1028,1073,1046,946,1046,820,1042,740,1044,613,1075,510,1118,434,1221,340,1324,266,1391,217,1418,110,1485,62,1518,0,1523" shape="poly">
<area alt="Lake" title="Lake" data-passage="Lake" coords="588,136,684,103,776,96,829,101,863,168,887,244,915,326,944,403,919,472,901,568,865,631,760,664,642,673,550,664,474,680,403,689,342,653,300,584,271,505,271,418,277,326,284,257,311,175,412,123,501,110" shape="poly">
<area alt="Crater" title="Crater" data-passage="Crater" coords="1080,1715,1160,1711,1247,1715,1294,1746,1317,1789,1239,1847,1154,1878,1071,1873,1010,1838,979,1793,1008,1746" shape="poly">
<area alt="Clearing" title="Clearing" data-passage="Camp" coords="1745,1205,1797,1232,1850,1248,1910,1261,1931,1303,1964,1324,2002,1333,2043,1344,2043,1699,2016,1683,1980,1621,1928,1588,1870,1594,1812,1610,1743,1605,1680,1588,1640,1541,1591,1480,1569,1399,1573,1324,1626,1272,1673,1237" shape="poly">
<area alt="Forest" title="Forest" data-passage="Woods" coords="2048,2048,0,0" shape="rect">
</map>
<<done>>
<<script>>
// Apply maphilight to all images that have a usemap attribute, e.g.
// all the maps that are in this twine. This sets the default styling
// for all the maps. These are all the possible styling options.
// Note: for picking colors, check out http://hslpicker.com/. You can
// copy the HEX value as long as you leave off the "#".
$("img[usemap]").maphilight({
fill: true, // Fill the area?
fillColor: '0F0F0F', // HEX format without the starting "#"
fillOpacity: 0.2, // Opacity of the filled area
stroke: true, // Outline the area?
strokeColor: '0F870F',
strokeOpacity: 0.2,
strokeWidth: 3, // Outline width
fade: true, // Animate when hovered with a fade?
alwaysOn: false, // Always show the areas?
neverOn: false,
groupBy: false,
wrapClass: true,
shadow: false,
shadowX: 0,
shadowY: 0,
shadowRadius: 6,
shadowColor: '000000',
shadowOpacity: 0.8,
shadowPosition: 'outside',
shadowFrom: false
});
$("img[usemap]").rwdImageMaps();
<</script>>
<</done>>
[[DebugCamp]]<<nobr>>
<<set $location to $campLoc + " Camp">>
<<set $locationImage to "media/locations/" + $campLoc + "_camp.webp">>
<<set $_target to $campLoc + "Camp">>
<</nobr>>
You collect whatever you can find to create a haphazard shelter. It might at least let you hide from the sun.
[[Go To Camp|$_target]]<div class="camp-status-container">
<div class="resource-row" id="resource-target">
</div>
</div>
<<done>>
<<script>>
const resources = State.variables.resources;
let html = '';
Object.values(resources)
.filter(r => r.visible)
.forEach(r => {
const name = r.name.slice(0,1).toUpperCase() + r.name.slice(1);
html += `<div class="resource-item">
<img src="${r.icon}" title="${name}" class="resource-icon">
<div class="resource-value">${r.amount}</div>
</div>`;
});
$('#resource-target').wiki(html);
<</script>>
<</done>><div class="choice-header">Actions</div>
<br>
<div class="buttongrid">
<<customButton "Travel" "" "CraterExplore" "move-btn" "media/icons/compass.svg">><</customButton>>
<<customButton "Explore" "" "CraterExplore" "move-btn" "media/icons/spyglass.svg">><</customButton>>
<<customButton "Build" "" "" "action-btn" "media/icons/wheelbarrow.svg">><</customButton>>
<<customButton "Rest" "" "" "move-btn" "media/icons/night-sleep.svg">><<include "Sleep">><</customButton>>
<<customButton "Train" "" "CraterCamp" "move-btn" "media/icons/biceps.svg">><</customButton>>
<<customButton "Craft" "" "CraterCamp" "action-btn" "media/icons/stone-crafting.svg">><</customButton>>
<<customButton "Manage" "" "CraterCamp" "action-btn" "media/icons/pointing.svg">><</customButton>>
<<customButton "Logistics" "" "CraterCamp" "action-btn" "media/icons/warehouse.svg">><</customButton>>
<<customButton "HUNT" "" "CraterCamp" "blood-btn frenzy" "media/icons/bleeding-eye_red.svg">><</customButton>>
</div>
<br>
/*
- Search for food - no food in crater
- Scavenge - first scavenge of pod gives unpowered codex
- Search for water - shallow pool of water in crater, risk for disease
- Make tools - lots of stone, no wood
- Find blood - no blood
- Explore - leave crater, travel menu to known locations
*/<<link [[Sleep until morning|CraterCamp]]>>
<<editcycle 'time' reset>>
<<editcycle 'sleep' change -40>>
<<script>>
const time = Cycle.get('time');
const hunger = Cycle.get('hunger');
const thirst = Cycle.get('thirst');
const value = time.turnsTotal() - time.stack;
thirst.update(Math.min(value, thirst.turnsTotal() - 1 - thirst.stack));
hunger.update(Math.min(value, hunger.turnsTotal() - 1 - hunger.stack));
<</script>>
<</link>>
<<link [[Sleep for a couple of hours|CraterCamp]]>>
<<editcycle 'time' change 5>>
<<editcycle 'hunger' change 5>>
<<editcycle 'thirst' change 5>>
<<editcycle 'sleep' change -5>>
<</link>><div class="combat-container">
<div class="enemies-row">
<<for _i, _enemy range $enemies>>
<div class="enemy-container" @data-enemy-index="_i" data-selector>
<h2 class="enemy-name">_enemy.name</h2>
<span class="enemy-stamina">_enemy.stamina.current / _enemy.stamina.max</span>
<div class="portrait-container">
<img @src="_enemy.image" @alt="_enemy.name" class="enemy-portrait">
</div>
</div>
<</for>>
</div>
<<if $allies>>
<hr />
<div class="allies-row">
<<for _i, _ally range $allies>>
<div class="ally-container">
<h2 class="ally-name">_ally.name</h2>
<span class="ally-stamina">_ally.stamina.current / _ally.stamina.max</span>
<div class="portrait-container">
<img @src="_ally.image" @alt="_ally.name" class="ally-portrait">
</div>
</div>
<</for>>
</div>
<</if>>
<div class="action-buttons">
<button onclick="performAttack();">Attack</button>
<button onclick="performDefense();">Defend</button>
<button onclick="performFocus();">Focus</button>
<button onclick="performFlee();">Flee</button>
<div id="combat-loading" style="display: none; text-align: center;">
<em>Enemy is attacking...</em>
</div>
</div>
<div id="easymode" class="action-buttons" style="display: none;">
<button onclick="win();">Win fight</button>
<button onclick="lose();">Lose fight</button>
</div>
<div id="action-description" class="action-description">
$combatIntro
</div>
</div>
<<done>>
<<script>>
if (settings.easymode) {
document.getElementById('easymode').style.display = 'block';
}
if (window.updateTargetSelectionUI) {
updateTargetSelectionUI();
}
if (window.updatePreCalculatedActionDisplays) {
updatePreCalculatedActionDisplays();
}
$(document).on('click', '[data-selector]', function() {
var index = $(this).data('enemy-index');
selectTarget(index);
});
<</script>>
<</done>>You successfully fled from combat!
<<link "Continue" $fleePassage>>
<<unset $winPassage>>
<<unset $losePassage>>
<<unset $fleePassage>>
<</link>><h2>You win!</h2>
<<if $defeatedEnemies && $defeatedEnemies.length > 0>>
<h3>Defeated Enemies:</h3>
<<for _enemy range $defeatedEnemies>>
_enemy.name <br>
<</for>>
<br>
<div id="victory-actions" class="victory-actions">
<<link "Recruit All">>
<<script>>
State.variables.result = handleRecruitAll();
<</script>>
<<replace "#victory-actions">>
<<include $result>>
<</replace>>
<</link>>
<<link "Murder All">>
<<script>>
State.variables.result = handleMurderAll();
<</script>>
<<replace "#victory-actions">>
<<include $result>>
<</replace>>
<</link>>
<<link "Leave All">>
<<script>>
State.variables.result = handleLeaveAll();
<</script>>
<<replace "#victory-actions">>
<<include $result>>
<</replace>>
<</link>>
</div>
<</if>>
<<if !$defeatedEnemies || $defeatedEnemies.length === 0>>
<<link "Continue" $winPassage>>
<<unset $winPassage>>
<<unset $losePassage>>
<<unset $fleePassage>>
<</link>>
<</if>><h2>Recruitment Results</h2>
<<if $recruitedPeons && $recruitedPeons.length > 0>>
<p>You successfully recruited:</p>
<<for _peon range $recruitedPeons>>
<div class="recruited-peon">
<h4>_peon.Name.First _peon.Name.Last</h4>
<p>Race: _peon.Race | Gender: _peon.Gender | Age: _peon.Age</p>
</div>
<</for>>
<</if>>
<<if $failedRecruits && $failedRecruits.length > 0>>
<p>Failed to recruit: $failedRecruits</p>
<</if>>
<<link "Continue" $winPassage>>
<<unset $winPassage>>
<<unset $losePassage>>
<<unset $fleePassage>>
<</link>><h2>Recruitment Failed</h2>
<p>None of the enemies were willing to join you.</p>
<<link "Continue" $winPassage>>
<<unset $winPassage>>
<<unset $losePassage>>
<<unset $fleePassage>>
<</link>><h2>You murdered the enemies</h2>
<p>All defeated enemies have been killed.</p>
<p>I hope you feel bad.</p>
<<link "Continue" $winPassage>>
<<unset $winPassage>>
<<unset $losePassage>>
<<unset $fleePassage>>
<</link>><p>You leave your enemies lying on the ground.</p>
<<link "Continue" $winPassage>>
<<unset $winPassage>>
<<unset $losePassage>>
<<unset $fleePassage>>
<</link>><h2>You lose...</h2>
<<link "Continue" $losePassage>>
<<unset $winPassage>>
<<unset $losePassage>>
<<unset $fleePassage>>
<</link>><<script>>
UIBar.stow().hide()
<</script>>
<style>
#passages, #story, #passage-crash-location, .passage {
width: 100% !important;
max-width: 100% !important;
padding: 0 !important;
margin: 0 !important;
}
body {
min-height: 100vh;
background-color: var(--black);
margin: 0;
color: white;
overflow-x: hidden;
}
h1 {
margin-bottom: 20px;
font-size: 2.5em;
text-align: center;
}
#passages {
padding: 0 !important;
margin: 0 !important;
min-height: 100vh !important;
display: flex;
flex-direction: column;
justify-content: center;
}
body {
padding-top: 0 !important;
margin: 0 !important;
}
.ui-dialog {
top: 0 !important;
}
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
justify-content: center;
gap: 100px;
padding: 20px 5%;
width: 100%;
max-width: 100% !important;
box-sizing: border-box;
}
.choice-box {
justify-self: center;
width: 100%;
min-height: 600px;
height: auto;
border-radius: 30px;
box-sizing: border-box;
overflow: hidden;
display: flex;
flex-direction: column;
text-align: center;
background-color: var(--dark);
transition: all 0.3s ease;
position: relative;
cursor: pointer;
}
.choice-box:hover {
transform: scale(1.05);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5);
}
.choice-box img {
width: 100%;
height: 65vh;
max-height: 400px;
min-height: 300px;
object-fit: cover;
}
.choice-box p {
margin: 0;
padding: 15px;
font-size: 1.2em;
background-color: transparent;
transition: color 0.3s ease;
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
}
.choice-box:hover p {
color: var(--light);
}
.expanded-content {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(30, 30, 30, 0.9);
padding: 20px;
box-sizing: border-box;
overflow-y: auto;
}
.choice-box.expanded {
transform: scale(1.2);
z-index: 10;
transition: all 0.3s ease-out;
}
.choice-box.expanded .expanded-content {
display: block;
padding: 15px;
}
.link-button {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
background-color: #ffd700;
color: #121212;
text-decoration: none;
border-radius: 5px;
transition: background-color 0.3s ease;
}
.link-button:hover {
background-color: #ffea00;
}
@media (min-width: 2000px) {
.container {
grid-template-columns: repeat(4, minmax(400px, 1fr));
}
}
@media (max-width: 1999px) and (min-width: 900px) {
.container {
grid-template-columns: repeat(2, minmax(400px, 1fr));
}
}
@media (max-width: 899px) {
.container {
grid-template-columns: minmax(300px, 1fr);
}
.choice-box {
width: 90%;
max-width: 500px;
}
}
@media (max-width: 768px) {
.choice-box img {
height: 50vh;
}
h1 {
font-size: 2em;
}
.choice-box.expanded {
transform: scale(1.05);
margin: 1rem;
}
}
</style>
<body>
<h1>Select your landing location</h1>
<div class="container">
<div class="choice-box" onclick="expandBox(this)">
<img src="media/images/riverine_forest.jpg" alt="Riverine Forest">
<p>Riverine Forest</p>
<div class="expanded-content">
<h3>Riverine Forest</h3>
<p>From high above, a dark green ribbon winds through the landscape, following the serpentine path of a glistening river. <br><br> The dense canopy of the riverine forest creates a stark contrast with the surrounding terrain, its lush vegetation fed by the life-giving waters below.</p>
<<customButton "Aim at the Riverine Forest" "" "ForestCrash" "move-btn pulse-animation">><<script>>UIBar.unstow().show();<</script>><</customButton>>
</div>
</div>
<div class="choice-box" onclick="expandBox(this)">
<img src="media/images/rainforest.jpg" alt="Rainforest">
<p>Rainforest</p>
<div class="expanded-content">
<h3>Rainforest</h3>
<p>A vast, unbroken carpet of emerald green stretches across the curvature of the planet, occasionally obscured by swirling white clouds. <br><br> The immense scale of this verdant expanse is evident from space, hinting at the incredible biodiversity hidden beneath its canopy.</p>
<<link "Not Implemented">><</link>>
</div>
</div>
<div class="choice-box" onclick="expandBox(this)">
<img src="media/images/savannah.jpg" alt="Savannah">
<p>Savannah</p>
<div class="expanded-content">
<h3>Savannah</h3>
<p>Golden-hued plains dominate the view, punctuated by scattered dark spots representing solitary trees and small copses. <br><br> From this celestial vantage point, herds of wildlife appear as tiny moving specks, traversing the sun-baked landscape in search of water and grazing grounds.</p>
<<link "Not Implemented">><</link>>
</div>
</div>
<div class="choice-box" onclick="expandBox(this)">
<img src="media/images/islands.jpg" alt="Islands">
<p>Islands</p>
<div class="expanded-content">
<h3>Islands</h3>
<p>The islands form a stunning archipelago of emerald and turquoise gems against the deep blue ocean. <br><br> Their varied shapes and sizes create a mesmerizing pattern, from rugged volcanic peaks to smooth curved shorelines, all pristine and untouched.</p>
<<link "Not Implemented">><</link>>
</div>
</div>
</div>
<script>
function expandBox(box) {
document.querySelectorAll('.choice-box').forEach(el => el.classList.remove('expanded'));
box.classList.add('expanded');
event.stopPropagation();
}
document.addEventListener('click', function() {
document.querySelectorAll('.choice-box').forEach(el => el.classList.remove('expanded'));
});
</script>
</body>Placeholder.
You are from a very advanced galaxy spanning culture.
You were accused of a crime you did not commit and sentenced to eternal pain.
Injected with a strange serum, you were put into a stasis pod and launched into the void towards a barren planet.
You have the opportunity to guide your sentencing pod slightly.
[[Continue|Crash Location]]
<<link "DebugtoCamp" "CampSetup">>
<<set $campLoc to "Crater">>
<<set $dayIndex to 1>>
<<set $timeIndex to 0>>
<<set $actions to 3>>
<<set $showTime to true>>
<<editcycle 'thirst' resume>>
<<editcycle 'hunger' resume>>
<<editcycle 'sleep' resume>>
<</link>>
<<set $healthIndex to 2>>
<<set $intro to false>>
<<set $location to "Unknown">>
<<set $dayIndex to -2>>
<<set $weekIndex to 1>>
<<set $monthIndex to 1>>
<<set $yearIndex to 1>>
<<set $placesArray to ["Woods", "River", "Lake", "Clearing"]>><<set $time to ["morning", "noon", "evening", "night"]>>
<<set $health to ["dying", "wounded", "bruised", "fine", "good", "divine"]>>
<<script>>
if (typeof State.variables.inventory === 'undefined') {
State.variables.inventory = [];
}
if (typeof State.variables.profileImage === 'undefined') {
State.variables.profileImage = 'media/portraits/portrait.svg';
}
if (typeof State.variables.activeBuffs === 'undefined') {
State.variables.activeBuffs = new Set();
}
gender.setPronouns("other");
const unitDefaults = {
image: "media/portraits/portrait.svg",
};
fetch('data/units.json')
.then(response => {
if (!response.ok) throw new Error('Failed to load units.json');
return response.json();
})
.then(data => {
const processedUnits = data.map(unit => {
const mergedUnit = { ...unitDefaults, ...unit };
if (!unit.hasOwnProperty('image')) {
switch (mergedUnit.faction) {
case 'enemy':
mergedUnit.image = "media/portraits/ogre.svg";
break;
case 'friendly':
mergedUnit.image = "media/portraits/invisible-face.svg";
break;
}
}
return mergedUnit;
});
setup.units = processedUnits;
State.variables.units = processedUnits;
debugLog('Processed units with faction-based defaults:', processedUnits);
})
.catch(error => console.error('Error loading units.json:', error));
fetch('data/combat.json')
.then(response => {
if (!response.ok) throw new Error('Failed to load combat.json');
return response.json();
})
.then(data => {
setup.combatDescriptions = data.descriptions;
debugLog('Combat descriptions loaded:', setup.combatDescriptions);
})
.catch(error => {
console.error('Error loading combat.json:', error);
setup.combatDescriptions = {
melee: ["You attack {enemy}!"],
ranged: ["You attack {enemy}!"],
defeated: ["{enemy} is defeated!"]
};
});
fetch('data/resources.json')
.then(response => {
if (!response.ok) throw new Error('Failed to load resources.json');
return response.json();
})
.then(data => {
const resourcesMap = data.reduce((map, resource) => {
map[resource.name] = resource;
return map;
}, {});
setup.resources = resourcesMap;
State.variables.resources = resourcesMap;
debugLog('Processed resources as map:', resourcesMap);
})
.catch(error => console.error('Error loading resources.json:', error));
fetch('media/faces/_faces.json')
.then(response => {
if (!response.ok) throw new Error('Failed to load faces.json');
return response.json();
})
.then(data => {
setup.faceData = data;
const featureCategories = ['faces', 'eyes', 'eyebrows', 'nose', 'mouth', 'ears', 'hair', 'detail'];
const files = featureCategories.flatMap(cat =>
(data[cat] || []).map(file => ({ category: cat, filename: file }))
);
debugLog(`Preloading ${files.length} face SVGs...`);
return Promise.all(
files.map(({ filename }) => {
const path = `media/faces/${filename}.svg`;
return fetch(path)
.then(response => {
if (!response.ok) throw new Error(`Failed to load ${path}`);
return response.text().then(svg => [path, svg]);
});
})
).then(entries => {
setup.faceMap = new Map(entries);
});
})
.then(() => debugLog('All face SVGs preloaded successfully'))
.catch(error => console.error('Error loading faces:', error));
<</script>>
<<set $timeImage to "media/images/sunrise.png">>
<<set $exploredPassages to {}>>
<<set $showTime to false>>
<<set $physicalAge to 25>>
<<set $chronologicalAge to 25>>
<<set $timeSave to false>>
<<set $inventoryCount to 0>>
<<newcycle 'time' 5 1>>
<<phase 'morning'>>
<<phase 'noon'>>
<<phase 'evening'>>
<<phase 'night'>>
<</newcycle>>
<<newcycle "hunger" 20 1 suspend>>
<<phase full>>
<<phase hungry>>
<<phase famished>>
<<phase starving>>
<<phase malnourished>>
<</newcycle>>
<<newcycle "thirst" 10 1 suspend>>
<<phase quenched>>
<<phase thirsty >>
<<phase parched>>
<<phase dehydrated>>
<<phase desiccated>>
<</newcycle>>
<<newcycle "sleep" 20 1 suspend>>
<<phase rested>>
<<phase drowsy>>
<<phase tired>>
<<phase lethargic>>
<<phase fatigued>>
<</newcycle>><<nobr>>
<<set $healthClass to "health-" + $health[$healthIndex]>>
<<if $location>>
Location: $location
<</if>>
<<if $dayIndex > -1>>
<<if Cycle.check('time', 'morning')>>
<<set $timeImage to "media/time/sunrise.png">>
<<elseif Cycle.check('time', 'noon')>>
<<set $timeImage to "media/time/noon.png">>
<<elseif Cycle.check('time', 'evening')>>
<<set $timeImage to "media/time/dusk.png">>
<<elseif Cycle.check('time', 'night')>>
<<set $timeImage to "media/time/night.png">>
<<elseif $showTime>>
<<unset $timeImage>>
<</if>>
<<if $timeImage>>
<div class="time-location-wrapper">
<<if $locationImage>>
<img src="$locationImage" class="location-image">
<</if>>
<<if $showTime>>
<img src="$timeImage" class="time-indicator">
<</if>>
</div>
<</if>>
<br>
<<if $showTime>>
Time of day: <<showcycle 'time' upperfirst>>
<br><br>
Year $yearIndex <br>
Month $monthIndex <br>
Week $weekIndex <br>
Day $dayIndex
<br><br>
<</if>>
<div class="health-display-container">
You are <span id="health-status"></span>
</div>
<div id="player-stamina" style="display:none;">
<span class="player-stamina">Stamina: 0 / 0</span>
</div>
<br><br>
<div id="buffs-container"></div>
<img src="media/images/borders/divider/fade-divider/divider-fade-001.png" class="divider">
<a href="#" class="link-internal" id="characterLink">Character</a> <br> <br>
<a href="#" class="link-internal" id="inventoryLink">Inventory</a> <br> <br>
<<if $codexUnlocked is true>>
<a href="#" class="link-internal" id="codexLink">PHIL</a> <br> <br>
<</if>>
<<if $mapUnlocked is true>>
<a href="#" class="link-internal" id="mapLink">Map</a> <br> <br>
<</if>>
<<if Config.debug>>
<a href="#" class="link-internal" id="debugLink">Debug menu</a>
<</if>>
<img src="media/images/borders/divider/fade-divider/divider-fade-001.png" class="divider">
<</if>>
<</nobr>>Icons from:
https://game-icons.net/ https://www.flaticon.com
from authors:
Viscious Speed https://viscious-speed.deviantart.com/ [CC0 PDD]
Delapouite https://delapouite.com/ [CC BY 3.0]
Lorc https://lorcblog.blogspot.com/ [CC BY 3.0]
sbed https://opengameart.org/users/sbed [CC BY 3.0]
Freepik https://www.freepik.com/
Flat Icons https://flat-icons.com/<<link "Credits">>
<<script>>
Dialog.create("Credits")
.wikiPassage("Credits")
.open();
<</script>>
<</link>><div id="start-container">
<h1>Character Creation</h1>
<p>Set your name, pronouns, and formal title</p>
<div class="input-group">
<label for="first-name">First Name:</label>
<<textbox "$first_name" "Dion">>
</div>
<div class="input-group">
<label for="last-name">Last Name:</label>
<<textbox "$last_name" "Cyrellis">>
</div>
<div class="input-group">
<label>Pronouns:</label>
<<link 'Configure your gender and pronouns.'>>
<<pronouns>>
<</link>>
This can be changed at any time in the settings menu.
</div>
<div class="input-group">
<label for="title">Title:</label>
<<textbox "$formal" "Seres">>
</div>
<div class="input-group">
<label for="profile-image">Custom Profile Image:</label>
<input type="file" id="profile-image" accept="image/*">
</div>
<div class="input-group">
<img id="profile-preview" src="" alt="Profile Image Preview" style="display: none; max-width: 100%; height: auto; border-radius: 10px; margin-top: 10px;">
</div>
<<customButton "Submit" "" "Prologue" "move-btn pulse-animation" "media/icons/play-button.svg" "large" "Welcome $formal $first_name $last_name !">><</customButton>>
</div>
<<set $intro to true>><h1>Uh oh you reached a passage only possible if there was an error</h1>
<<back "Go Back">>
<br><br>
<h3>Export Debug Data</h3>
<p>Please add some information on what your previous actions were.</p>
<p>Copy the text below and email it to me:</p>
<textarea readonly id="save-export" style="width:100%; height:150px; font-family:monospace; font-size:11px;"></textarea>
<<done>>
<<script>>
document.getElementById("save-export").value = Save.base64.save();
<</script>>
<</done>>
<<button "Copy to Clipboard">>
<<script>>
var textarea = document.getElementById("save-export");
textarea.select();
document.execCommand("copy");
// Feedback
var btn = this;
btn.textContent = "✓ Copied!";
btn.disabled = true;
setTimeout(() => {
btn.textContent = "Copy to Clipboard";
btn.disabled = false;
}, 2000);
<</script>>
<</button>><<nobr>>
<<set $location to "Clearing">>
<<set $locationImage to "media/locations/riverine_forest_map_no_camp.webp">>
The forest spits you into a clearing; a cruel parody of sanctuary. Your vision swims, each breath a razor-drawn gamble, as you collapse against a moss-veined rock. The air reeks of damp earth and your own blood.
<br><br>
Somewhere ahead, water rasps over stone, its taunting chorus sharper than the wind's hollow dirge through the pines.
<br><br>
<i>Move</i>, your failing body screams, but the clearing's soft moss yawns like a grave. Shadows thicken at the edges of your sight.
<br><br>
Even the sunlight feels accusatory here, dappling the ground as if to say: <i>This is where you'll bleed out. This is where the planet swallows you whole.</i>
<br><br>
[[You pass out|PassOut]]
<</nobr>><<nobr>>
<<script>>
UIBar.stow().hide();
increaseDate(5);
<</script>>
<<unset $locationImage>>
<<unset $location>>
<<unset $showTime>>
<<editcycle 'time' increment 20>>
<<timed 2s>><<fadein 3s>>
<span style="font-size: 2em; font-weight: bold;">.</span>
<</fadein>>
<<next 1s>><<fadein 2s>>
<span style="font-size: 2em; font-weight: bold;">.</span>
<</fadein>>
<<next 1s>><<fadein 2s>>
<span style="font-size: 2em; font-weight: bold;">.</span>
<</fadein>>
<</timed>>
<</nobr>>
<<timed 8s>><<fadein 4s>>
Consciousness claws its way back. Above you, the stars glare like shattered glass; cold, sharp, indifferent. The forest presses closer now, its silhouette jagged and breathing. Something wet soaks your tattered clothes; your blood, pooling in the moss. The air reeks of copper and rot.
<</fadein>><<next 5s>><<fadein 2s>>
<span>You are alive.</span>
Your ribs scream. Your leg bends wrong. A gash in your side pulses in time with your heartbeat, each throb a whisper: <i>This is how you die here. This is how the soil drinks you.</i> The hunger is a feral thing, gnawing at your stomach. Thirst cracks your tongue. Every breath tastes like failure.
<span style="font-style: italic;">You are alive.</span>
The ground hums. Roots curl around your wrists. <i>Stay</i>, they hiss. <i>Lie still. Let the planet peel you apart. Let the crows feast.</i> Your eyelids flutter. The stars blur.
<span style="font-weight: bold; font-style: italic;">You are alive.</span>
<<linkreplace "Defy the forest">><<fadein 1s>>
You lurch sideways, retching bile. The world tilts. Your mangled leg buckles, you claw at a sapling, snapping it in your grip. Blood slicks your palms. Shelter. Water. Fire. The words echo, brittle and distant. The forest leers. <i>You'll die crawling</i>, it taunts. But crawl anyway.
You slump against the gnarled trunk, its bark gouging your spine like teeth. The forest's laughter dies to a venomous hum, but its eyes linger; glints of starlight caught in the leaves above. Your breath rasps, a broken rhythm chanting: <i>Alive. Alive. Alive.</i> Blood slicks the roots beneath you, black in the moonlight. Somewhere, the river still mocks. Somewhere, your body still obeys.
The cold seeps into your bones. The shadows thicken. But the tree stands. But your heart beats. But the night is not eternal.
[[Rest|ClearingRested]]
<</fadein>><</linkreplace>>
<</fadein>>
<</timed>><<nobr>>
<<set $healthIndex to 1>>
<<editcycle 'time' increment 1>>
<<set $location to "Clearing">>
<<set $locationImage to "media/locations/riverine_forest_map_no_camp.webp">>
<<set $showTime to true>>
<<script>>
increaseDate(2);
setup.Cycle.get('thirst').resume();
setup.Cycle.get('thirst').update(20);
setup.Cycle.get('hunger').resume();
setup.Cycle.get('hunger').update(40);
setup.Cycle.get('sleep').resume();
removeBuff(3);
<</script>>
<</nobr>><<fadein 5s>><h2>The sun's light is a liar.</h2>
It paints your skin in gold while your body screams; every muscle a knotted rope, every bone ground to dust.
Your leg pulses: a forge-hot hammer striking iron.
<i>
Strike.
Strike.
Strike.
</i>
Relentless as the planet's heartbeat.
<<linkreplace "Open your eyes">><<nobr>><<script>>UIBar.unstow().show();<</script>><</nobr>><<fadein 1s>>The forest greets you in a haze of chlorophyll and cruelty. Sunlight stabs through the canopy, needling your pupils. Blurred shapes sharpen: ferns bowed like mourners, roots coiled like snakes. Then, movement. A small, feathered thing jabs its beak into your calf. Again. <i>Again.</i> It tears at dried blood, at scab-flecked skin. You twitch. It flutters back, beady eyes glinting; <i>hungry</i>, not afraid.
Your clothes cling, stiff with filth and old gore. But the wounds… gone. In their place: scars, pale and ropey, as if the forest itself stitched you back together. <i>Wrong.</i> Your throat cracks. Your stomach gnaws itself. You taste bile and pine resin.
<i>You should be dead.</i>
The trees creak in agreement. The bird watches, waiting. Above, the sky pales into dawn, its light thin and grudging. Cold still clings to the air. Predators will wake.
And the pod, rusted relic of a dead hope, still lurks somewhere in this green hell. It has metal. Circuitry. Data. Corroded teeth to pry loose. Dead hope to scavenge. <i>Lies.</i>
<<linkreplace "Kick the bird">>You lash out, leg screaming as you kick toward the creature; a mangled, graceless arc. The bird hops sideways, unbothered. Its head tilts. Black eyes lock onto yours, unblinking. <i>Pathetic,</i> they seem to say. A guttural croak escapes its throat, more rasp than song. Then it pecks again. <i>Harder.</i> Blood blooms fresh on your calf. The forest holds its breath.<</linkreplace>>
The clearing's false peace shatters. <i>You cannot stay.</i>
<<nobr>>
<<linkreplace "Leave this place">>
<<fadein 1s>>
<div class="choice-header">Where will you go?</div>
<br>
<div class="buttongrid">
<<customButton "Stagger toward the pod"
"The pod's carcass lies behind; rusted metal, frayed wires, data corroded to gibberish."
"PodRoute"
"move-btn"
"media/icons/apollo-capsule.svg"
"large">>
<<script>>debugLog("Moving to pod");<</script>>
<</customButton>>
/*
<<customButton "Stagger toward the river"
"The river hisses your name. Its water is a liquid grave, but your throat burns like ash."
"RiverRoute"
"move-btn"
"media/icons/river.svg"
"large">>
<</customButton>>
<<customButton "Stagger toward the forest"
"Branches sag like gallows. Roots writhe like nooses. The forest offers shelter in exchange for flesh."
"ForestRoute"
"move-btn"
"media/icons/forest.svg"
"large">>
<</customButton>>
<<customButton "Stagger toward the lake"
"The lake's breath reeks of algae and rot. Fish bones litter the shallows; salvation or slow poison?"
"LakeRoute"
"move-btn"
"media/icons/at-sea.svg"
"large">>
<</customButton>>
*/
</div>
<br>
<div class="disclaimer">
Your choice is not permanent, all locations will remain accessible.
</div>
<</fadein>>
<</linkreplace>>
<</nobr>>
<</fadein>><</linkreplace>><</fadein>><div class="choice-header">Where will you go?</div>
<br>
<div class="buttongrid">
<<customButton "Stagger toward the pod"
"The pod's carcass lies behind; rusted metal, frayed wires, data corroded to gibberish."
"PodRoute"
"move-btn"
"media/icons/apollo-capsule.svg"
"large">>
<<script>>debugLog("Moving to pod");<</script>>
<</customButton>>
/*
<<customButton "Stagger toward the river"
"The river hisses your name. Its water is a liquid grave, but your throat burns like ash."
"RiverRoute"
"move-btn"
"media/icons/river.svg"
"large">>
<</customButton>>
<<customButton "Stagger toward the forest"
"Branches sag like gallows. Roots writhe like nooses. The forest offers shelter in exchange for flesh."
"ForestRoute"
"move-btn"
"media/icons/forest.svg"
"large">>
<</customButton>>
<<customButton "Stagger toward the lake"
"The lake's breath reeks of algae and rot. Fish bones litter the shallows; salvation or slow poison?"
"LakeRoute"
"move-btn"
"media/icons/at-sea.svg"
"large">>
<</customButton>>
*/
</div>
<br>
<div class="disclaimer">
Your choice is not permanent, all locations will remain accessible.
</div>You awaken in a smoldering crater, the aftermath of your own catastrophic descent. The air is thick with the scent of scorched earth and the acrid tang of burnt metal. Every fiber of your being throbs with a relentless, all-encompassing pain, as if the very essence of your existence has been shattered and reassembled in the most agonizing manner possible.
<<timed 2s>><<fadein 2s>>[[Look around]]<</fadein>><</timed>>
<<set $healthIndex to 0>>
<<set $intro to false>>
<<set $location to "Unknown">>
<<set $dayIndex to 0>>
<<set $totalDays to 0>>
<<set $timeIndex to 0>>
<<set $actions to 3>>
<<set $placesArray to ["Woods", "River", "Lake"]>>
<<done>>
<<script>>
equipItem(addItemToInventory(0));
equipItem(addItemToInventory(1));
equipItem(addItemToInventory(2));
addBuff(3);
<</script>>
<</done>>
<<shakescreen 1.5s>>Vision bleeds into clarity. The crater walls loom; jagged teeth slick with ash. To your left, a slope <i>almost</i> navigable: dirt scarred by your crash, roots exposed like broken ribs. Beyond it, the forest waits. Not trees; <i>sentinel pines</i>, their trunks blackened by firelight, branches tangled into a cage. The air thrums. Insects shriek. Somewhere, water hisses. A taunt. A <i>dare</i>.
[[Drag yourself upward, toward the slope|LandingCraterEdge]]<<nobr>>
<<set $showTime to true>>
<<set $location to "Crater's Edge">>
<<set $locationImage to "media/locations/crater-edge.jpg">>
<</nobr>>
Every inch is a battle. Elbows gouge dirt. Knees shred against stone. Halfway up, you retch; bile and blood flecking the soil. The crater <i>clings</i>, as if the planet resists your escape. But you crawl. You crawl until fingernails split and breath frays to nothing.
<<timed 2s>><<fadein 1s>>
At the rim, the world unfurls in shades of green and ruin. Behind you: the pod's carcass, still spitting embers into the dawn. Ahead: a primordial forest, so dense it swallows light. To the east, a clearing glows; a liar's promise of safety. Beyond it, water glints, sharp as a blade.
[[Stare at the clearing|ClearingCrash]]
<</fadein>><<next 1s>><<fadein 3s>>
...a river's voice rises. Not a murmur. A <i>laugh</i>.
<</fadein>><</timed>><<include "CampStatus" "div">>
<<include "CampActions" "div">>
<<print getPassageSize(passage());>><<set _next to exploreArea("crater")>>
<<if _next>>
<<goto _next>>
<<else>>
There are no more unexplored locations in the crater.
<</if>>
<<return "Return">>You got evented!
[[CraterCamp]]CE1, this is a permanent exploration passage
[[CraterCamp]]CE2
This will be put inside the exploredPassages variable and not be visited again.
[[CraterCamp]]CE3
This will be put inside the exploredPassages variable and not be visited again.
[[CraterCamp]]<<nobr>>
<<first>>
Placeholder first exploration of the lake.
<<run $placesArray.delete(passage())>>
<<run $exploredPlaces.push(passage())>>
<<finally>>
Placeholder returning to the lake.
<</first>>
<</nobr>>
[[Camp]]Uh oh, you fell in the water!
<<link "Continue" $continue>><</link>><<nobr>>
<<first>>
Placeholder first exploration of the river.
<<run $placesArray.delete(passage())>>
<<run $exploredPlaces.push(passage())>>
<<finally>>
Placeholder returning to the river.
<</first>>
<</nobr>>
[[Camp]] [[Wade out into the river|RiverMiddle]]You are standing in the middle of a river.
You can see a small fire on the other side of the river.
[[Back to the river bank|River]] [[Go to the other side|Other Side of the River]]You are on the other side of the river.
[[Back to camp|Camp]] [[Go back in the river|RiverMiddle]]
<<first>>
<<run $exploredPlaces.push(passage())>>
<</first>><<nobr>>
<<set $location to "Craters Edge">>
<<set $locationImage to "media/locations/crater-edge.jpg">>
<</nobr>>
The pod. Your only anchor in this green hell. <i>It WILL save you.</i> The thought claws through the pain, a lifeline thrown to drowning flesh.
You rise. Joints scream like rusted hinges. Muscles tear like rotten fabric. The forest watches - a thousand leafy eyes judging your stumbling betrayal of its mossy grave.
The earth tilts. Roots snake around your ankles, whispering <i>stay, decay, become soil</i>. You wrench free. Blood blooms fresh on your calf where the bird feasted.
The path ahead: a cathedral of destruction. Fallen giants lie splayed like broken ribs, their splintered bones jutting skyward. You crawl through their graveyard:
Bark scrapes raw palms.
Rot stings nostrils with the sweet stench of dying worlds.
Shadows pool like blood beneath shattered trunks.
Your fingers sink into pulpy wood. Beetles swarm from the wound, black carapaces gleaming like spilled oil. At the crest, the crater gapes below - your past and future screaming from its depths.
There. At the epicenter of ruin:
The pod's carcass.
Twisted metal breathing smoke.
Your origin story written in scorch marks.
<i>Promises rusting in alien rain.</i>
<<linkreplace "Lean over the edge">>
<<fadein 2s>>
Acrid smoke drills into your sinuses - the sacred incense of shattered technology. Below lies your genesis-turned-tomb:
Twisted metal ribs curl skyward like a skeletal prayer.
Molten cables bleed black ichor into the soil.
Heat shimmers dance above the wreckage, mocking mirages of safety.
<i>This rusted corpse birthed you. Now it calls you home.</i> The crater's edge crumbles beneath your weight. Pebbles skitter down the slope, each click echoing like a countdown.
[[Climb down the craters edge|Crater]]
<</fadein>>
<</linkreplace>><<nobr>>
<<set $location to "Crater">>
<</nobr>>
The earth betrays your every step. Stones roll like conspirators beneath your <<print window.getItemInSlot("feet").name.toLowerCase();>>, sending you skidding down the slope in a miniature avalanche of scree. Each impact hammers through shattered ribs. <<set $painLevel += 1>>
A choking shroud of dust swallows the world; grave dirt clotting in your throat, blinding you to everything but the pod's grim silhouette. Every breath rasps the same warning: <i>you shouldn't be here</i>.
Your <<print window.getItemInSlot("feet").name.toLowerCase();>> sink into ash fine as cremated bones. Residual heat radiates through, cooking your soles.
The pod's carcass reveals itself in horrific intimacy: hull plates peeled back like rotting fruit skin; support struts snapped like femurs; the cockpit window webbed with cracks - a dead insect eye staring at heaven.
The air thrums with dying energy. Old scars pulse in time with the machinery's final heartbeats.
In front on the wretched carcass, an impish creature is moving, tearing, biting the metal corpse.
<<nobr>>
<<linkreplace "Pick up a rock">>
<<script>>
equipItem(addItemToInventory(8));
<</script>>
You find a small rock, holding it with your right hand.
<</linkreplace>>
<</nobr>>
<<link "Get Closer" "CraterGoblin">><</link>><<script>>
generateEnemies([{ type: "goblin",
name: "impish creature",
armor: "none",
weapon: "stone",
attributes: {
constitution: 5,
defense: 2
}
}]);
<</script>>
<<set $combatIntro to "It freezes. You can see its hand shaking fiercely. Slowly, it turns... and you see yourself reflected in eyes like fractured obsidian. A guttural hiss escapes its throat as it raises a $enemy.weapon carved from the crater's bones.">>
<<done>>
<<script>>window.startCombat('CraterGoblinWin', 'CraterGoblinLoss', 'CraterConsideration', true, true);<</script>>
<</done>>
<<include "CombatUI">>Your blow lands with sickening finality - the crunch of bone beneath desperate strength. The creature staggers, a wet rattle bubbling in its throat. For one suspended moment, its obsidian eyes hold yours... then it collapses face-first into the dust. Engine oil spills out of the creatures mouth, blooming around its skull like a black halo.
The pod stands unchallenged now - your steel womb, your shattered ark. Its wounds glow dully in the fading light.
<<nobr>>
<<linkreplace "Search the pods carcass">>
<<addclass "a[data-passage='CraterConsideration']" "hidden">>
<<fadein 1s>>
Ruin greets you. The pod's electronic heart lies eviscerated; silicon entrails spilled across scorched earth.
<</fadein>>
<br>
<<fadein 1s 3s>>
Torn wiring snakes through ash, copper veins ripped raw and weeping energy.
<</fadein>>
<br>
<<fadein 1s 6s>>
Hull plates curl like dead petals, revealing structural bones snapped clean through.
<</fadein>>
<br>
<<fadein 1s 9s>>
Inside the coffin-cage: restraints hang like gutted serpents, still smelling of your terror.
<</fadein>>
<br>
<<fadein 1s 12s>>
There. A hull plate hangs by a metallic sinew - cracked edge gleaming like a promise.
<br>
<<fadein 1s 15s>>
<<linkreplace "Claim the shard">>
<<script>>addItemToInventory(4);<</script>>
Metal screams as you wrench it free. The broken edge cuts your palm - a blood pact sealed.
<<removeclass "a[data-passage='CraterConsideration']" "hidden">>
<br><br>
<<linkreplace "Search inside the pod">>
Digging around in the oil and blood on the pods' inside, there is a small piece of tarp. Barely reaching it through the wiring and hanging restraints, you grasp the edge and is able to lift it out of the pod.
<br><br>
Inside the tarp is a small rectangular machine, backside covered in photovoltaic cells. Trying to power it on, nothing happens. <i>"It must be discharged"</i> you realize. <<set $codexGet to $totalDays>>
<<script>>addItemToInventory(9);<</script>>
<</linkreplace>>
<</linkreplace>>
<</fadein>>
<</fadein>>
<</linkreplace>>
<</nobr>>
[[Inspect the crater|CraterConsideration]]The world detonates in white agony as stone meets temple. You taste blood and silicate dust. Through your swimming vision, the creature looms - a shrieking gargoyle carved from nightmares. Its $enemy.weapon descends again...
<<fadein 200ms 2s>>
You wake to the pod's corpse groaning above you. Blood crusts your eyelashes. The creature is gone, but its guttural chittering echoes over the crater's rim. Your chance at salvation bleeds into the hungry soil.
<<if !settings.easyMode>>
How did you lose this battle? 😮💨
There is a toggle for easy combat mode in the settings.
<</if>>
<</fadein>>
<<link "Retry combat with more health?" "CraterGoblin">><<set $healthIndex to 3>><</link>>
[[Drag yourself to shelter and skip the battle|CraterConsideration]]The crater holds you in its dusty hand. You taste metal on the wind, the pod's dying breath. This scar in the earth birthed you; now it offers brutal sanctuary. Your gaze surveys the ashes of your arrival:
<<linkreplace "Consider the crater as shelter">>
<<fadein 1s>>
The pod's carcass lies broken but rich; veins of wiring to harvest, hull plates to salvage. Days could be spent tearing secrets from its ribs.
No reprieve from the sun's hammerblow... but when rain comes, that twisted metal roof will sing. And the crater walls? They'll break the wind's teeth.
No berries. No streams. Just dust that coats your tongue like ash. Every hour spent scavenging metal is an hour your stomach screams.
Shadows pool thickest where wreckage meets earth. That impish creature came from somewhere. How many more eyes study you from the rim?
<</fadein>>
<<fadein 1s 2s>>
<<linkreplace "Claim the crater as shelter">>
<<fadein 2s>>
You press a palm against the pod's still-warm skin. <i>"We're both stranded here,"</i> you whisper to the dead metal. <i>"At least one of us will survive." </i>
<<link "Explore the crater" "CampSetup">><<set $campLoc to "Crater">><</link>>
<</fadein>>
<</linkreplace>>
[[Retreat to the forest's edge|Clearing]]
<</fadein>>
<</linkreplace>><<nobr>>
<<set $location to 'Dark forest'>>
<<set $locationImage to 'media/locations/forest.webp'>>
<</nobr>>
The forest contains the necessary material for shelter and game to hunt.You decide that a day at the lake sounds perfect.
Standing up, aching joints makes themselves known, you listen for the soft sound of water and start your journey.You decide that drinkable water and possibly food is your primary goal.
Standing up, aching joints makes themselves known, you lumber towards the rivers murmur.<<nobr>>
<<first>>
Placeholder first exploration of the woods.
<<run $placesArray.delete(passage())>>
<<run $exploredPlaces.push(passage())>>
<<finally>>
Placeholder returning to the woods.
<</first>>
<</nobr>>
[[Camp]]
<<set $playerX = 57>>
<<set $playerY = 53>>
<<set $location to "Woods">>