diff --git a/packages/webapp/src/app/globals.css b/packages/webapp/src/app/globals.css index f4bd77c0..583993b8 100644 --- a/packages/webapp/src/app/globals.css +++ b/packages/webapp/src/app/globals.css @@ -85,23 +85,7 @@ body { overflow-x: hidden; } -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} - a { color: inherit; text-decoration: none; } - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } -} diff --git a/packages/webapp/src/app/page.module.css b/packages/webapp/src/app/page.module.css deleted file mode 100644 index 5c4b1e6a..00000000 --- a/packages/webapp/src/app/page.module.css +++ /dev/null @@ -1,230 +0,0 @@ -.main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - min-height: 100vh; -} - -.description { - display: inherit; - justify-content: inherit; - align-items: inherit; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); -} - -.description a { - display: flex; - justify-content: center; - align-items: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.grid { - display: grid; - grid-template-columns: repeat(4, minmax(25%, auto)); - max-width: 100%; - width: var(--max-width); -} - -.card { - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-bottom: 0.7rem; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - max-width: 30ch; - text-wrap: balance; -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - padding: 4rem 0; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; -} - -.center::after { - background: var(--primary-glow); - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ""; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; -} -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -@media (prefers-reduced-motion) { - .card:hover span { - transform: none; - } -} - -/* Mobile */ -@media (max-width: 700px) { - .content { - padding: 4rem; - } - - .grid { - grid-template-columns: 1fr; - margin-bottom: 120px; - max-width: 320px; - text-align: center; - } - - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } - - .center { - padding: 8rem 0 6rem; - } - - .center::before { - transform: none; - height: 300px; - } - - .description { - font-size: 0.8rem; - } - - .description a { - padding: 1rem; - } - - .description p, - .description div { - display: flex; - justify-content: center; - position: fixed; - width: 100%; - } - - .description p { - align-items: center; - inset: 0 0 auto; - padding: 2rem 1rem 1.4rem; - border-radius: 0; - border: none; - border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); - background: linear-gradient( - to bottom, - rgba(var(--background-start-rgb), 1), - rgba(var(--callout-rgb), 0.5) - ); - background-clip: padding-box; - backdrop-filter: blur(24px); - } - - .description div { - align-items: flex-end; - pointer-events: none; - inset: auto 0 0; - padding: 2rem; - height: 200px; - background: linear-gradient( - to bottom, - transparent 0%, - rgb(var(--background-end-rgb)) 40% - ); - z-index: 1; - } -} - -/* Tablet and Smaller Desktop */ -@media (min-width: 701px) and (max-width: 1120px) { - .grid { - grid-template-columns: repeat(2, 50%); - } -} - -@media (prefers-color-scheme: dark) { - .vercelLogo { - filter: invert(1); - } - - .logo { - filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} diff --git a/packages/webapp/src/app/page.tsx b/packages/webapp/src/app/page.tsx index 22328397..0aa944b7 100644 --- a/packages/webapp/src/app/page.tsx +++ b/packages/webapp/src/app/page.tsx @@ -1,46 +1,16 @@ -import Image from "next/image"; -import styles from "./page.module.css"; import DevView from "@/components/DevView"; -export default function Home() { - return ( -
-
-

- Get started by editing  - src/app/page.tsx -

-
- - By{" "} - Vercel Logo - -
-
- -
- Next.js Logo -
+const getIsLocal = async () => { + 'use server' + // Production is not ready for remote multiplayer yet. + return process.env.NODE_ENV === 'production'; +} - +export default async function Home() { + const isLocal = await getIsLocal(); + return ( +
+
); } diff --git a/packages/webapp/src/components/BoardGame.tsx b/packages/webapp/src/components/BoardGame.tsx index 8471831b..d3911dd0 100644 --- a/packages/webapp/src/components/BoardGame.tsx +++ b/packages/webapp/src/components/BoardGame.tsx @@ -1,5 +1,5 @@ import { Client, BoardProps } from 'boardgame.io/react'; -import { SocketIO } from 'boardgame.io/multiplayer' +import { SocketIO, Local } from 'boardgame.io/multiplayer' import { OpenStarTerVillage } from '@/game'; import Table from '@/components/Table/Table'; import Players from '@/components/Players/Players'; @@ -15,10 +15,14 @@ const Board: React.FC> = (props) = ); } -const Boardgame = Client({ - game: OpenStarTerVillage, - board: Board, - multiplayer: SocketIO({ server: 'localhost:8000' }), -}); +const Boardgame: React.FC<{ isLocal: boolean} & React.ComponentProps>> = ({ isLocal, ...props }) => { + const multiplayer = isLocal ? Local() : SocketIO({ server: 'localhost:8000' }); + + const BoardgameComponent = Client({ game:OpenStarTerVillage, + board: Board, + multiplayer, + }) + return ; +} export default Boardgame; diff --git a/packages/webapp/src/components/DevView.tsx b/packages/webapp/src/components/DevView.tsx index f97ef2e1..c57f3c7d 100644 --- a/packages/webapp/src/components/DevView.tsx +++ b/packages/webapp/src/components/DevView.tsx @@ -3,20 +3,20 @@ import { Box, Typography } from '@mui/material'; import Boardgame from '@/components/BoardGame'; -function DevView() { +function DevView({ isLocal }: { isLocal: boolean }) { return ( <> Player 0 view - + Player 1 view - + Observer view - + ); diff --git a/packages/webapp/src/server.ts b/packages/webapp/src/server.ts index 64bb90a7..ab6326ca 100644 --- a/packages/webapp/src/server.ts +++ b/packages/webapp/src/server.ts @@ -3,7 +3,9 @@ import { OpenStarTerVillage } from "./game"; async function serve() { const port = Number(process.env.PORT) || 8000; - const apiPort = Number(process.env.API_PORT) || 8080; + const dev = process.env.NODE_ENV !== "production"; + + console.log(`Starting server on port ${port} in ${dev ? 'dev' : 'production'} mode...`); const server = Server({ games: [OpenStarTerVillage], @@ -12,19 +14,12 @@ async function serve() { Origins.LOCALHOST_IN_DEVELOPMENT, ], }); - const mainServerConfig = { + const config = { port, callback: () => console.log(`Main server running on port ${port}...`), }; - const lobbyConfig = { - apiPort, - apiCallback: () => console.log(`Lobby api running on port ${apiPort}`), - }; - server.run({ - ...mainServerConfig, - lobbyConfig, - }); + server.run(config); } serve();