Oasis Builder - from Open Oasis
A modern isometric city builder in the Oasis built with Next.js, Phaser.js, and shadcn/ui components.
- ๐๏ธ Build your city: Place various buildings and tiles on an isometric grid
- ๐จ 24 different tiles: Choose from a curated selection of buildings and terrain
- ๐ค AI sprite generation: Generate custom isometric buildings with DALL-E
- ๐ฆ Custom assets: Upload your own sprite sheets or single images
- ๐๏ธ Sprite controls: Adjust scale, origin, and multi-tile footprints
- ๐น Camera controls: Pan, zoom, and explore your city
- ๐ฑ๏ธ Intuitive interface: Modern UI with shadcn components
- ๐ Dark mode ready: Styled with lime theme on stone base
- โก Next.js 15: Built with the latest Next.js features
- ๐ฎ Phaser.js: Professional game engine for smooth rendering
- Framework: Next.js 15 with App Router
- Game Engine: Phaser.js 3
- UI Components: shadcn/ui (Radix UI + Tailwind CSS)
- Styling: Tailwind CSS with lime theme
- TypeScript: Full type safety
npm installCreate a .env.local file for AI sprite generation:
OPENAI_API_KEY=your_openai_api_keynpm run devOpen http://localhost:3000 in your browser.
npm run build
npm start- Left Click: Place the selected tile
- Right Click: Remove a tile
- Arrow Keys / WASD: Pan the camera
- Mouse Wheel: Zoom in/out
- Hover: See preview of tile placement
Generate custom isometric buildings using AI:
- Click Add Custom Assets in the tile selector
- Switch to Generate / Single Image tab
- Set the footprint size (1x1 to 4x4 tiles)
- Enter a prompt (e.g., "City Hall", "Fire Station", "Hospital")
- Click Generate to create an isometric sprite
- Adjust Scale (0.5x - 2x) and Origin to align with the tile grid
- Preview shows the sprite on isometric tiles with anchor point
- Click Add Asset to add to your tile palette
Requires OPENAI_API_KEY environment variable.
Click the + button on any custom asset set to add more sprites to it.
Upload your own sprite sheets:
- Sprite Sheet + XML: Upload a PNG sprite sheet with an XML atlas definition
- Single Image: Upload any PNG/JPEG image to auto-scale for the isometric grid
XML format for sprite sheets:
<TextureAtlas>
<SubTexture name="tile.png" x="0" y="0" width="132" height="66"/>
<SubTexture name="building.png" x="132" y="0" width="132" height="200"
footprintWidth="2" footprintHeight="2"/>
</TextureAtlas>iso-city-builder/
โโโ app/
โ โโโ page.tsx # Main page component
โ โโโ globals.css # Global styles
โ โโโ api/
โ โโโ generate-sprite/ # AI sprite generation endpoint
โโโ components/
โ โโโ iso-city-game.tsx # Phaser game component
โ โโโ tile-selector.tsx # Tile selection UI
โ โโโ sprite-packer.tsx # Custom asset & AI generation dialog
โ โโโ ui/ # shadcn components
โโโ public/
โ โโโ assets/ # Game sprite sheets
โโโ lib/
โโโ utils.ts # Utility functions
The game uses Phaser.js for rendering the isometric city. The Phaser scene is wrapped in a React component and dynamically imported to avoid SSR issues:
const IsoCityGame = dynamic(
() => import("@/components/iso-city-game").then((mod) => mod.IsoCityGame),
{ ssr: false },
);The game converts between grid coordinates and isometric screen coordinates:
// Grid to Isometric
const isoX = (gridX - gridY) * (tileWidth / 2);
const isoY = (gridX + gridY) * (tileHeight / 2);
// Isometric to Grid
const gridX = Math.floor(
(isoX / (tileWidth / 2) + isoY / (tileHeight / 2)) / 2,
);
const gridY = Math.floor(
(isoY / (tileHeight / 2) - isoX / (tileWidth / 2)) / 2,
);Communication between React and Phaser uses:
- Custom window events for data passing
- Window-scoped functions for method calls
- React state for UI updates
Edit the tilesToShow array in components/tile-selector.tsx:
const tilesToShow = [0, 13, 18, 26, 33, 97, ...];Modify gridSize in components/iso-city-game.tsx:
gridSize = 30; // Change to your desired sizeThe project uses shadcn's lime theme on a stone base. To change colors, modify components.json and run:
npx shadcn@latest init- Phaser uses WebGL for hardware-accelerated rendering
- Sprite sheets reduce draw calls
- React components only re-render on state changes
- Game loop runs independently of React
- Game Engine: Phaser.js
- UI Components: shadcn/ui
- Isometric Assets: Kenney's City Kit
- Framework: Next.js
MIT