Developer b070bab2e3 Initial commit: Western Shooter - Complete implementation
Retro western vertical shooter inspired by Gun.Smoke, built with
TypeScript and WebGL2. Features 3-direction shooting, vertical
scrolling, economy/shop loop, boss fights, and CRT shader effects.

Phases implemented:
- Phase 1: Engine skeleton (WebGL2 renderer, fixed timestep loop, input)
- Phase 2: Shooting identity (3-dir shooting, bullet pools, collision)
- Phase 3: Enemies & patterns (JSON waves, 4 enemy types, parallax bg)
- Phase 4: Economy loop (pickups, shop, upgrades, HUD)
- Phase 5: Boss system (3 bosses, wanted posters, multi-phase attacks)
- Phase 6: Shader layer (CRT effects, bloom, scanlines, screen shake)
- Phase 7: Performance (VAO batching, O(1) allocation, stress testing)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 19:28:35 -06:00

86 lines
2.0 KiB
TypeScript

import path from 'path';
// Build the TypeScript bundle
async function buildBundle() {
const result = await Bun.build({
entrypoints: ['./src/main.ts'],
outdir: './dist',
target: 'browser',
format: 'esm',
sourcemap: 'inline',
minify: false,
});
if (!result.success) {
console.error('Build failed:');
for (const log of result.logs) {
console.error(log);
}
throw new Error('Build failed');
}
console.log('Bundle built successfully');
return result;
}
// Initial build
await buildBundle();
const server = Bun.serve({
port: 3000,
hostname: '0.0.0.0', // Bind to all interfaces
async fetch(req) {
const url = new URL(req.url);
let filePath = url.pathname;
// Default to index.html
if (filePath === '/') {
filePath = '/index.html';
}
// Redirect main.ts to bundled version
if (filePath === '/src/main.ts') {
filePath = '/dist/main.js';
}
// Determine content type
const ext = filePath.split('.').pop() || '';
const contentTypes: Record<string, string> = {
html: 'text/html',
js: 'application/javascript',
mjs: 'application/javascript',
css: 'text/css',
json: 'application/json',
png: 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
svg: 'image/svg+xml',
};
const contentType = contentTypes[ext] || 'application/octet-stream';
try {
const file = Bun.file(`.${filePath}`);
const exists = await file.exists();
if (!exists) {
console.log(`404: ${filePath}`);
return new Response('Not Found', { status: 404 });
}
return new Response(file, {
headers: {
'Content-Type': contentType,
'Cache-Control': 'no-cache',
},
});
} catch (error) {
console.error('Server error:', error);
return new Response('Internal Server Error', { status: 500 });
}
},
});
console.log(`Server running at http://0.0.0.0:${server.port}`);
console.log(`Access locally: http://localhost:${server.port}`);