Batman: I forgot to commit the new website branch so I guess here it is

with bun and a cool game page
This commit is contained in:
2026-09-06 15:46:06 -04:00
commit b5fb570df4
12 changed files with 580 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
# dependencies (bun install)
node_modules
# output
out
dist
*.tgz
# code coverage
coverage
*.lcov
# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# caches
.eslintcache
.cache
*.tsbuildinfo
# IntelliJ based IDEs
.idea
# Finder (MacOS) folder config
.DS_Store
+15
View File
@@ -0,0 +1,15 @@
# escape
To install dependencies:
```bash
bun install
```
To run:
```bash
bun run index.ts
```
This project was created using `bun init` in bun v1.4.0. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+66
View File
@@ -0,0 +1,66 @@
{
"lockfileVersion": 2,
"configVersion": 1,
"workspaces": {
"": {
"name": "escape",
"devDependencies": {
"@types/bun": "latest",
},
"peerDependencies": {
"typescript": "^7",
},
},
},
"packages": {
"@types/bun": ["@types/bun@1.4.0", "", { "dependencies": { "bun-types": "1.4.0" } }, "sha512-K+lZULY23vRgK/CfTjFIV+tyifaNdSMlPh9j+6mQ/cLfpOznLyAuzgV/JQysyECpkBQLVMSyvjlr2fBUSA9wFQ=="],
"@types/node": ["@types/node@26.4.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA=="],
"@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ=="],
"@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA=="],
"@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA=="],
"@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ=="],
"@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw=="],
"@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ=="],
"@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ=="],
"@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ=="],
"@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA=="],
"@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA=="],
"@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ=="],
"@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw=="],
"@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A=="],
"@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA=="],
"@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.2", "", { "os": "none", "cpu": "x64" }, "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA=="],
"@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ=="],
"@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg=="],
"@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g=="],
"@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ=="],
"@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g=="],
"bun-types": ["bun-types@1.4.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-iIKw23BspnQQYd3prITOBxeUsxBHnwzX6YJfGMuNOZzeNcMmVqzIIVGRm1l69ogaPQmb4wB6BN8mA5bE9YuC5Q=="],
"typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="],
"undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
}
}
+141
View File
@@ -0,0 +1,141 @@
<!doctype html>
<html>
<head>
<title>Escape the Island</title>
<link rel="icon" type="image/x-icon" href="assets/shipwreck.png" />
<link rel="stylesheet" href="styles.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Almendra:ital,wght@0,400;0,700;1,400;1,700&display=swap"
rel="stylesheet"
/>
<style></style>
</head>
<body>
<header>
<div class="header-container">
<h1>Escape the Island</h1>
<div class="boat-container">
<img src="assets/boat.png" alt="" class="boat" />
</div>
</div>
</header>
<div class="Content">
<div class="Instruction">
<p>Backstory</p>
<details>
<summary>Click to expand</summary>
<p>
You and your class planned to go on a one week cruise trip over
spring break to learn about how inflation affects nautical
exploration and catching some sun. The cruise ship is built a pirate
ship which you all find amusing at first. However, issues arise from
an underlying problem. They didn't have the money to get schedule a
final inspection before departing, but they still let you go anyways
(because they are broke). As the boat leaves and cruises away from
land, you see rocky terrain that has formed in the middle of the
ocean (shocking). Your boat hits it and as people don't learn from
the titanic, you don't have enough life boats to fit everyone and
make it home safely. Everybody else gets on boats while you and your
classmates are still on the boat (coincidentally). One of your
friends believes he has a boat license (he doesn't) and tries to
steer the boat before you sink. Magically you find an island. You
all get onto the island safely but with no way home, scattered and
disoriented.
</p>
</details>
</div>
<div class="Instruction">
<p>Objective</p>
<details>
<summary>Click to expand</summary>
<p>
You will have 16 hours each day to gain as many resources as
possible to survive. You must choose what to spend your hours doing
each day carefully. The survival requirement for the end of each day
is to have 8 fish and 4 pieces of lumber. Otherwise, you die (lose).
You will be able to trade with other classmates you have found
stranded at no expense of your daily hours.
</p>
</details>
</div>
<div class="Instruction">
<p>Requirements</p>
<details>
<summary>Click to expand</summary>
<ol>
<li>
In order to escape, you must have 24 stockpiled fish and a boat at
the START of a new day.
</li>
<li>Fish will go bad without a preserver.</li>
<li>
Improving skills requires 8 hours and adds 1 per hour the next
day.
</li>
<li>Building a preserver requires 8 hours and 25 wood</li>
<li>Building a boat requires 16 hours and 100 wood</li>
<li>You can only trade with "found" players</li>
<li>
It is recommended to donate resources to other players at end of
day if you have a boat (Need to have 24 fish to leave)
</li>
</ol>
</details>
</div>
<div class="game">
<div class="table-container">
<table>
<tr>
<th></th>
<th>Fishing Stats</th>
<th>Foraging Stats</th>
</tr>
<tr>
<th style="width: 25%">Days: <span id="days">0</span></th>
<td id="fish_p_hour">0</td>
<td id="wood_p_hour">0</td>
</tr>
<tr>
<th style="width: 25%">
Players Found: <span id="found">0</span>
</th>
<td>Preserver: <span id="preserver">No</span></td>
<td>Boat: <span id="boat">No</span></td>
</tr>
<tr>
<th style="width: 25%">Hours Left: <span id="hours">16</span></th>
<td>Stored Fish: <span id="fish_stored"></span></td>
<td>Stored Wood: <span id="wood_stored"></span></td>
</tr>
</table>
</div>
<div class="button-container">
<div class="button-container-part">
<button type="button" id="go-fishing">Go Fishing</button>
<button type="button" id="go-foraging">Go Foraging</button>
<!-- <button type="button" id="trading">Trade</button> -->
</div>
<div class="button-container-part">
<button type="button" id="improve-fishing">
Improve Fish Per Hour
</button>
<button type="button" id="build-preserver">Build Preserver</button>
<button type="button" id="improve-forgaing">
Improve Wood Per Hour
</button>
<button type="button" id="build-boat">Build Boat</button>
</div>
</div>
</div>
</div>
<footer>
<h3 style="padding: 10px 0px 0px 10px">
Gamemaker: Mr. J. Walla ~=~ Developer: Andrew H. ~=~ Designer: Logan C.
</h3>
</footer>
<script src="index.js"></script>
</body>
</html>
+107
View File
@@ -0,0 +1,107 @@
function create_player_stats() {
let x = Math.floor(Math.random() * 2) + 1;
let y = 0;
if (x == 1) {
y = 2;
} else {
y = 1;
}
return { x: x, y: y };
}
let x, y;
function init() {
if (localStorage.getItem("player_x")) {
x = parseInt(localStorage.getItem("player_x"));
y = parseInt(localStorage.getItem("player_y"));
} else {
let player = create_player_stats();
x = player.x;
y = player.y;
localStorage.setItem("player_x", x);
localStorage.setItem("player_y", y);
}
return { x: x, y: y };
}
let player = init();
let gamedata = {
fishing: {
per_hour: player.x,
preserver: "No",
stored: 0,
},
foraging: {
per_hour: player.y,
boat: "No",
stored: 0,
},
hours: 16,
days: 0,
};
function updateTable() {
document.getElementById("fish_p_hour").innerText = gamedata.fishing.per_hour;
document.getElementById("wood_p_hour").innerText = gamedata.foraging.per_hour;
document.getElementById("fish_stored").innerText = gamedata.fishing.stored;
document.getElementById("wood_stored").innerText = gamedata.foraging.stored;
document.getElementById("preserver").innerText = gamedata.fishing.preserver;
document.getElementById("boat").innerText = gamedata.foraging.boat;
document.getElementById("hours").innerText = gamedata.hours;
document.getElementById("days").innerText = gamedata.days;
if (gamedata.hours < 8) {
document.getElementById("improve-fishing").disabled = true;
} else {
document.getElementById("improve-fishing").disabled = false;
}
if (gamedata.hours < 8) {
document.getElementById("improve-forgaing").disabled = true;
} else {
document.getElementById("improve-forgaing").disabled = false;
}
if (gamedata.foraging.stored < 25 || gamedata.hours < 8) {
document.getElementById("build-preserver").disabled = true;
} else {
document.getElementById("build-preserver").disabled = false;
}
if (gamedata.foraging.stored < 100 || gamedata.hours < 16) {
document.getElementById("build-boat").disabled = true;
} else {
document.getElementById("build-boat").disabled = false;
}
}
function go_fishing() {
let prompt = window.prompt("How many hours do you want to fish?");
if (prompt === null || prompt > gamedata.hours) {
window.alert("You dont have the hours for this or prompt exited");
console.log("Prompt Exited");
} else {
gamedata.fishing.stored += prompt * gamedata.fishing.per_hour;
gamedata.hours -= prompt;
if (gamedata.hours === 0) {
gamedata.days++;
gamedata.hours = 16;
}
updateTable();
}
}
function go_foraging() {
let prompt = window.prompt("How many hours do you want to foraging?");
if (prompt === null || prompt > gamedata.hours) {
window.alert("You dont have the hours for this or prompt exited");
console.log("Prompt Exited");
} else {
gamedata.foraging.stored += prompt * gamedata.foraging.per_hour;
gamedata.hours -= prompt;
if (gamedata.hours === 0) {
gamedata.days++;
gamedata.hours = 16;
}
updateTable();
}
}
document.getElementById("go-fishing").onclick = go_fishing;
document.getElementById("go-foraging").onclick = go_foraging;
updateTable();
+8
View File
@@ -0,0 +1,8 @@
const server = Bun.serve({
port: 3000,
routes: {
"/": () => new Response("Bun!"),
},
});
console.log(`Listening on ${server.url}`);
+12
View File
@@ -0,0 +1,12 @@
{
"name": "escape",
"module": "index.ts",
"type": "module",
"private": true,
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^7"
}
}
+167
View File
@@ -0,0 +1,167 @@
html {
background-color: moccasin;
height: 100%;
}
body {
background-color: cadetblue;
transition: background-color 0.1s ease-out;
margin: 20px;
padding: 0;
font-family: "Almendra";
}
header {
background-color: moccasin;
padding: 10px;
border-bottom: 2px dashed gray;
.header-container {
display: flex;
flex-direction: row-reverse;
align-items: center;
h1 {
color: cornflowerblue;
font-family: "Almendra";
text-align: left;
font-size: clamp(20px, 10vh, 55px);
height: auto;
max-height: 100px;
flex: 1;
}
.boat {
height: auto;
max-width: 150px;
width: 100%;
pointer-events: none;
display: block;
}
.boat-container {
display: flex;
justify-content: left;
align-items: left;
width: 100%;
flex: 2;
}
}
}
.Content {
margin-left: 10px;
margin-right: 10px;
.Instruction {
display: flex;
align-items: baseline;
gap: 10px;
details {
p {
line-height: 1.4;
font-size: 20px;
color: black;
}
}
p {
font-size: 40px;
text-align: left;
line-height: 1;
margin-top: 5px;
margin-bottom: 5px;
}
li {
line-height: 1.4;
font-size: 20px;
color: black;
}
}
.game {
display: flex;
width: 100%;
gap: 10px;
.table-container {
padding: 10px;
flex: 1;
background-color: cadetblue;
table,
th,
td,
tr {
border: 1px solid black;
}
tr:nth-child(even) {
background-color: rgba(0, 0, 0, 0.2);
}
tr:nth-child(odd) {
background-color: rgba(0, 0, 0, 0.125);
}
table {
border-collapse: collapse;
width: 100%;
}
th,
td {
padding: 10px;
text-align: center;
}
th {
background-color: darkseagreen;
}
}
.button-container {
flex: 1;
padding: 10px;
.button-container-part {
display: flex;
button {
font-family: "Almendra";
font-size: 18px;
width: 100%;
text-align: center;
transition-duration: 0.2s;
padding: 7px;
height: clamp(30px, 15vh, 85px);
}
button:hover {
background-color: darkseagreen;
color: black;
cursor: grab;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.6);
border: 2px solid black;
}
button:disabled {
pointer-events: none;
}
}
}
}
}
footer {
background-color: moccasin;
width: 100%;
margin-top: 25px;
text-align: center;
border-top: 2px dashed gray;
}
+30
View File
@@ -0,0 +1,30 @@
{
"compilerOptions": {
// Environment setup & latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
"types": ["bun"],
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}