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

5.3 KiB

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

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:

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

interface DailyVerse {
  id: string;
  date: string; // 'YYYY-MM-DD'
  bookId: string;
  text: string;
  reference: string; // e.g. 'John 3:16'
}

Guess

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:

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]

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]

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

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?