A monorepo project for exploring modern full-stack technologies through building an engaging puzzle game platform.
Puzloc (Puzzle Lock) is a collection of puzzle games where players attempt to "unlock" challenges through logic and deduction.
A Wordle-inspired number guessing game with a keypad interface.
How it works:
A Hangman/Countdown-style phrase guessing game.
How it works:
*** **** ***** ***
Just want to start coding?
# 1. Clone and setup
git clone https://github.com/olemak/puzloc.git
cd puzloc
npm install
# 2. Start development environment
npm run dev
# 3. Create backend (automated)
npm run setup:backend
# 4. Start coding!
cd apps/backend
dotnet watch run
OR follow the detailed guide: START_HERE.md ๐
npm run dev # Start Docker services
npm run setup:backend # Auto-create backend project
npm run docker:start # Start Docker only
npm run docker:stop # Stop Docker services
npm run db # Open PostgreSQL CLI
puzloc/
โโโ apps/
โ โโโ backend/ # .NET Web API
โ โ โโโ src/
โ โ โ โโโ Api/ # API controllers & endpoints
โ โ โ โโโ Core/ # Domain models & business logic
โ โ โ โโโ Infrastructure/ # Database, auth, external services
โ โ โ โโโ Services/ # Game logic services
โ โ โโโ tests/
โ โโโ frontend-svelte/ # Svelte web application
โ โ โโโ src/
โ โ โ โโโ lib/
โ โ โ โ โโโ components/ # Shared UI components
โ โ โ โ โโโ games/ # Game-specific components
โ โ โ โ โโโ services/ # API client, state management
โ โ โ โโโ routes/ # SvelteKit routes
โ โ โโโ tests/
โ โโโ frontend-native/ # React Native app (future)
โโโ packages/
โ โโโ shared-types/ # Shared TypeScript types
โ โโโ game-engine/ # Shared game logic
โ โโโ api-client/ # Typed API client
โโโ infrastructure/
โ โโโ docker/
โ โโโ docker-compose.yml
โ โโโ postgres/
โโโ docs/
โโโ api/ # API documentation
โโโ architecture/ # Architecture decisions
-- Users
CREATE TABLE users (
id UUID PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Daily Challenges
CREATE TABLE challenges (
id UUID PRIMARY KEY,
game_type VARCHAR(20) NOT NULL, -- 'numlock' or 'phraselock'
challenge_date DATE NOT NULL,
solution TEXT NOT NULL, -- encrypted/hashed
difficulty VARCHAR(20),
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(game_type, challenge_date)
);
-- Game Attempts
CREATE TABLE attempts (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
challenge_id UUID REFERENCES challenges(id),
guess TEXT NOT NULL,
result JSONB NOT NULL, -- Feedback data
attempt_number INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- User Stats
CREATE TABLE user_stats (
user_id UUID PRIMARY KEY REFERENCES users(id),
game_type VARCHAR(20) NOT NULL,
games_played INT DEFAULT 0,
games_won INT DEFAULT 0,
current_streak INT DEFAULT 0,
max_streak INT DEFAULT 0,
average_attempts DECIMAL(4,2),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(user_id, game_type)
);
-- Leaderboards (computed view or materialized)
CREATE TABLE leaderboard_entries (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
game_type VARCHAR(20) NOT NULL,
period VARCHAR(20) NOT NULL, -- 'daily', 'weekly', 'all_time'
score INT NOT NULL,
rank INT,
calculated_at TIMESTAMP DEFAULT NOW()
);
Clone and install dependencies:
git clone <repo-url>
cd puzloc
npm install
Start PostgreSQL:
cd infrastructure/docker
docker-compose up -d postgres
Run backend:
cd apps/backend
dotnet restore
dotnet run
Run frontend:
cd apps/frontend-svelte
npm install
npm run dev
function checkGuess(guess: string, solution: string): Feedback[] {
// Compare each digit
// Return array of: 'correct' | 'wrong-position' | 'not-in-answer'
}
function revealLetter(phrase: string, guessedLetters: Set<string>): string {
// Reveal guessed letters, keep rest masked
}
This project is designed to explore:
MIT
Built as a learning project to explore modern full-stack technologies.