A web app for Phasmophobia to keep track of evidence and narrow down which ghost you are hunting (or is hunting you)!
Built with Next.js and deployed as a static site.
π Live App: daedalist.github.io/ghostbook
- Evidence Tracking: Click evidence to cycle through states (Not Selected β Selected β Ruled Out)
- Smart Ghost Filtering: Automatically filters possible ghosts based on your evidence
- Evidence Disabling: Grays out evidence that's impossible based on current selections
- Reset Function: Clear all evidence with one click
- Responsive Design: Works on desktop and mobile devices
- Node.js (version 14 or higher)
- npm
-
Clone the repository:
git clone https://github.com/daedalist/ghostbook.git cd ghostbook -
Install dependencies:
npm install
-
Run the development server:
npm run dev
-
Open http://localhost:3000/ghostbook/ in your browser
β οΈ Note: The app uses the/ghostbookbase path to match the GitHub Pages deployment structure.
npm run dev- Start development server with hot reloadingnpm run build- Build the app for productionnpm start- Build and serve the production version locally
npm test- Run the unit test suite oncenpm run test:watch- Run tests in watch mode during developmentnpm run test:github-pages- Test the app as it will appear on GitHub Pages
npm run lint- Run ESLintnpm run format:check- Check Prettier formattingnpm run type-check- Run TypeScript type checkingnpm run clean- Remove build artifacts and test files
-
Select Evidence: Click on evidence types as you discover them in-game
- First click: Mark as "Selected" (white background)
- Second click: Mark as "Ruled Out" (gray background with strikethrough)
- Third click: Return to "Not Selected"
-
View Possible Ghosts: The right panel shows ghosts ranked by likelihood based on your evidence
-
Evidence Auto-Disable: Evidence that becomes impossible will be grayed out automatically
-
Reset: Use the "Reset" button to clear all evidence and start fresh
- Next.js 16 - React framework with static site generation
- React 19 - UI library
- TypeScript - Type safety for app router files
- ESLint - Code quality and best practices
- Prettier - Automated code formatting
- CSS - Custom styling with CSS Grid and Flexbox
- GitHub Pages - Static site hosting
src/
βββ app/
β βββ layout.tsx # Root layout with metadata
β βββ globals.css # Global styles
β βββ [[...slug]]/ # Catch-all route for SPA behavior
β βββ page.tsx # Main page component
β βββ client.tsx # Client-side wrapper
βββ components/
β βββ Ghostbook.jsx # Main application component
β βββ ObservationList.jsx # Evidence tracking interface
β βββ CandidateList.jsx # Ghost filtering display
βββ lib/
βββ ghost.js # Ghost and evidence data
βββ ghost_data_map.json # Ghost evidence mappings
βββ evidenceState.js # Evidence state constants
This project was migrated from Create React App to Next.js to take advantage of:
- Better build optimization and tree-shaking
- Automatic code splitting
- Static site generation
- Foundation for future server-side features
The app currently runs as a Single Page Application (SPA) using Next.js static export for GitHub Pages compatibility.
Evidence states are managed using JavaScript Maps and React class component state. Each evidence type can be in one of four states:
NOT_SELECTED- Default stateSELECTED- User has confirmed this evidenceRULED_OUT- User has confirmed this evidence is NOT presentDISABLED- Evidence is impossible based on current ghost candidates
Ghosts are scored based on evidence:
- +10 points for each matching primary evidence
- +5 points for each matching fake evidence
- -10 points (elimination) for contradictory evidence
Unit tests are written with Vitest and Testing Library. Run them with:
npm testThe test suite covers three areas:
- Data integrity β validates evidence constants, evidence state values, and the ghost data map (correct evidence counts, no overlaps between primary and fake evidence, all entries reference valid evidence names).
- Component rendering β verifies that Header, Ghost, ObservationList, and CandidateList render the expected elements, apply the correct CSS classes for each evidence state, and call the right callbacks on click.
- User journeys β exercises the full Ghostbook component: selecting evidence and verifying ghost filtering, cycling evidence through all states, ruling out evidence to eliminate ghosts, resetting to the initial state, evidence auto-disabling when only one candidate remains, and The Mimic's fake-evidence scoring.
Tests run in a jsdom environment so they don't need a browser. During development, npm run test:watch re-runs affected tests on file save.
E2E tests are written with Playwright and verify the functionality of the deployed application in a real browser.
To run the E2E tests:
npm run test:e2eThe E2E test suite covers two main areas:
- Page Rendering: Ensures that all UI elements, such as the header, evidence buttons, and candidate list, render correctly on page load.
- User Interactions: Simulates user behavior, such as clicking evidence buttons, filtering ghosts, and using the reset button, to verify that the application's features work as expected.
Playwright is configured to automatically start the application server, run the tests, and then shut down the server.
The app is configured for static deployment to GitHub Pages:
-
Build the static site:
npm run build
-
The
build/directory contains all static files ready for deployment -
GitHub Pages serves from the
/ghostbookpath, configured viabasePathinnext.config.js
We welcome contributions! Please see CONTRIBUTING.md for detailed guidelines on:
- Setting up your development environment
- Code style and formatting (Prettier & ESLint)
- Making changes and submitting pull requests
- Testing and build verification
This project is open source and available under the MIT License.
- Phasmophobia by Kinetic Games
- Ghost data and evidence information from the Phasmophobia community
- Originally built with Create React App, migrated to Next.js
Happy ghost hunting! π»