Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 62 additions & 16 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Box Game</title>
<meta name="description"
content="Jump, collect hearts, and beat your friends in Box Game – a fast-paced multiplayer platformer." />
<link rel="shortcut icon" href="icon.png" type="image" />
<link rel="stylesheet" href="styles.css" />
</head>
Expand All @@ -13,28 +15,72 @@

<!-- ===== LOBBY SCREEN ===== -->
<div id="nameScreen">
<div class="nameBox" id="lobbyBox">
<h2>Box Game</h2>
<p>Jump, collect hearts, beat your friends.</p>
<div class="landing-container">

<label class="field-label">Your Name</label>
<input type="text" id="nameInput" placeholder="Enter your name…" maxlength="15" autofocus />
<section class="hero">

<div class="divider"><span>choose a room</span></div>
<span class="hero-tag">MULTIPLAYER PLATFORMER</span>

<!-- Create Room -->
<button id="createRoomBtn" class="btn-primary">✦ Create Private Room</button>
<h1>BOX GAME</h1>

<p class="hero-description">
Jump across platforms, collect points, compete with your friends,
and top the leaderboard.
</p>

<!-- <div class="hero-features"> -->
<!-- <div class="feature"> -->
<!-- <span>⚡</span> -->
<!-- <p>Low Latency</p> -->
<!-- </div> -->
<!---->
<!-- <div class="feature"> -->
<!-- <span>❤</span> -->
<!-- <p>Collect Hearts</p> -->
<!-- </div> -->
<!---->
<!-- <div class="feature"> -->
<!-- <span>👥</span> -->
<!-- <p>Private Rooms</p> -->
<!-- </div> -->
<!-- </div> -->

</section>

<div class="nameBox" id="lobbyBox">

<h2>Play Now</h2>

<p>Enter your name and join a room.</p>

<label class="field-label">Player Name</label>

<input type="text" id="nameInput" maxlength="15" placeholder="Player name">

<button id="createRoomBtn" class="btn-primary">
Create Private Room
</button>

<div class="divider">
<span>OR</span>
</div>

<div class="join-row">

<input id="roomCodeInput" maxlength="5" placeholder="ABCDE">

<button id="joinRoomBtn" class="btn-secondary">
Join
</button>

</div>

<p id="lobbyError" class="error-msg"></p>

<!-- Join Room -->
<div class="join-row">
<input type="text" id="roomCodeInput" placeholder="Room code…" maxlength="5" />
<button id="joinRoomBtn" class="btn-secondary">Join</button>
</div>

<p id="lobbyError" class="error-msg"></p>
</div>
</div>

<!-- ===== IN-GAME HUD ===== -->
<div id="hud" style="display:none;">
<button id="menuBtn" title="Options">☰</button>
Expand Down Expand Up @@ -63,9 +109,9 @@ <h3>Options</h3>
<script src="https://cdn.socket.io/4.8.3/socket.io.min.js"
integrity="sha384-kzavj5fiMwLKzzD1f8S7TeoVIEi7uKHvbTA3ueZkrzYq75pNQUiUi6Dy98Q3fxb0"
crossorigin="anonymous"></script>
<!-- ⬇ Change this URL when deploying to Vercel (point to your VM's gateway) -->
<!-- Gateway URL: set to production gateway for Vercel deployment -->
<script>
window.GATEWAY_URL = "http://localhost:8080";
window.GATEWAY_URL = "https://gateway.boxgame.shadyggs.xyz";
</script>
<script src="index.js"></script>
<script src="game.js"></script>
Expand Down
42 changes: 22 additions & 20 deletions client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@
// GATEWAY_URL is injected by index.html as a <script> block so it works
// both locally and on Vercel without a bundler.
// Locally: window.GATEWAY_URL = "http://localhost:3000"
// Vercel: window.GATEWAY_URL = "https://<your-vm-ip-or-domain>"
const GATEWAY_URL = window.GATEWAY_URL || "http://localhost:3000";
// Vercel: window.GATEWAY_URL = "https://gateway.boxgame.shadyggs.xyz"
const GATEWAY_URL = window.GATEWAY_URL;

// In production the game-server domain is server.boxgame.shadyggs.xyz.
// Nginx terminates TLS for wss://server.boxgame.shadyggs.xyz:<port> and
// forwards to the hostNetwork pod on the same port.
// In local dev the cookie will contain "localhost" so http:// is used.
const isLocalDev = GATEWAY_URL.startsWith("http://");
const WS_SCHEME = isLocalDev ? "http" : "wss";
Comment on lines +6 to +13

// socket is created lazily after a room is assigned so we know which
// game-server host+port to connect to.
Expand Down Expand Up @@ -52,29 +59,24 @@ createRoomBtn.addEventListener("click", async () => {
try {
// Gateway picks the least-loaded game server, sets cookies
// (hostIp, port, roomID) and returns.
const res = await fetch(`${GATEWAY_URL}/createRoom`, {
credentials: "include", // receive the Set-Cookie headers
});

const res = await fetch(`${GATEWAY_URL}/createRoom`);
if (!res.ok) {
showLobbyError("No game servers available. Try again.");
setLobbyLoading(false);
return;
}

// Read the cookies the gateway just set
const hostIp = getCookie("hostIp");
const port = getCookie("port");
const roomID = getCookie("roomID");

console.log("Logging res:");
console.log(res);
console.log("Logging hostIp and port");
const { hostIp, port, roomID } = await res.json();
console.log(`hostIp: ${hostIp}, port: ${port}`);
if (!hostIp || !port || !roomID) {
showLobbyError("Server response missing. Try again.");
setLobbyLoading(false);
return;
}

// Connect socket directly to the assigned game-server
connectSocket(`http://${hostIp}:${port}`, () => {
// Connect socket directly to the assigned game-server via TLS in prod
connectSocket(`${WS_SCHEME}://${hostIp}:${port}`, () => {
socket.emit("createRoom", pName, roomID, (ack) => {
setLobbyLoading(false);
if (ack && ack.success) {
Expand Down Expand Up @@ -118,17 +120,17 @@ joinRoomBtn.addEventListener("click", async () => {
return;
}

const hostIp = getCookie("hostIp");
const port = getCookie("port");
const { hostIp, port, roomID } = await res.json();
console.log(hostIp);

if (!hostIp || !port) {
if (!hostIp || !port || !roomID) {
showLobbyError("Could not locate room server.");
setLobbyLoading(false);
return;
}

connectSocket(`http://${hostIp}:${port}`, () => {
socket.emit("joinRoom", { name: pName, code }, (ack) => {
connectSocket(`${WS_SCHEME}://${hostIp}:${port}`, () => {
socket.emit("joinRoom", { name: pName, roomID }, (ack) => {
setLobbyLoading(false);
Comment on lines +132 to 134
if (ack && ack.success) {
enterGame(ack.code);
Expand Down
Loading