Add ink integration UI and media playback

This commit is contained in:
2026-05-15 21:23:46 +02:00
parent 44dc64f830
commit f2e786d5bc
89 changed files with 6561 additions and 556 deletions
+26 -10
View File
@@ -47,6 +47,7 @@ const http_1 = __importDefault(require("http"));
const socket_io_1 = require("socket.io");
const dotenv = __importStar(require("dotenv"));
const fs_1 = require("fs");
const turn_result_1 = require("./interfaces/turn-result");
// Load environment variables
dotenv.config();
// Create Express application
@@ -59,7 +60,7 @@ exports.io = io;
// Get port from environment variables or use default
const DEFAULT_PORT = 3001;
const PORT = process.env.PORT ? parseInt(process.env.PORT) : DEFAULT_PORT;
const PORT_RANGE = 10; // Try up to 10 ports starting from the default
const PORT_RANGE = 300; // Try enough ports to skip OS-excluded ranges.
// Serve static files from the public directory. Keep browser modules uncached
// during local development so fixes are visible without a hard cache clear.
app.use(express_1.default.static(path_1.default.join(__dirname, '../public'), {
@@ -82,14 +83,23 @@ io.on('connection', (socket) => {
console.log(`New client connected: ${socket.id}`);
let currentParagraphIndex = 0;
let gameRunning = false;
let nextTurnId = 1;
const saveGames = new Set();
const startDemoGame = () => {
gameRunning = true;
nextTurnId = 1;
currentParagraphIndex = 0;
socket.emit('gameIntroduction', {
introduction: "::chapter[Interactive Fiction Test]\n\nWelcome to the Interactive Fiction Test. This is a simplified version that sends predefined paragraphs instead of using an LLM.",
initialRoomDescription: TEST_PARAGRAPHS[0],
currentRoomId: "test-room"
socket.emit('narrativeResponse', {
turnId: nextTurnId++,
paragraphs: [
...(0, turn_result_1.textToParagraphs)("#chapter[Interactive Fiction Test]\n\nWelcome to the Interactive Fiction Test. This is a simplified version that sends predefined paragraphs instead of using an LLM."),
...(0, turn_result_1.textToParagraphs)(TEST_PARAGRAPHS[0]),
],
choices: [],
inputMode: 'text',
gameState: {
currentRoomId: 'test-room',
},
});
};
const normalizeSaveSlot = (slot) => {
@@ -174,7 +184,10 @@ io.on('connection', (socket) => {
console.log(`Received command: ${data.command}`);
// Send narrative response to client
socket.emit('narrativeResponse', {
text: data.command,
turnId: nextTurnId++,
paragraphs: (0, turn_result_1.textToParagraphs)(String(data.command || '')),
choices: [],
inputMode: 'text',
gameState: {
currentRoomId: "test-room"
},
@@ -235,15 +248,17 @@ async function startServer(initialPort, range) {
}
// Try to start the server on the current port
await new Promise((resolve, reject) => {
server.listen(currentPort, () => {
server.removeAllListeners('error');
server.removeAllListeners('listening');
server.once('listening', () => {
console.log(`AI Interactive Fiction TEST SERVER running on http://localhost:${currentPort}`);
console.log('This server is sending predefined test paragraphs instead of using an LLM');
resolve();
});
server.on('error', (error) => {
server.once('error', (error) => {
// If port is in use, try next port
if (error.code === 'EADDRINUSE') {
console.log(`Port ${currentPort} is in use, trying next port...`);
if (error.code === 'EADDRINUSE' || error.code === 'EACCES') {
console.log(`Port ${currentPort} is unavailable (${error.code}), trying next port...`);
server.close();
currentPort++;
reject();
@@ -254,6 +269,7 @@ async function startServer(initialPort, range) {
reject(error);
}
});
server.listen(currentPort);
});
// If we reach here, server started successfully
return;