Files
bibdle/plans/bibdle-architecture.md
George Powell 530291d271 Version 1
2025-12-16 10:23:24 -05:00

216 lines
5.3 KiB
Markdown

# Bibdle Game Architecture Plan
## Overview
Bibdle is a daily Bible verse guessing game inspired by Wordle. Players guess the book of the Bible for a random daily verse. Features:
- Infinite guesses
- Feedback grid: Guess | Testament (Old/New) | Section | Proximity (! if adjacent book)
- Daily verse fetched from Bible API (`/data/web/random`) and cached in DB by calendar day (YYYY-MM-DD)
- Hierarchical book categorization for feedback
## Data Structures
### BibleBook Interface
```typescript
interface BibleBook {
id: string; // e.g. 'GEN'
name: string; // e.g. 'Genesis'
testament: "old" | "new";
section: string; // e.g. 'Law', 'Gospels'
order: number; // Canonical position 1-66
url: string;
}
```
### Full Books Array
Static data derived from provided JSON + hierarchy:
```typescript
export const bibleBooks: BibleBook[] = [
{
id: "GEN",
name: "Genesis",
testament: "old",
section: "Law",
order: 1,
url: "https://bible-api.com/data/web/GEN",
},
{
id: "EXO",
name: "Exodus",
testament: "old",
section: "Law",
order: 2,
url: "https://bible-api.com/data/web/EXO",
},
// ... (all 66 books mapped similarly)
// Full list to be implemented in src/lib/bible.ts
];
```
**Mapping Summary**:
- **Old Testament** (1-39):
- Law (1-5): GEN-EXO-LEV-NUM-DEU
- History (6-17): JOS-JDG-RUT-1SA-2SA-1KI-2KI-1CH-2CH-EZR-NEH-EST
- Wisdom (18-22): JOB-PSA-PRO-ECC-SNG
- Major Prophets (23-27): ISA-JER-LAM-EZK-DAN
- Minor Prophets (28-39): HOS-JOL-AMO-OBA-JON-MIC-NAM-HAB-ZEP-HAG-ZEC-MAL
- **New Testament** (40-66):
- Gospels (40-43): MAT-MRK-LUK-JHN
- History (44): ACT
- Pauline Epistles (45-57): ROM-1CO-2CO-GAL-EPH-PHP-COL-1TH-2TH-1TI-2TI-TIT-PHM
- General Epistles (58-65): HEB-JAS-1PE-2PE-1JN-2JN-3JN-JUD
- Apocalyptic (66): REV
### DailyVerse
```typescript
interface DailyVerse {
id: string;
date: string; // 'YYYY-MM-DD'
bookId: string;
text: string;
reference: string; // e.g. 'John 3:16'
}
```
### Guess
```typescript
interface Guess {
book: BibleBook;
isCorrect: boolean;
isAdjacent: boolean; // Math.abs(guess.order - correct.order) === 1
}
```
## Database Schema Additions
Extend [`src/lib/server/db/schema.ts`](src/lib/server/db/schema.ts):
```typescript
export const dailyVerses = sqliteTable("daily_verses", {
id: text("id").primaryKey(),
date: text("date").unique().notNull(), // YYYY-MM-DD
bookId: text("book_id").notNull(),
verseText: text("verse_text").notNull(),
reference: text("reference").notNull(),
createdAt: integer("created_at", { mode: "timestamp" }).defaultNow(),
});
```
## Key Services (Server-Side)
### 1. Bible Service [`src/lib/server/bible.ts`]
- Load `bibleBooks` array
- Methods: `getBook(id)`, `getBooksByTestament()`, `getBooksBySection()`, `isAdjacent(book1, book2)`
### 2. Bible API Service [`src/lib/server/bible-api.ts`]
```typescript
export async function fetchRandomVerse(): Promise<
Omit<DailyVerse, "date" | "id">
> {
const res = await fetch("https://bible-api.com/data/web/random");
// Parse response to extract text, reference, bookId
}
```
### 3. DailyVerse Service [`src/lib/server/daily-verse.ts`]
```typescript
export async function getDailyVerse(
date = getTodayDate()
): Promise<DailyVerse> {
let verse = await db
.select()
.from(dailyVerses)
.where(eq(dailyVerses.date, date))
.get();
if (!verse) {
const apiVerse = await fetchRandomVerse();
verse = await db
.insert(dailyVerses)
.values({
...apiVerse,
date,
id: crypto.randomUUID(),
})
.returning();
}
return verse;
}
```
## Frontend Components Structure
```
src/lib/components/
├── Game.svelte # Main game
├── VerseDisplay.svelte
├── BookSearch.svelte # Autocomplete book selector
├── GuessesGrid.svelte # Rows: Book | Testament | Section | !
└── Keyboard.svelte # Virtual keyboard (optional)
```
## Game Flow
```mermaid
graph TD
A[Load page] --> B[getDailyVerse()]
B --> C[Display verse]
C --> D[Book selector]
D --> E[Submit guess]
E --> F[Get feedback]
F --> G[Add row to grid]
G --> H{Correct?}
H -->|Yes| I[Win screen]
H -->|No| D
```
## Proximity Logic
```
isAdjacent(guess: BibleBook, correct: BibleBook): boolean {
return Math.abs(guess.order - correct.order) === 1;
}
```
## Implemented Features
- ✅ Bible data structures & full books array in `src/lib/types/bible.ts`
- ✅ DB schema `daily_verses` & migration
- ✅ Bible API service with random + next 2 verses range fetch
- ✅ Daily verse loader in `+page.server.ts`
- ✅ Interactive UI in `+page.svelte`: search, guesses, 3-column feedback grid (Book/Testament/Section green/red), win screen
- ✅ Responsive Tailwind design
## Remaining / Future
- Stats tracking
- ✅ Share functionality
- Virtual keyboard
- Animations
- Multi-day history
## Updated Feedback Grid
3 columns (Close hidden secret):
- Book: green exact, red incorrect
- Testament: green match, red mismatch
- Section: green match, red mismatch
- Implement static bibleBooks array with full metadata
- Update DB schema + migrate
- Create server actions/load functions for daily verse
- Build core game logic
- UI implementation
This plan covers the core data structures and architecture. Ready for implementation?