Initialize calm game project

This commit is contained in:
2026-06-27 08:37:40 +03:00
commit cc7aec8db5
34 changed files with 5329 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
# 🌙 Уютная викторина — Calm Family Quiz
Спокойная семейная игра-викторина в стиле «Своей игры», созданная для уютного
вечера перед сном. Все смотрят на одно табло, ведущий управляет игрой, команда
отвечает вместе — без таймеров, давления и спешки.
## 🚀 Запуск
```bash
npm install
npm run dev
```
Откройте адрес из консоли (обычно `http://localhost:5173`).
### Прочее
```bash
npm run build # production-сборка
npm run preview # предпросмотр сборки
npm run check # проверка типов (svelte-check)
```
## 🎮 Как играть
1. **Выбор набора** — выберите тему вопросов.
2. **Табло** — категории и карточки очков (100 / 200 / 300 / 500 / 1000).
Чем дороже карточка, тем сложнее вопрос.
3. Ведущий открывает вопрос, затем «Показать ответ», и решает:
- **Засчитать +N** — команде идут очки;
- **Не засчитывать** — без очков, но вопрос закрыт.
- Штрафов и минусов нет.
4. Для творческих вопросов (type `creative`) кнопка мягче:
«Засчитать творческий ответ +N».
5. Сыгранный вопрос затемняется и больше не выбирается.
6. Когда сыграны все вопросы — экран результата с мягкой финальной фразой.
Прогресс сохраняется автоматически — после перезагрузки игра продолжится с того же места.
## 🧩 Добавление нового набора вопросов
Архитектура задумана так, чтобы наборы добавлялись без правок UI.
1. Создайте файл `src/lib/question-sets/<name>.ts`:
```ts
import type { QuestionSet } from '$lib/types';
export const mySet: QuestionSet = {
id: 'my-set', // уникальный
title: 'Моя тема',
description: 'Короткое описание',
ageRange: '6+ лет',
categories: [
{
id: 'cat-1', // уникально в пределах набора
title: 'Категория',
questions: [
{ id: 'q1', points: 100, question: '...', answer: '...', type: 'strict' },
{ id: 'q2', points: 200, question: '...', answer: '...', type: 'strict' },
{ id: 'q3', points: 300, question: '...', answer: '...', type: 'strict' },
{ id: 'q4', points: 500, question: '...', answer: '...', type: 'creative' },
{ id: 'q5', points: 1000, question: '...', answer: '...', type: 'strict' }
// ровно 5 вопросов с очками 100/200/300/500/1000
]
}
// …остальные категории
]
};
```
2. Зарегистрируйте набор в `src/lib/question-sets/index.ts`:
```ts
import { mySet } from './my-set';
export const questionSets = [animalsSet, cozySet, mySet];
```
Готово — набор автоматически появится на экране выбора.
## 🏗️ Архитектура
Код аккуратно разделён по слоям:
```
src/
├─ lib/
│ ├─ types.ts # Доменные типы (Question, Category, QuestionSet, GameState)
│ ├─ question-sets/ # ДАННЫЕ (отделены от UI)
│ │ ├─ animals.ts # набор-заглушка
│ │ ├─ cozy.ts # набор-заглушка
│ │ └─ index.ts # реестр наборов + хелперы поиска
│ ├─ stores/
│ │ └─ game.ts # СОСТОЯНИЕ игры (Svelte store + localStorage)
│ └─ components/ # UI-компоненты
│ ├─ QuestionSetSelector.svelte
│ ├─ GameBoard.svelte
│ ├─ QuestionCard.svelte
│ ├─ ScorePanel.svelte
│ ├─ QuestionModal.svelte
│ ├─ HostControls.svelte
│ ├─ GameResult.svelte
│ └─ ConfirmDialog.svelte
└─ routes/
├─ +layout.svelte # подключение глобальных стилей
├─ +layout.ts # CSR-only (localStorage)
└─ +page.svelte # оркестрация экранов
```
**Принципы:**
- Данные вопросов полностью отделены от состояния и UI.
- Состояние игры живёт в Svelte store с автосохранением в `localStorage`
и восстанавливается после перезагрузки.
- Очки берутся из данных вопроса — ничего не хардкодится в UI.
- Никакого бэкенда, БД, авторизации, мультиплеера или редактора в MVP.
## 🎨 Стек
- **SvelteKit + TypeScript**
- **Tailwind CSS v4** (через `@tailwindcss/vite`)
- Без тяжёлых UI-библиотек — только лёгкие зависимости.
Лицензия: личный/семейный проект.