The useProjectStore hook manages the project configuration wizard that guides users through setting up a new game. It stores dimension (2D/3D), genre, template, and project name selections.
State interface
interface ProjectStore {
config: ProjectConfig;
setDimension: (d: GameDimension) => void;
setGenre: (g: GameGenre) => void;
setTemplate: (t: GameTemplate) => void;
setName: (n: string) => void;
reset: () => void;
}
Types
ProjectConfig
interface ProjectConfig {
name: string;
dimension: GameDimension | null;
genre: GameGenre | null;
template: GameTemplate | null;
}
The project name entered by the user
dimension
GameDimension | null
required
Whether the project is 2D or 3D
template
GameTemplate | null
required
The starter template to use
GameDimension
type GameDimension = '2d' | '3d';
GameGenre
type GameGenre =
| 'platformer'
| 'puzzle'
| 'rpg'
| 'racing'
| 'shooter'
| 'adventure'
| 'strategy'
| 'sandbox'
| 'social'
| 'other';
GameTemplate
type GameTemplate =
| 'blank'
| 'platformer-starter'
| 'token-gate-room'
| 'nft-gallery'
| 'multiplayer-arena'
| 'endless-runner';
Available starter templates:
- blank - Empty scene to start from scratch
- platformer-starter - Basic platformer with player and platforms
- token-gate-room - Web3 room requiring token to enter
- nft-gallery - 3D gallery showcasing user NFTs
- multiplayer-arena - Arena setup for multiplayer games
- endless-runner - Infinite runner template with obstacles
State properties
The current project configuration object
Actions
setDimension
Set the project dimension (2D or 3D).
setDimension(d: GameDimension): void
Example:
const projectStore = useProjectStore();
projectStore.setDimension('3d');
setGenre
Set the game genre.
setGenre(g: GameGenre): void
Example:
projectStore.setGenre('platformer');
setTemplate
Set the starter template to use.
setTemplate(t: GameTemplate): void
Example:
projectStore.setTemplate('platformer-starter');
setName
Set the project name.
Example:
projectStore.setName('My First Game');
reset
Reset all configuration values to defaults (null/empty).
Usage example
import { useProjectStore } from '@/store/projectStore';
function ProjectWizard() {
const { config, setDimension, setGenre, setTemplate, setName } = useProjectStore();
const handleComplete = () => {
console.log('Creating project:', config);
// Navigate to editor based on dimension
if (config.dimension === '3d') {
router.push('/editor');
} else {
router.push('/editor-2d');
}
};
return (
<div>
{/* Step 1: Choose dimension */}
<button onClick={() => setDimension('2d')}>2D Game</button>
<button onClick={() => setDimension('3d')}>3D Game</button>
{/* Step 2: Choose genre */}
<select onChange={(e) => setGenre(e.target.value as GameGenre)}>
<option value="platformer">Platformer</option>
<option value="puzzle">Puzzle</option>
<option value="rpg">RPG</option>
</select>
{/* Step 3: Choose template */}
<select onChange={(e) => setTemplate(e.target.value as GameTemplate)}>
<option value="blank">Blank Canvas</option>
<option value="platformer-starter">Platformer Starter</option>
<option value="token-gate-room">Token Gate Room</option>
</select>
{/* Step 4: Name project */}
<input
type="text"
placeholder="Project name"
value={config.name}
onChange={(e) => setName(e.target.value)}
/>
<button onClick={handleComplete}>Create Project</button>
</div>
);
}
Wizard flow
The project wizard typically follows this 4-step flow:
Choose dimension
User selects between 2D or 3D game
Pick genre
User selects the game genre (platformer, puzzle, RPG, etc.)
Choose template
User selects a starter template or blank canvas
Name project
User enters a project name and confirms to create the project
Default values
const DEFAULT_CONFIG: ProjectConfig = {
name: '',
dimension: null,
genre: null,
template: null,
};
See also