Poly Game is a monorepo that contains:
- Backend: Express server written in TypeScript
- Frontend: Vue 3 (Vite, Pinia, Vue Router)
User uploads a character image → OpenAI generates a textual description and a low‑poly style image → Meshy generates a 3D model + texture → the result is previewed in Three.js.
- Node 20+ (managed via
miseif you use it) - Yarn (monorepo workspaces)
- Docker & Docker Compose (for MongoDB and Redis)
- MongoDB, Redis, BullMQ, Socket.io, OpenAI, Meshy, Three.js
packages/server– Express API, job queue, OpenAI + Meshy integration
Seepackages/server/README.mdfor server-specific setup and architecture.packages/client– Vue 3 frontend, character upload and viewer
Seepackages/client/README.mdfor client-specific setup and UI flow.
Create your server env file from the example:
cp packages/server/.env.example packages/server/.envThen fill in the sensitive values:
PORT– API port (default3000)MONGODB_URI– MongoDB connection string (e.g.mongodb://localhost:27017/poly-game)REDIS_HOST– Redis host (e.g.localhost)REDIS_PORT– Redis port (e.g.6379)OPENAI_API_KEY– OpenAI API key (GPT‑4o + DALL‑E 3)GEMINI_API_KEY– Gemini API key (if used in the pipeline)MESHY_API_KEY– API key from Meshy API
Do not commit your real
.envfiles to git – only.env.example.
Create the client env file from the example:
cp packages/client/.env.example packages/client/.envAvailable variables:
VITE_API_BASE_URL– base URL of the backend API, e.g.http://localhost:3000
If you use the provided Docker setup:
docker-compose up -dOr, if you prefer, use the npm scripts:
yarn docker:up # start MongoDB and Redis
yarn docker:down # stop containersFrom the repository root:
yarnRun both client and server in parallel:
yarn devOr start them separately:
yarn dev:server # backend on http://localhost:3000
yarn dev:client # frontend on http://localhost:5173Default URLs:
- Frontend:
http://localhost:5173 - API:
http://localhost:3000
-
TestPage (upload)
The user uploads an image. The frontend sendsPOST /api/upload/image.
The server:- creates a document in the
characterscollection, - saves the uploaded image into
packages/server/uploads, - enqueues a BullMQ job for the full AI pipeline.
The response contains{ id }, and the client redirects to/character/:id.
- creates a document in the
-
CharacterPage (viewer)
The page fetches character details byidand listens to Socket.io events:- channel:
character:progress
When the job finishes, the backend emits the final payload withmodelUrl.
The frontend then shows the 3D model in Three.js with OrbitControls and available rig animations (if Meshy returns them).
- channel:
-
BullMQ job (AI pipeline) – a single job covers the entire flow:
- OpenAI Vision – generates a description of the uploaded image,
- OpenAI Image (DALL‑E 3) – generates a low‑poly style image from the description + fixed style prompt,
- saves the generated image into
uploads, - Meshy Image‑to‑3D – creates a 3D model + texture (
should_texture: true), - polls Meshy job status, and on success:
- saves
modelUrlinto the character document, - emits the final update via Socket.io so the frontend can refresh.
- saves
| Script | Description |
|---|---|
yarn dev |
Run client + server in parallel |
yarn dev:server |
Run server only (port 3000) |
yarn dev:client |
Run client only (port 5173) |
yarn build |
Build all packages |
yarn docker:up |
Start MongoDB and Redis via Docker |
yarn docker:down |
Stop Docker containers |