Updates rules to be closer to original Y.A.R.N
This commit is contained in:
parent
a65607b054
commit
f1e9470710
|
|
@ -477,7 +477,10 @@
|
|||
hasSubmitted = false;
|
||||
hasVoted = false;
|
||||
updateUI();
|
||||
appendSystemMessage('New round started!');
|
||||
appendSystemMessage(`Round ${gameState.currentRound} started!`);
|
||||
if (gameState.currentRound === gameState.gameSettings.roundLimit) {
|
||||
appendSystemMessage(`It's the final round. Points count double!`);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('gameOver', (data) => {
|
||||
|
|
@ -553,9 +556,13 @@
|
|||
case 'lobby':
|
||||
if (isHost) {
|
||||
gameBar.innerHTML = `
|
||||
<div class="setting-group">
|
||||
<label>Round Limit:</label>
|
||||
<input type="number" id="round-limit" value="${gameState.gameSettings.roundLimit}" min="3" max="100">
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<label>Score Limit:</label>
|
||||
<input type="number" id="score-limit" value="${gameState.gameSettings.scoreLimit}" min="10" max="100">
|
||||
<input type="number" id="score-limit" value="${gameState.gameSettings.scoreLimit}" min="0" max="100">
|
||||
</div>
|
||||
<div class="setting-group">
|
||||
<label>Time per Round (sec):</label>
|
||||
|
|
@ -576,8 +583,6 @@
|
|||
} else {
|
||||
gameBar.innerHTML = `
|
||||
<span class="waiting-message">Waiting for host to start the game...</span>
|
||||
<span>Score Limit: ${gameState.gameSettings.scoreLimit}</span>
|
||||
<span>Time Limit: ${gameState.gameSettings.timeLimit}s</span>
|
||||
`;
|
||||
}
|
||||
break;
|
||||
|
|
@ -755,12 +760,14 @@
|
|||
|
||||
function startGame() {
|
||||
const scoreLimit = parseInt(document.getElementById('score-limit').value) || 100;
|
||||
const roundLimit = parseInt(document.getElementById('round-limit').value) || 15;
|
||||
const timeLimit = parseInt(document.getElementById('time-limit').value) || 60;
|
||||
const botCount = parseInt(document.getElementById('bot-count').value) || 0;
|
||||
const startText = document.getElementById('start-text').value;
|
||||
|
||||
socket.emit('startGame', {
|
||||
scoreLimit: Math.max(10, Math.min(9999, scoreLimit)),
|
||||
scoreLimit: Math.max(0, Math.min(9999, scoreLimit)),
|
||||
roundLimit: Math.max(0, Math.min(100, roundLimit)),
|
||||
timeLimit: Math.max(15, Math.min(600, timeLimit)),
|
||||
botCount: Math.max(0, Math.min(5, botCount)),
|
||||
startText
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta property="og:title" content="Y.A.R.N HTML5" />
|
||||
<meta property="og:description" content="A collaborative story-writing game. Remake of the 2000s GameSpy Arcade classic." />
|
||||
<title>Y.A.R.N. 2026</title>
|
||||
<title>Y.A.R.N. HTML5</title>
|
||||
|
||||
<!-- re-use the same CSS-variables and base look -->
|
||||
<style>
|
||||
|
|
@ -134,7 +134,8 @@
|
|||
<ul>
|
||||
<li>Players have a limited amount of time to write a sentence, selected by the host at game start.</li>
|
||||
<li>Once all players have submitted their sentences, players have 30 seconds to vote for their favorite.</li>
|
||||
<li>The player whose sentence is chosen receives 5 points, plus one point for each vote they received.</li>
|
||||
<li>The player whose sentence is chosen receives 3 bonus points, and all players receive one point for each vote they received.</li>
|
||||
<li>In the case of a tie, the longest sentence receives two extra points and the other sentences tied receive 1 point each.</li>
|
||||
<li>When a player reaches the point limit, they win the game.</li>
|
||||
</ul>
|
||||
<p>Enjoy the story-writing!<br><br>
|
||||
|
|
|
|||
42
server.js
42
server.js
|
|
@ -25,7 +25,8 @@ class YarnGame {
|
|||
this.inProgress = false;
|
||||
this.gameHost = null;
|
||||
this.gameSettings = {
|
||||
scoreLimit: 50,
|
||||
scoreLimit: 0,
|
||||
roundLimit: 15,
|
||||
timeLimit: 60,
|
||||
botCount: 0,
|
||||
startText: "It was a dark and stormy night..."
|
||||
|
|
@ -36,6 +37,7 @@ class YarnGame {
|
|||
this.yarnStory = []; // { player: "", str: "" }
|
||||
this.chat = []; // { id, name, msg }
|
||||
this.round_data = []; // { entry_text, player_id, votes: [] }
|
||||
this.roundCount = 0; // current round
|
||||
this.currentPhase = 'lobby'; // lobby, writing, voting, gameOver
|
||||
this.timer = null;
|
||||
this.timeRemaining = 0;
|
||||
|
|
@ -133,6 +135,7 @@ class YarnGame {
|
|||
|
||||
async startGame(settings) {
|
||||
this.gameSettings = { ...this.gameSettings, ...settings };
|
||||
this.roundCount = 0;
|
||||
this.startBots(this.gameSettings.botCount);
|
||||
this.inProgress = true;
|
||||
this.yarnStory = [{ player: "Narrator", str: this.gameSettings.startText }];
|
||||
|
|
@ -142,9 +145,13 @@ class YarnGame {
|
|||
|
||||
async processBotWriting() {
|
||||
for (const botObj of this.bots) {
|
||||
try {
|
||||
const botText = await botObj.bot.Write(this.getStoryText());
|
||||
console.log(`Bot text: ${botText}`)
|
||||
this.submitEntry(botObj.bot_id, botText)
|
||||
console.log(`Bot text: ${botText}`);
|
||||
this.submitEntry(botObj.bot_id, botText);
|
||||
} catch (err) {
|
||||
console.warn(`Bot ${botObj.bot_id} failed to write:`, err.message || err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -180,8 +187,13 @@ class YarnGame {
|
|||
|
||||
async processBotVoting() {
|
||||
for (const botObj of this.bots) {
|
||||
try {
|
||||
const botVote = await botObj.bot.Vote(this.getStoryText(), this.round_data);
|
||||
this.submitVote(botObj.bot_id, botVote)
|
||||
this.submitVote(botObj.bot_id, botVote);
|
||||
} catch (err) {
|
||||
// One bot failing to vote is not critical; keep going
|
||||
console.warn(`Bot ${botObj.bot_id} failed to vote:`, err.message || err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,15 +269,26 @@ class YarnGame {
|
|||
});
|
||||
}
|
||||
|
||||
this.roundCount++; // increment round counter
|
||||
return leaders.length === 1 ? leaders[0] : null; // return single winner or null on tie
|
||||
}
|
||||
|
||||
checkGameOver() {
|
||||
const winner = this.players.find(p => p.score >= this.gameSettings.scoreLimit);
|
||||
if (winner) {
|
||||
this.currentPhase = 'gameOver';
|
||||
this.inProgress = false;
|
||||
return winner;
|
||||
// score limit win
|
||||
if (this.gameSettings.scoreLimit) {
|
||||
const scoreWinner = this.players.find(p => p.score >= this.gameSettings.scoreLimit);
|
||||
if (scoreWinner) return scoreWinner;
|
||||
}
|
||||
// round limit win
|
||||
if (this.roundCount >= this.gameSettings.roundLimit && this.gameSettings.roundLimit != 0) {
|
||||
return this.players.reduce(
|
||||
(best, p) => (p.score > best.score ? p : best),
|
||||
this.players[0]
|
||||
);
|
||||
}
|
||||
// if we're one before the round limit, append to the story
|
||||
if (this.roundCount == this.gameSettings.roundLimit-1) {
|
||||
this.yarnStory.push({ player: "Narrator", str: "The moral of this story: " });
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -345,6 +368,7 @@ class YarnGame {
|
|||
})),
|
||||
yarnStory: this.yarnStory,
|
||||
currentPhase: this.currentPhase,
|
||||
currentRound: this.roundCount+1,
|
||||
timeRemaining: this.timeRemaining,
|
||||
round_data: this.currentPhase === 'voting' ? this.round_data.map((e, i) => ({
|
||||
index: i,
|
||||
|
|
|
|||
Loading…
Reference in New Issue