Add files via upload

This commit is contained in:
James 2025-04-30 14:50:27 -07:00 committed by GitHub
parent 1fa2e66f34
commit 96ebb2c8e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 283 additions and 11 deletions

BIN
img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -18,7 +18,8 @@
<nav>
<a href="index.html">Home</a> |
<a href="servermanager.html">Server Manager</a> |
<a href="shardwalker.html">Shardwalker</a>
<a href="shardwalker.html">Shardwalker</a> |
<a href="indie_game_roadmap.html">Indie Game Roadmap</a>
</nav>
<header>
<h1>Obli.Studios</h1>

183
indie_game_roadmap.html Normal file
View File

@ -0,0 +1,183 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Indie Game Roadmap</title>
<style>
body {
font-family: 'Segoe UI', sans-serif;
background-color: #121212;
color: #ffffff;
margin: 0;
padding: 2rem;
}
h1, h2 {
color: #00bfff;
text-align: center;
}
.timeline {
display: flex;
flex-direction: column;
gap: 1.5rem;
max-width: 1000px;
margin: auto;
}
.phase {
background-color: #1f1f1f;
padding: 1rem 1.5rem;
border-left: 5px solid #00bfff;
border-radius: 6px;
box-shadow: 0 0 8px rgba(0, 191, 255, 0.2);
position: relative;
}
.phase h3 {
margin: 0;
font-size: 1.2rem;
color: #00e0ff;
}
.dates {
font-size: 0.9rem;
color: #aaaaaa;
margin-bottom: 0.5rem;
}
.description {
font-size: 1rem;
color: #dddddd;
}
.status {
font-size: 0.8rem;
padding: 2px 6px;
border-radius: 4px;
margin-left: 10px;
text-transform: uppercase;
}
.status.done {
background: #28a745;
color: #fff;
}
.status.progress {
background: #ffc107;
color: #000;
}
.status.not-started {
background: #dc3545;
color: #fff;
}
.toggle {
position: absolute;
top: 1rem;
right: 1rem;
font-size: 0.9rem;
cursor: pointer;
background-color: #2d2d2d;
color: #ffffff;
border: none;
padding: 0.3rem 0.6rem;
border-radius: 4px;
}
</style>
<script>
async function login() {
const password = document.getElementById('password').value;
const res = await fetch('/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ password })
});
const result = await res.json();
if (result.success) {
document.getElementById('login-status').textContent = '✅ Logged in';
document.getElementById('login-form').style.display = 'none';
loadRoadmap();
} else {
document.getElementById('login-status').textContent = '❌ Incorrect password';
}
}
async function loadRoadmap() {
const res = await fetch('/api/roadmap');
const data = await res.json();
const container = document.getElementById('roadmap');
container.innerHTML = '';
data.forEach(phase => {
const el = document.createElement('div');
el.className = 'phase';
el.innerHTML = `
<strong>${phase.title}</strong>
<span class="status">[${phase.status}]</span>
<select onchange="updateStatus(${phase.id}, this.value)">
<option value="not started" ${phase.status === 'not started' ? 'selected' : ''}>Not Started</option>
<option value="in progress" ${phase.status === 'in progress' ? 'selected' : ''}>In Progress</option>
<option value="done" ${phase.status === 'done' ? 'selected' : ''}>Done</option>
</select>
`;
container.appendChild(el);
});
}
async function updateStatus(id, newStatus) {
await fetch('/api/roadmap', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id, status: newStatus })
});
loadRoadmap();
}
// Auto-login check
fetch('/check-auth')
.then(res => res.json())
.then(data => {
if (data.authenticated) {
document.getElementById('login-form').style.display = 'none';
loadRoadmap();
}
});
</script>
</head>
<body>
<nav class="navbar">
<a href="index.html">Home</a> |
<a href="servermanager.html">Server Manager</a> |
<a href="shardwalker.html">Shardwalker</a> |
<a href="indie_game_roadmap.html">Indie Game Roadmap</a>
</nav>
<h1>Shardwalker: The Mirror's Edge</h1>
<div id="login-panel" style="text-align:center; margin-bottom:2rem;">
<input type="password" id="admin-pass" placeholder="Enter admin password" />
<button onclick="login()">Login</button>
<p id="login-status" style="color:#00bfff;"></p>
</div>
<h2>Indie Dev Production Roadmap</h2>
<div class="timeline" id="roadmap">
<div class="phase"><h3>Pre-Production <span class="status done">Done</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">Start: [Today] — End: +30 Days</div><div class="description">Design docs, game concept, visual target, core loop</div></div>
<div class="phase"><h3>Blockout Maps & Prototypes <span class="status progress">In Progress</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+31 Days — +75 Days</div><div class="description">Build test maps, whitebox environments, establish movement/combat feel</div></div>
<div class="phase"><h3>Core Mechanics Development <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+76 Days — +135 Days</div><div class="description">Implement combat, shard-switching, attunement system</div></div>
<div class="phase"><h3>First Playable (Vertical Slice) <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+136 Days — +165 Days</div><div class="description">Basic UI, combat, single map, testable state</div></div>
<div class="phase"><h3>Story & World Design <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+166 Days — +210 Days</div><div class="description">Write lore, quests, dialogue, map flow</div></div>
<div class="phase"><h3>Environment Art & Level Design <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+211 Days — +285 Days</div><div class="description">Model, texture, and populate maps</div></div>
<div class="phase"><h3>Multiplayer Networking Setup <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+286 Days — +330 Days</div><div class="description">Mirror or FishNet implementation, lobby & match start logic</div></div>
<div class="phase"><h3>UI/UX Polish <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+331 Days — +360 Days</div><div class="description">Final HUD, menus, pause screens</div></div>
<div class="phase"><h3>Sound, Music & VFX <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+361 Days — +390 Days</div><div class="description">Placeholders replaced with final effects, transitions</div></div>
<div class="phase"><h3>Beta Playtesting <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+391 Days — +420 Days</div><div class="description">Gather feedback on PvP and solo campaign</div></div>
<div class="phase"><h3>Final Polish & Optimization <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+421 Days — +450 Days</div><div class="description">Bug fixing, performance, controller support</div></div>
<div class="phase"><h3>Marketing & Steam Page Prep <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+451 Days — +471 Days</div><div class="description">Trailer, screenshots, copywriting</div></div>
<div class="phase"><h3>Launch <span class="status not-started">Not Started</span><button class="toggle" onclick="toggleStatus(this)">Toggle</button></h3><div class="dates">+472 Days — +479 Days</div><div class="description">Push to Steam, promote, manage release</div></div>
</div>
</body>
</html>

15
roadmap.json Normal file
View File

@ -0,0 +1,15 @@
[
{ "id": 1, "title": "Pre-Production", "status": "done" },
{ "id": 2, "title": "Blockout Maps & Prototypes", "status": "in progress" },
{ "id": 3, "title": "Core Mechanics Development", "status": "not started" },
{ "id": 4, "title": "First Playable (Vertical Slice)", "status": "not started" },
{ "id": 5, "title": "Story & World Design", "status": "not started" },
{ "id": 6, "title": "Environment Art & Level Design", "status": "not started" },
{ "id": 7, "title": "Multiplayer Networking Setup", "status": "not started" },
{ "id": 8, "title": "UI/UX Polish", "status": "not started" },
{ "id": 9, "title": "Sound, Music & VFX", "status": "not started" },
{ "id": 10, "title": "Beta Playtesting", "status": "not started" },
{ "id": 11, "title": "Final Polish & Optimization", "status": "not started" },
{ "id": 12, "title": "Marketing & Steam Page Prep", "status": "not started" },
{ "id": 13, "title": "Launch", "status": "not started" }
]

68
server.js Normal file
View File

@ -0,0 +1,68 @@
// server.js (Node.js + Express backend)
const express = require('express');
const fs = require('fs');
const path = require('path');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const jwt = require('jsonwebtoken');
const app = express();
const SECRET_KEY = 'your_super_secret_key';
const PASSWORD = 'shardwalker2025'; // set your password here
const PORT = 3000;
app.use(express.static('public'));
app.use(bodyParser.json());
app.use(cookieParser());
// Serve login check
app.get('/check-auth', (req, res) => {
const token = req.cookies.token;
if (!token) return res.status(401).json({ authenticated: false });
try {
jwt.verify(token, SECRET_KEY);
res.json({ authenticated: true });
} catch (err) {
res.status(403).json({ authenticated: false });
}
});
// Login route
app.post('/login', (req, res) => {
const { password } = req.body;
if (password === PASSWORD) {
const token = jwt.sign({ user: 'admin' }, SECRET_KEY, { expiresIn: '1d' });
res.cookie('token', token, { httpOnly: true });
res.json({ success: true });
} else {
res.status(403).json({ success: false });
}
});
// Get current roadmap
app.get('/api/roadmap', (req, res) => {
const data = fs.readFileSync(path.join(__dirname, 'roadmap.json'));
res.json(JSON.parse(data));
});
// Update roadmap status
app.post('/api/roadmap', (req, res) => {
const token = req.cookies.token;
if (!token || !jwt.verify(token, SECRET_KEY)) {
return res.status(403).json({ success: false });
}
const { id, status } = req.body;
const filePath = path.join(__dirname, 'roadmap.json');
const roadmap = JSON.parse(fs.readFileSync(filePath));
const phase = roadmap.find(p => p.id === id);
if (phase) {
phase.status = status;
fs.writeFileSync(filePath, JSON.stringify(roadmap, null, 2));
res.json({ success: true });
} else {
res.status(404).json({ success: false });
}
});
app.listen(PORT, () => console.log(`Server running at http://localhost:${PORT}`));

View File

@ -11,7 +11,8 @@
<nav class="navbar">
<a href="index.html">Home</a> |
<a href="servermanager.html">Server Manager</a> |
<a href="shardwalker.html">Shardwalker</a>
<a href="shardwalker.html">Shardwalker</a> |
<a href="indie_game_roadmap.html">Indie Game Roadmap</a>
</nav>
<div class="container">

View File

@ -1,17 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shardwalker: The Mirror's Edge</title>
<link rel="stylesheet" href="shardwalkerMain.css">
<meta charset="UTF-8">
<title>Shardwalker: The Mirror's Edge</title>
<link rel="stylesheet" href="shardwalkerMain.css">
</head>
<body>
<nav class="navbar">
<a href="index.html">Home</a> |
<a href="servermanager.html">Server Manager</a> |
<a href="shardwalker.html">Shardwalker</a>
</nav>
<nav class="navbar">
<a href="index.html">Home</a> |
<a href="servermanager.html">Server Manager</a> |
<a href="shardwalker.html">Shardwalker</a> |
<a href="indie_game_roadmap.html">Indie Game Roadmap</a>
</nav>
<div class="container">
<header>