diff --git a/README.md b/README.md index 7b49bfe4..6692edb8 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,15 @@ This is the code forked from OrcPub2, from the [original](https://github.com/lar   -[About](#about) • [Getting Started](#getting-started) • [Development](#development) • [Contributing](#how-do-i-contribute?) • [Fundamentals](#Fundamentals) +[About](#about) • [Getting Started](#getting-started) • [Development](#development) • [Contributing](#how-do-i-contribute?) • [📚 Documentation](docs/index.md) ## About Dungeon Master's Vault is a web server that allows you to host your own Character Generator website for D&D 5th Edition. +> 📚 **New to the Project?** Check out our comprehensive [Developer Documentation](docs/index.md) with beginner-friendly guides, technology overviews, and contribution instructions. + ## Getting Started @@ -214,6 +216,8 @@ More on these passwords here. ## How do I contribute? Thank you for rolling for initiative! +> 📖 **Start Here**: Our new [Contributing Guide](docs/contributing.md) provides comprehensive information for contributors of all skill levels, including Clojure newcomers. + We work on forks, and branches. Fork our repo, then create a new branch for any bug or new feature that you want to work on. ### Get started @@ -460,7 +464,11 @@ For this reason we have to build a dependency graph of derived attributes and th ## FAQs **Q: I'm a newb Clojure developer looking to get my feet wet, where to start?** -**A:** *First I would start by getting the fundamentals down at https://4clojure.oxal.org/ From there you might add some unit tests or pick up an open issue on the "Issues" tab (and add unit tests with it).* +**A:** *Great question! We have comprehensive resources for Clojure newcomers:* +- *Start with our [Technology Overview](docs/technology-overview.md) to understand Clojure, ClojureScript, and the web stack* +- *Follow our detailed [Getting Started](docs/getting-started.md) guide for step-by-step setup instructions* +- *Try the interactive exercises at https://4clojure.oxal.org/ to practice Clojure fundamentals* +- *Check our [Contributing Guide](docs/contributing.md) for beginner-friendly issues and development tips* **Q: Your DSL for defining character options is pretty cool, I can build any type of character option out there. How about I add a bunch on content from the Player's Handbook?** diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 00000000..4d80d809 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,447 @@ +# Contributing Guide + +Thank you for your interest in contributing to Dungeon Master's Vault! This guide will help you get started with contributing code, documentation, or other improvements to the project. + +## 🎯 How You Can Contribute + +### For New Contributors +- **Bug Reports**: Help us find and fix issues +- **Documentation**: Improve guides and examples +- **Testing**: Try new features and report problems +- **Code Review**: Review pull requests from other contributors + +### For Experienced Developers +- **Bug Fixes**: Solve existing issues +- **New Features**: Add D&D content or application features +- **Performance**: Optimize code and database queries +- **Architecture**: Improve code structure and patterns + +### For D&D Experts +- **Content Accuracy**: Verify D&D rules implementation +- **Game Balance**: Ensure rules work correctly together +- **New Content**: Add support for new D&D books and content + +## 🚀 Getting Started + +### 1. Set Up Your Development Environment + +Follow our [Getting Started](getting-started.md) guide to set up your local development environment. Make sure you can: +- Run the application locally +- Execute tests successfully +- Make a simple change and see it work + +### 2. Find an Issue to Work On + +**Good First Issues:** +Look for issues labeled `good-first-issue` on our [GitHub Issues](https://github.com/codeGlaze/orcpub/issues) page. These are specifically chosen to be approachable for new contributors. + +**Categories of Work:** +- **Bug fixes** - Issues labeled `bug` +- **Feature requests** - Issues labeled `enhancement` +- **Documentation** - Issues labeled `documentation` +- **D&D content** - Issues labeled `content` +- **Performance** - Issues labeled `performance` + +**Before Starting Work:** +1. Comment on the issue saying you'd like to work on it +2. Wait for a maintainer to assign it to you +3. Ask questions if anything is unclear + +### 3. Fork and Branch + +```bash +# Fork the repository on GitHub, then clone your fork +git clone https://github.com/YOUR_USERNAME/orcpub.git +cd orcpub + +# Add upstream remote +git remote add upstream https://github.com/codeGlaze/orcpub.git + +# Create a feature branch from develop +git checkout develop +git pull upstream develop +git checkout -b feature/descriptive-name + +# Example branch names: +# feature/add-warlock-spells +# bugfix/character-sheet-pdf-formatting +# docs/improve-getting-started-guide +``` + +## 📝 Development Guidelines + +### Code Style + +#### Clojure/ClojureScript Standards +```clojure +;; Use descriptive function names +(defn calculate-spell-attack-bonus [character] + ;; Implementation here + ) + +;; Use threading macros for data transformation +(-> character + (get :abilities) + (get :intelligence) + ability-modifier) + +;; Use meaningful variable names +(let [intelligence-score (get-in character [:abilities :intelligence]) + intelligence-modifier (ability-modifier intelligence-score)] + (+ base-spell-attack intelligence-modifier)) + +;; Document public functions +(defn calculate-armor-class + "Calculates total AC from base AC, dexterity modifier, and bonuses. + + Args: + base-ac: Base armor class from armor + dex-mod: Dexterity modifier (may be capped by armor) + bonuses: Collection of magical/situational AC bonuses + + Returns: + Total armor class as integer" + [base-ac dex-mod bonuses] + (+ base-ac dex-mod (apply + bonuses))) +``` + +#### re-frame Conventions +```clojure +;; Use namespaced event keywords +(dispatch [:character/update-name "New Name"]) +(dispatch [:spell/add-to-spellbook spell-id]) + +;; Keep event handlers pure +(reg-event-db + :character/level-up + (fn [db [_ character-id]] + (update-in db [:characters character-id :level] inc))) + +;; Use descriptive subscription names +(reg-sub + :character/spell-slots-remaining + (fn [db [_ character-id]] + (calculate-remaining-spell-slots + (get-in db [:characters character-id])))) +``` + +#### HTML/CSS Guidelines +```clojure +;; Use semantic Hiccup markup +[:section.character-sheet + [:header.character-header + [:h1.character-name (:name character)] + [:p.character-details + "Level " (:level character) " " (:class character)]] + [:main.character-stats + ;; Character stats here + ]] + +;; Use CSS classes for styling, not inline styles +[:button.btn.btn-primary {:on-click handle-save} "Save Character"] +;; Instead of: +[:button {:style {:background "blue" :color "white"}} "Save"] +``` + +### Testing Requirements + +#### Writing Tests +Every contribution should include appropriate tests: + +**For Pure Functions:** +```clojure +(deftest ability-modifier-test + (testing "ability modifier calculation" + (are [score expected] (= expected (ability-modifier score)) + 1 -5 + 8 -1 + 10 0 + 16 3 + 20 5))) +``` + +**For re-frame Events:** +```clojure +(deftest character-update-events + (testing "character name update" + (let [initial-db {:current-character {:name "Old Name"}} + result (events/update-character-name + initial-db + [:character/update-name "New Name"])] + (is (= "New Name" + (get-in (:db result) [:current-character :name])))))) +``` + +**For UI Components:** +```clojure +(deftest character-display-test + (testing "character display component" + (let [character {:name "Test" :level 5 :class "Fighter"} + component (character-summary character)] + (is (string/includes? (str component) "Test")) + (is (string/includes? (str component) "Level 5"))))) +``` + +#### Running Tests +```bash +# Run all tests before submitting +lein test + +# Run specific test file +lein test orcpub.character-test + +# Run tests continuously during development +lein test-refresh +``` + +### Documentation Standards + +#### Code Documentation +- Document all public functions with docstrings +- Include parameter descriptions and return values +- Add examples for complex functions +- Explain any non-obvious business logic + +#### User Documentation +- Use clear, beginner-friendly language +- Include examples and code samples +- Provide links to external resources +- Test all instructions on a fresh setup + +## 🔍 Pull Request Process + +### Before Submitting + +**Quality Checklist:** +- [ ] **Tests pass**: `lein test` succeeds +- [ ] **Code formatted**: `lein cljfmt check` passes +- [ ] **Manual testing**: Changes work as expected in browser +- [ ] **Documentation**: Updated any relevant docs +- [ ] **No console errors**: Check browser developer tools + +**Performance Checklist:** +- [ ] No obvious performance regressions +- [ ] Database queries are efficient +- [ ] UI remains responsive + +### Pull Request Template + +Use this template when creating your pull request: + +```markdown +## Description +Brief description of what this PR does and why. + +Fixes #(issue number) + +## Type of Change +- [ ] Bug fix (non-breaking change that fixes an issue) +- [ ] New feature (non-breaking change that adds functionality) +- [ ] Breaking change (fix or feature that changes existing behavior) +- [ ] Documentation update + +## Testing +Describe how you tested your changes: + +- [ ] Unit tests added/updated +- [ ] Manual testing completed +- [ ] Tested in multiple browsers +- [ ] Tested with different character builds + +## Screenshots +Include screenshots for UI changes. + +## Checklist +- [ ] Tests pass locally +- [ ] Code follows project style guidelines +- [ ] Self-review of code completed +- [ ] Documentation updated +- [ ] No new warnings or errors +``` + +### Review Process + +1. **Automated Checks**: GitHub Actions will run tests and checks +2. **Code Review**: Maintainers will review your code +3. **Feedback**: You may receive requests for changes +4. **Approval**: Once approved, your PR will be merged + +**Responding to Feedback:** +- Be open to suggestions and questions +- Make requested changes promptly +- Ask for clarification if feedback is unclear +- Update your branch with any changes + +## 🏗️ Types of Contributions + +### Bug Fixes + +**Finding Bugs:** +1. Check existing issues for known bugs +2. Test edge cases in the application +3. Try unusual character combinations +4. Test on different browsers/devices + +**Fixing Bugs:** +1. Write a test that reproduces the bug +2. Fix the minimal code needed to make test pass +3. Verify fix doesn't break existing functionality +4. Update documentation if needed + +**Example Bug Fix:** +```clojure +;; Bug: Spell DC calculation incorrect for sorcerers +;; Test first: +(deftest spell-dc-calculation-test + (testing "sorcerer spell save DC" + (let [sorcerer {:class :sorcerer + :level 5 + :abilities {:charisma 16}} + expected-dc (+ 8 3 3)] ; 8 + proficiency + cha modifier + (is (= expected-dc (calculate-spell-save-dc sorcerer)))))) + +;; Then fix: +(defn calculate-spell-save-dc [character] + (let [casting-ability (get-casting-ability (:class character)) + ability-mod (ability-modifier + (get-in character [:abilities casting-ability])) + prof-bonus (proficiency-bonus (:level character))] + (+ 8 prof-bonus ability-mod))) +``` + +### Adding New Features + +**Feature Planning:** +1. Discuss the feature in an issue first +2. Consider how it fits with existing architecture +3. Plan the user interface and experience +4. Consider edge cases and error handling + +**Implementation Process:** +1. Start with the data model/backend logic +2. Add necessary database schema changes +3. Implement UI components +4. Add comprehensive tests +5. Update documentation + +### Adding D&D Content + +**Content Sources:** +- **Official D&D content only** - We cannot accept copyrighted material +- **System Reference Document (SRD)** content is acceptable +- **Open Game License (OGL)** content may be acceptable + +**Content Structure:** +```clojure +;; Example: Adding a new race +{:name "Dragonborn" + :key :dragonborn + :size :medium + :speed 30 + :languages #{:common :draconic} + :modifiers [(modifier ?str-bonus (+ ?str-bonus 2)) + (modifier ?cha-bonus (+ ?cha-bonus 1)) + (modifier ?damage-resistance + (conj ?damage-resistance damage-type))] + :selections [{:key :draconic-ancestry + :min 1 + :max 1 + :options draconic-ancestry-options}]} +``` + +### Documentation Improvements + +**Types of Documentation:** +- **Developer docs**: Setup guides, architecture explanations +- **User docs**: How to use the application +- **API docs**: Function documentation and examples +- **Troubleshooting**: Common issues and solutions + +**Documentation Standards:** +- Write for your audience (beginners vs experts) +- Include working code examples +- Test all instructions on a clean setup +- Keep language clear and concise + +## 🤝 Community Guidelines + +### Code of Conduct + +We are committed to providing a welcoming and inclusive environment: + +- **Be respectful** of different viewpoints and experiences +- **Be collaborative** and help others learn +- **Focus on the code**, not personal characteristics +- **Give constructive feedback** with specific suggestions +- **Ask questions** when you need help + +### Getting Help + +**Where to Ask Questions:** +- **GitHub Discussions**: General questions and discussions +- **GitHub Issues**: Bug reports and feature requests +- **Pull Request Comments**: Questions about specific code + +**How to Ask Good Questions:** +1. Search existing issues/discussions first +2. Provide context about what you're trying to do +3. Include error messages and code samples +4. Describe what you've already tried + +**Response Times:** +- Issues and PRs are typically reviewed within a few days +- Complex changes may take longer to review +- Be patient - maintainers are volunteers + +## 🎓 Learning Resources + +### Clojure Learning Path +1. **Basics**: [Clojure for the Brave and True](https://www.braveclojure.com/) +2. **Practice**: [4clojure](https://4clojure.oxal.org/) exercises +3. **Reference**: [ClojureDocs](https://clojuredocs.org/) +4. **Community**: [Clojure Slack](http://clojurians.net/) + +### re-frame Learning Path +1. **Tutorial**: [Official re-frame tutorial](https://day8.github.io/re-frame/) +2. **Examples**: Study the orcpub codebase +3. **Debugging**: Use re-frame-10x dev tools +4. **Patterns**: Learn subscription composition and event chains + +### D&D 5e Resources +1. **System Reference Document**: [Official SRD](https://dnd.wizards.com/resources/systems-reference-document) +2. **Rules Reference**: [Basic Rules PDF](https://dnd.wizards.com/products/tabletop/players-basic-rules) +3. **Community**: [r/DMAcademy](https://reddit.com/r/DMAcademy), [r/dndnext](https://reddit.com/r/dndnext) + +## 📊 Project Roadmap + +### Current Priorities +1. **Stability**: Fix existing bugs and improve test coverage +2. **Performance**: Optimize slow operations and large character sheets +3. **Usability**: Improve user interface and experience +4. **Mobile**: Better mobile browser support + +### Future Goals +1. **Additional Game Systems**: Support for other RPG systems +2. **Advanced Features**: Campaign management, party tracking +3. **Integration**: APIs for third-party tool integration +4. **Collaboration**: Real-time character sharing and editing + +## 🏆 Recognition + +Contributors are recognized in several ways: + +- **Commit Attribution**: Your contributions are permanently recorded in Git history +- **Release Notes**: Major contributions are mentioned in release notes +- **Contributors List**: Regular contributors may be added to a contributors file +- **Mentorship**: Experienced contributors can mentor newcomers + +--- + +**Ready to Contribute?** + +1. Set up your [development environment](getting-started.md) +2. Find a [good first issue](https://github.com/codeGlaze/orcpub/labels/good%20first%20issue) +3. Follow the [development workflow](development-workflow.md) +4. Submit your first pull request! + +**Questions?** Open an issue or start a discussion - we're here to help! \ No newline at end of file diff --git a/docs/development-workflow.md b/docs/development-workflow.md new file mode 100644 index 00000000..c76081ff --- /dev/null +++ b/docs/development-workflow.md @@ -0,0 +1,543 @@ +# Development Workflow + +This guide covers the daily development process, including building, testing, debugging, and common development tasks. It's designed for developers at all levels working on Dungeon Master's Vault. + +## Daily Development Process + +### 1. Starting Your Development Session + +**Preparation Steps:** +```bash +# Navigate to your project directory +cd orcpub + +# Pull latest changes from upstream +git fetch upstream +git checkout develop +git merge upstream/develop + +# Start your feature branch +git checkout -b feature/your-feature-name +``` + +**Start Development Servers:** + +*Terminal 1 - Database:* +```bash +# Start Datomic (keep running throughout session) +cd lib/datomic-free-0.9.5703 +bin/transactor config/samples/free-transactor-template.properties +``` + +*Terminal 2 - Backend REPL:* +```bash +# Start Clojure REPL with server +lein with-profile +start-server repl +``` +In the REPL: +```clojure +;; Initialize database (only needed once) +(init-database) + +;; Start web server +(start-server) +``` + +*Terminal 3 - Frontend Development:* +```bash +# Start ClojureScript compiler and dev server +lein figwheel +``` + +**Verify Setup:** +- Database running: Check terminal 1 for "System started" message +- Backend running: Visit [http://localhost:8890/health](http://localhost:8890/health) +- Frontend running: Main app at [http://localhost:8890](http://localhost:8890) + +### 2. Making Changes + +#### Backend Development (Clojure) + +**File Types and Locations:** +- **API endpoints**: `src/clj/orcpub/routes.clj` +- **Business logic**: `src/cljc/orcpub/dnd/e5/` +- **Database queries**: `src/clj/orcpub/datomic.clj` + +**Development Flow:** +1. Edit Clojure files in your editor +2. Save changes +3. Reload namespace in REPL: + ```clojure + ;; Reload a specific namespace + (require '[orcpub.routes :as routes] :reload) + + ;; Or reload all changed namespaces + (refresh) + ``` + +**Example: Adding a New API Endpoint** +```clojure +;; In src/clj/orcpub/routes.clj +(defn get-character-summary + [{:keys [path-params] :as request}] + (let [character-id (:character-id path-params) + character (db/get-character character-id)] + {:status 200 + :body {:name (:name character) + :level (:level character) + :class (:class character)}})) + +;; Add route +["/character/:character-id/summary" :get get-character-summary] +``` + +#### Frontend Development (ClojureScript) + +**File Types and Locations:** +- **UI components**: `src/cljs/orcpub/dnd/e5/views.cljs` +- **State management**: `src/cljs/orcpub/dnd/e5/events.cljs`, `src/cljs/orcpub/dnd/e5/subs.cljs` +- **Shared logic**: `src/cljc/orcpub/` + +**Development Flow:** +1. Edit ClojureScript files +2. Save changes +3. **Changes appear automatically** in browser (hot-reload) +4. Check browser console for any errors + +**Example: Adding a New UI Component** +```clojure +;; In src/cljs/orcpub/dnd/e5/views.cljs +(defn character-summary [character-id] + (let [character @(subscribe [:character/by-id character-id])] + [:div.character-summary + [:h3 (:name character)] + [:p "Level " (:level character) " " (:class character)]])) + +;; Add event handler in events.cljs +(reg-event-fx + :character/load-summary + (fn [{:keys [db]} [_ character-id]] + {:http-xhrio {:method :get + :uri (str "/api/character/" character-id "/summary") + :response-format (ajax/json-response-format) + :on-success [:character/summary-loaded]}})) + +;; Add subscription in subs.cljs +(reg-sub + :character/by-id + (fn [db [_ character-id]] + (get-in db [:characters character-id]))) +``` + +#### Shared Code Development (CLJC) + +Files with `.cljc` extension run on both client and server: + +**Example: Adding D&D Game Logic** +```clojure +;; In src/cljc/orcpub/dnd/e5/character.cljc +(defn calculate-proficiency-bonus [level] + (-> level + (dec) + (quot 4) + (+ 2))) + +(defn calculate-spell-attack-bonus [character] + (let [level (:level character) + ability-mod (:casting-ability-modifier character) + prof-bonus (calculate-proficiency-bonus level)] + (+ ability-mod prof-bonus))) +``` + +### 3. Testing Your Changes + +#### Running Tests + +**All Tests:** +```bash +lein test +``` + +**Specific Test Namespace:** +```bash +lein test orcpub.entity-spec +``` + +**Auto-running Tests (continuous):** +```bash +lein test-refresh +``` + +**Frontend Tests:** +```bash +# ClojureScript tests +lein doo phantom test once +``` + +#### Writing Tests + +**Backend Test Example:** +```clojure +;; In test/clj/orcpub/character_test.clj +(ns orcpub.character-test + (:require [clojure.test :refer :all] + [orcpub.dnd.e5.character :as char])) + +(deftest proficiency-bonus-test + (testing "proficiency bonus calculation" + (is (= 2 (char/calculate-proficiency-bonus 1))) + (is (= 3 (char/calculate-proficiency-bonus 5))) + (is (= 6 (char/calculate-proficiency-bonus 17))))) +``` + +**Frontend Test Example:** +```clojure +;; In test/cljs/orcpub/events_test.cljs +(ns orcpub.events-test + (:require [cljs.test :refer [deftest is testing]] + [orcpub.dnd.e5.events :as events])) + +(deftest character-creation-test + (testing "character creation event" + (let [initial-db {} + result (events/create-character initial-db [:character/create "Test Character"])] + (is (contains? (:db result) :current-character)) + (is (= "Test Character" (get-in (:db result) [:current-character :name])))))) +``` + +#### Manual Testing + +**Character Builder Testing Checklist:** +- [ ] Create a new character +- [ ] Select race and verify bonuses apply +- [ ] Select class and verify features appear +- [ ] Level up character and check spell progression +- [ ] Export PDF and verify formatting +- [ ] Save character and reload page + +**Browser Testing:** +- Test in multiple browsers (Chrome, Firefox, Safari) +- Test responsive design on mobile screens +- Check browser developer console for errors + +### 4. Code Quality and Style + +#### Code Formatting + +```bash +# Check formatting +lein cljfmt check + +# Auto-fix formatting +lein cljfmt fix +``` + +#### Linting + +```bash +# Run code analysis +lein kibit + +# Check for common issues +lein eastwood +``` + +#### Style Guidelines + +**Clojure/ClojureScript Style:** +- Use kebab-case for function and variable names +- Use meaningful names that describe purpose +- Keep functions small and focused +- Prefer pure functions over stateful ones + +**Example of Good Style:** +```clojure +(defn calculate-armor-class + "Calculates AC from base AC, dex modifier, and magical bonuses." + [base-ac dex-modifier magical-bonuses] + (+ base-ac + (min dex-modifier 2) ; Dex modifier capped at +2 for most armor + (apply + magical-bonuses))) +``` + +**re-frame Style:** +- Use descriptive event names with namespaces +- Keep event handlers pure (no side effects) +- Use subscriptions for all data queries +- Group related events, subs, and views in same files + +## Building and Deployment + +### Development Builds + +**ClojureScript Development:** +```bash +# Running via figwheel (recommended) +lein figwheel + +# Manual compilation +lein cljsbuild once dev +``` + +**CSS Compilation:** +```bash +# Generate CSS from Garden +lein garden once +``` + +### Production Builds + +**Create Production JAR:** +```bash +# Clean and build for production +lein clean +lein garden once +lein cljsbuild once prod +lein uberjar +``` + +**Docker Build:** +```bash +# Build Docker image +docker-compose build + +# Run production containers +docker-compose up -d +``` + +### Performance Testing + +**Load Testing:** +```bash +# Use Apache Bench for simple load testing +ab -n 1000 -c 10 http://localhost:8890/ + +# Or use more sophisticated tools like wrk +wrk -t12 -c400 -d30s http://localhost:8890/ +``` + +## Debugging + +### Backend Debugging + +**REPL Debugging:** +```clojure +;; Add breakpoints with println +(defn problematic-function [input] + (println "Debug: input is" input) + (let [result (complex-calculation input)] + (println "Debug: result is" result) + result)) + +;; Inspect database state +(d/q '[:find ?e ?name + :where [?e :character/name ?name]] + (d/db conn)) + +;; Test functions interactively +(calculate-armor-class 12 3 [2 1]) +``` + +**Exception Handling:** +```clojure +(try + (risky-operation) + (catch Exception e + (log/error e "Operation failed") + {:error (.getMessage e)})) +``` + +### Frontend Debugging + +**Browser Developer Tools:** +- Use React DevTools for component inspection +- Check Network tab for HTTP requests +- Use Console for ClojureScript debugging + +**re-frame-10x (Debugging Tool):** +```clojure +;; Add to dev dependencies in project.clj +[day8.re-frame/re-frame-10x "0.3.7"] + +;; Enable in development builds +:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true} +``` + +**Debug Subscriptions:** +```clojure +;; Add debug prints to subscriptions +(reg-sub + :debug/character-state + (fn [db _] + (let [character (:current-character db)] + (println "Debug: current character is" character) + character))) +``` + +### Common Issues and Solutions + +#### "Port already in use" +```bash +# Find process using port +lsof -i :8890 +kill -9 [PID] + +# Or change port in project.clj +:figwheel {:server-port 3450} +``` + +#### "Connection refused to database" +```bash +# Check if Datomic is running +ps aux | grep transactor + +# Restart Datomic transactor +cd lib/datomic-free-0.9.5703 +bin/transactor config/samples/free-transactor-template.properties +``` + +#### "Figwheel not connecting" +1. Check if port 3449 is available +2. Clear browser cache +3. Restart figwheel +4. Check firewall settings + +#### "Cannot resolve symbol" in ClojureScript +1. Check namespace requires +2. Ensure symbols are properly exported +3. Check spelling and capitalization +4. Restart figwheel compilation + +### Git Workflow + +#### Feature Development +```bash +# Create feature branch from develop +git checkout develop +git pull upstream develop +git checkout -b feature/new-spell-system + +# Make commits +git add . +git commit -m "Add spell slot calculation logic" + +# Push to your fork +git push origin feature/new-spell-system + +# Create pull request via GitHub +``` + +#### Code Review Process + +**Before Submitting PR:** +- [ ] All tests pass: `lein test` +- [ ] Code is formatted: `lein cljfmt check` +- [ ] No linting issues: `lein kibit` +- [ ] Manual testing completed +- [ ] Documentation updated if needed + +**PR Template:** +```markdown +## Description +Brief description of changes + +## Testing +- [ ] Unit tests added/updated +- [ ] Manual testing completed +- [ ] Browser testing (Chrome, Firefox) + +## Checklist +- [ ] Tests pass +- [ ] Code formatted +- [ ] Documentation updated +``` + +## Performance Optimization + +### Frontend Performance + +**ClojureScript Bundle Size:** +```bash +# Analyze bundle size +lein cljsbuild once prod +wc -c resources/public/js/compiled/orcpub.js +``` + +**React Performance:** +- Use `reagent.core/with-let` for expensive computations +- Implement `should-component-update` for large lists +- Use `re-frame` subscriptions efficiently + +### Backend Performance + +**Database Query Optimization:** +```clojure +;; Use specific queries instead of pulling whole entities +[:find ?name ?level + :in $ ?character-id + :where + [?e :character/id ?character-id] + [?e :character/name ?name] + [?e :character/level ?level]] +``` + +**Caching:** +```clojure +;; Cache expensive calculations +(def spell-list-cache (atom {})) + +(defn get-spell-list [class level] + (if-let [cached (@spell-list-cache [class level])] + cached + (let [spells (calculate-spell-list class level)] + (swap! spell-list-cache assoc [class level] spells) + spells))) +``` + +## Troubleshooting + +### Build Issues + +**Dependencies Not Downloading:** +```bash +# Clear local repository +rm -rf ~/.m2/repository +lein clean +lein deps +``` + +**ClojureScript Compilation Errors:** +1. Check for syntax errors in `.cljs` files +2. Verify all required namespaces are available +3. Clear compiled output: `lein clean` +4. Restart figwheel + +**CSS Not Updating:** +```bash +# Recompile CSS +lein garden once + +# Check if Garden is watching files +lein garden auto +``` + +### Runtime Issues + +**Characters Not Saving:** +1. Check browser network tab for failed requests +2. Verify database connection +3. Check server logs for errors +4. Test with simple curl request + +**UI Not Updating:** +1. Check browser console for JavaScript errors +2. Verify re-frame events are firing +3. Check subscription queries +4. Use re-frame-10x for debugging + +--- + +**Next Steps:** +- Review our [Contributing Guide](contributing.md) before submitting changes +- Explore advanced topics in our [Technology Overview](technology-overview.md) +- Join the community discussion in GitHub Issues \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 00000000..268bfac1 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,346 @@ +# Getting Started + +This guide will walk you through setting up your development environment for Dungeon Master's Vault, with detailed instructions for developers new to the Clojure ecosystem. + +## Prerequisites + +### System Requirements + +- **Operating System**: Windows 10+, macOS 10.14+, or Linux +- **Memory**: 4GB RAM minimum, 8GB recommended +- **Disk Space**: 2GB for development tools and dependencies +- **Network**: Internet connection for downloading dependencies + +### Required Tools + +#### 1. Java Development Kit (JDK) + +Clojure runs on the Java Virtual Machine (JVM), so you need Java installed. + +**For macOS:** +```bash +# Using Homebrew (recommended) +brew install openjdk@11 + +# Or download from Oracle/OpenJDK websites +``` + +**For Windows:** +```bash +# Using Chocolatey (recommended) +choco install openjdk11 + +# Or download from https://adoptium.net/ +``` + +**For Linux (Ubuntu/Debian):** +```bash +sudo apt update +sudo apt install openjdk-11-jdk +``` + +**Verify Installation:** +```bash +java -version +# Should show Java 11 or higher +``` + +#### 2. Git + +Required for version control and downloading the project. + +**Installation:** +- **Windows**: Download from [git-scm.com](https://git-scm.com/download/win) +- **macOS**: `brew install git` or use Xcode Command Line Tools +- **Linux**: `sudo apt install git` (Ubuntu/Debian) + +**Verify Installation:** +```bash +git --version +``` + +#### 3. Leiningen (Clojure Build Tool) + +Leiningen is the standard build tool for Clojure projects. + +**For macOS/Linux:** +```bash +# Download the lein script +curl -O https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein + +# Make it executable +chmod +x lein + +# Move to your PATH +sudo mv lein /usr/local/bin/ + +# Test installation (this will download Leiningen) +lein version +``` + +**For Windows:** +```bash +# Using Chocolatey +choco install lein + +# Or download lein.bat from https://leiningen.org/ +``` + +**What is Leiningen?** +Leiningen handles: +- Dependency management (like npm for Node.js) +- Compilation of Clojure/ClojureScript code +- Running development servers and REPLs +- Testing and packaging + +#### 4. Node.js (Optional, for some development tools) + +Some ClojureScript development tools use Node.js. + +**Installation:** +- Download from [nodejs.org](https://nodejs.org/) (LTS version) +- Or use a package manager: `brew install node` (macOS), `choco install nodejs` (Windows) + +#### 5. Code Editor/IDE + +Choose one based on your preference: + +**For Beginners:** +- **VS Code** with [Calva extension](https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.calva) + - Free, easy to set up + - Good Clojure support out of the box + - Integrated REPL + +**For Advanced Users:** +- **IntelliJ IDEA** with [Cursive plugin](https://cursive-ide.com/) + - Professional IDE experience + - Excellent debugging and refactoring tools + +- **Emacs** with [CIDER](https://cider.mx/) + - Traditional Lisp development environment + - Very powerful but steeper learning curve + +- **Vim** with [vim-fireplace](https://github.com/tpope/vim-fireplace) + - Lightweight, terminal-based + +## Project Setup + +### 1. Fork and Clone the Repository + +**Fork the Project:** +1. Go to [https://github.com/codeGlaze/orcpub](https://github.com/codeGlaze/orcpub) +2. Click the "Fork" button to create your own copy + +**Clone Your Fork:** +```bash +# Replace 'yourusername' with your GitHub username +git clone https://github.com/yourusername/orcpub.git +cd orcpub + +# Add the original repository as upstream +git remote add upstream https://github.com/codeGlaze/orcpub.git +``` + +### 2. Install Dependencies + +The project uses Leiningen to manage dependencies automatically: + +```bash +# This will download all required Clojure dependencies +lein deps + +# This may take several minutes on the first run +``` + +**What happens during `lein deps`:** +- Downloads Clojure and ClojureScript compilers +- Installs web framework dependencies (Pedestal, Ring) +- Downloads UI libraries (Reagent, re-frame) +- Installs database dependencies (Datomic) + +### 3. Set Up Datomic Database + +Datomic is the database used to store character data. + +**Download Datomic Free:** +```bash +# Create a lib directory for Datomic +mkdir -p lib + +# Download Datomic Free (Linux/macOS) +cd lib +curl -O https://github.com/Orcpub/orcpub/raw/develop/lib/datomic-free-0.9.5703.tar.gz +tar -xzf datomic-free-0.9.5703.tar.gz +cd .. +``` + +**For Windows:** +Download the file manually and extract to `lib/datomic-free-0.9.5703/` + +**Start Datomic Transactor:** + +*Linux/macOS:* +```bash +cd lib/datomic-free-0.9.5703 +bin/transactor config/samples/free-transactor-template.properties +``` + +*Windows:* +```cmd +cd lib\datomic-free-0.9.5703 +bin\transactor config\samples\free-transactor-template.properties +``` + +**Leave this running** - it's your database server. + +## Development Environment Setup + +### 1. Start the Development REPL + +The REPL (Read-Eval-Print Loop) is your interactive development environment: + +```bash +# From the project root directory +lein with-profile +start-server repl +``` + +**What is a REPL?** +- Interactive programming environment +- Allows you to test code immediately +- Modify running programs without restarting +- Essential for Clojure development + +### 2. Initialize the Database + +In your REPL, run these commands once: + +```clojure +;; Initialize the database schema +(init-database) + +;; Start the web server +(start-server) +``` + +### 3. Start the Frontend Development Server + +Open a **new terminal** while keeping the REPL running: + +```bash +# This starts the ClojureScript compiler and dev server +lein figwheel +``` + +**What is Figwheel?** +- Compiles ClojureScript to JavaScript +- Provides hot-reloading (changes appear instantly in browser) +- Creates a browser-connected REPL for interactive development + +### 4. Access the Application + +After both servers are running: +- Open your browser to [http://localhost:8890](http://localhost:8890) +- You should see the Dungeon Master's Vault interface + +## Development Workflow + +### Making Changes + +1. **Backend Changes** (Clojure files in `src/clj/`): + - Edit files in your editor + - Save the file + - In the REPL, reload the namespace: `(require '[your.namespace :as ns] :reload)` + +2. **Frontend Changes** (ClojureScript files in `src/cljs/`): + - Edit files in your editor + - Save the file + - Changes appear automatically in browser (hot-reloading) + +### Testing Your Changes + +```bash +# Run all tests +lein test + +# Run specific test namespaces +lein test orcpub.entity-spec +``` + +### Code Formatting + +```bash +# Check code formatting +lein cljfmt check + +# Auto-format code +lein cljfmt fix +``` + +## Common Issues and Troubleshooting + +### Issue: "Could not find artifact" errors + +**Problem**: Dependency download failures +**Solution**: +```bash +# Clear your local Maven cache and retry +rm -rf ~/.m2/repository +lein clean +lein deps +``` + +### Issue: "Port 8890 already in use" + +**Problem**: Previous development server still running +**Solution**: +```bash +# Find and kill the process using port 8890 +lsof -i :8890 # macOS/Linux +netstat -ano | findstr :8890 # Windows + +# Or change the port in project.clj +``` + +### Issue: Browser shows "Connection refused" + +**Problem**: Web server not started +**Solution**: +1. Make sure REPL is running +2. Run `(start-server)` in the REPL +3. Check that Datomic transactor is running + +### Issue: Database errors + +**Problem**: Datomic not accessible +**Solution**: +1. Ensure Datomic transactor is running +2. Run `(init-database)` in REPL if it's a fresh setup +3. Check database URL in configuration + +## Next Steps + +Now that your development environment is set up: + +1. **Explore the Code**: Check out our [Source File Guide](source-guide.md) +2. **Learn the Technologies**: Read our [Technology Overview](technology-overview.md) +3. **Make Your First Change**: See our [Development Workflow](development-workflow.md) +4. **Contribute**: Review our [Contributing Guide](contributing.md) + +## Learning Resources + +### Clojure Learning +- [Clojure for the Brave and True](https://www.braveclojure.com/) - Beginner-friendly book +- [4clojure](https://4clojure.oxal.org/) - Interactive Clojure exercises +- [ClojureDocs](https://clojuredocs.org/) - Function documentation and examples + +### ClojureScript & Web Development +- [ClojureScript Unraveled](https://funcool.github.io/clojurescript-unraveled/) - Comprehensive guide +- [Reagent Documentation](https://reagent-project.github.io/) - React in ClojureScript +- [re-frame Documentation](https://day8.github.io/re-frame/) - Application state management + +--- + +**Need Help?** +- Check our [Troubleshooting Guide](development-workflow.md#troubleshooting) +- Ask questions in [GitHub Issues](https://github.com/codeGlaze/orcpub/issues) +- Review existing documentation in the [docs](index.md) folder \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..b6fa52f2 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,44 @@ +# Dungeon Master's Vault - Developer Documentation + +Welcome to the developer documentation for Dungeon Master's Vault, a community-maintained D&D 5e character sheet generator built with Clojure and ClojureScript. + +## Documentation Overview + +This documentation is designed to help developers of all skill levels contribute to the project, with special attention to those new to the Clojure ecosystem. + +### 📚 Documentation Sections + +- **[Project Overview](project-overview.md)** - Learn about orcpub's purpose, features, and architecture +- **[Getting Started](getting-started.md)** - Complete setup guide for new developers +- **[Technology Overview](technology-overview.md)** - Introduction to Clojure, ClojureScript, Reagent, and re-frame +- **[Source File Guide](source-guide.md)** - Navigate the codebase and understand major components +- **[Development Workflow](development-workflow.md)** - Daily development tasks, building, and testing +- **[Contributing Guide](contributing.md)** - How to contribute, coding standards, and getting help + +### 🚀 Quick Start + +If you're new here and want to get started quickly: + +1. Start with the [Technology Overview](technology-overview.md) to understand the tech stack +2. Follow the [Getting Started](getting-started.md) guide to set up your development environment +3. Review the [Source File Guide](source-guide.md) to understand the codebase structure +4. Check the [Contributing Guide](contributing.md) before making your first contribution + +### 💡 For Clojure Newcomers + +This project is a great way to learn Clojure and ClojureScript! The documentation includes: + +- Links to learning resources for Clojure concepts +- Explanations of functional programming patterns used in the codebase +- Step-by-step setup instructions that don't assume prior Clojure experience +- Code examples and explanations of key architectural patterns + +### 🔗 Additional Resources + +- [Main README](../README.md) - Deployment and Docker setup instructions +- [Project Issues](https://github.com/codeGlaze/orcpub/issues) - Bug reports and feature requests +- [Contributing Guidelines](contributing.md) - Detailed contribution workflow + +--- + +*This documentation is maintained by the community. If you find errors or have suggestions for improvement, please [open an issue](https://github.com/codeGlaze/orcpub/issues) or submit a pull request.* \ No newline at end of file diff --git a/docs/project-overview.md b/docs/project-overview.md new file mode 100644 index 00000000..068e379c --- /dev/null +++ b/docs/project-overview.md @@ -0,0 +1,131 @@ +# Project Overview + +## What is Dungeon Master's Vault? + +Dungeon Master's Vault (formerly OrcPub2) is a web-based D&D 5th Edition character sheet generator and management system. It provides players and dungeon masters with powerful tools to create, customize, and manage D&D characters through an intuitive web interface. + +## Key Features + +### 🎲 Character Creation & Management +- **Interactive Character Builder**: Step-by-step character creation with real-time validation +- **Complete D&D 5e Support**: Races, classes, backgrounds, spells, equipment, and more +- **Character Sheet PDF Export**: Generate professional character sheets for offline play +- **Cloud Storage**: Save and manage multiple characters online +- **Party Management**: Organize characters into adventuring parties + +### 🎨 User Experience +- **Responsive Design**: Works seamlessly on desktop, tablet, and mobile devices +- **Real-time Updates**: Character changes are reflected immediately +- **Intuitive Interface**: Clean, user-friendly design that guides new players +- **Spell Management**: Organized spellbook with filtering and search capabilities + +### 🛠 Technical Features +- **Plugin Architecture**: Extensible system for adding custom content (homebrew) +- **RESTful API**: Programmatic access to character data +- **Multi-user Support**: User accounts, authentication, and data isolation +- **Docker Deployment**: Easy self-hosting with containerization + +## Project History + +Dungeon Master's Vault is a community fork of OrcPub2, originally created by Larry Christensen. The project was forked in January 2019 to ensure continued development and community maintenance after the original project became inactive. + +### Key Milestones +- **2019**: Community fork created from original OrcPub2 codebase +- **2019-2024**: Ongoing community development, bug fixes, and improvements +- **Present**: Active open-source project with Docker deployment support + +## Architecture Overview + +### High-Level Architecture + +``` +┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ +│ Web Browser │◄──►│ Clojure Server │◄──►│ Datomic DB │ +│ (ClojureScript)│ │ (Pedestal) │ │ (Character │ +│ + Reagent │ │ │ │ Data) │ +└─────────────────┘ └──────────────────┘ └─────────────────┘ +``` + +### Technology Stack + +**Frontend (Client-side)** +- **ClojureScript**: Compiled to JavaScript, runs in browser +- **Reagent**: React wrapper for ClojureScript UI components +- **re-frame**: State management and event handling framework + +**Backend (Server-side)** +- **Clojure**: JVM-based functional programming language +- **Pedestal**: Web application framework for HTTP services +- **Ring**: HTTP server abstraction layer + +**Data & Storage** +- **Datomic**: Immutable database for character and game data +- **Transit**: Data serialization between client and server + +## Core Concepts + +### Entity-Modifier System + +The application is built around a sophisticated **entity-modifier architecture** that models how D&D character building actually works: + +**Entities** represent characters as collections of hierarchical choices: +```clojure +{:options {:race {:key :elf + :options {:subrace {:key :high-elf}}}}} +``` + +**Modifiers** apply effects from character options: +```clojure +{:modifiers [(modifier ?dex-bonus (+ ?dex-bonus 2)) + (modifier ?race "Elf")]} +``` + +**Built Characters** are the final result of applying all modifiers: +```clojure +{:race "Elf" + :subrace "High Elf" + :dex-bonus 2} +``` + +This architecture provides several advantages: +- **Traceability**: Always know which options created which bonuses +- **Extensibility**: Easy to add new content without changing core logic +- **Maintainability**: No central calculation functions that become unmaintainable +- **Flexibility**: Rules can override and modify other rules dynamically + +### Plugin System + +The modifier system enables a powerful plugin architecture where new content can be added as data rather than code changes. This allows for: +- **Official Content**: Support for published D&D books +- **Homebrew Content**: User-created races, classes, spells, etc. +- **House Rules**: Campaign-specific modifications and additions + +## Project Goals + +### Primary Objectives +1. **Accessibility**: Make D&D character creation accessible to new and experienced players +2. **Community**: Provide a self-hostable alternative to commercial tools +3. **Extensibility**: Support homebrew and custom content through data-driven architecture +4. **Education**: Serve as an example of functional programming in web applications + +### Technical Goals +1. **Maintainability**: Clean, functional architecture that's easy to understand and modify +2. **Performance**: Efficient client-server communication and responsive UI +3. **Reliability**: Robust error handling and data persistence +4. **Scalability**: Support for multiple users and large amounts of game content + +## Getting Involved + +Whether you're interested in: +- Adding new D&D content or features +- Learning Clojure and functional programming +- Improving documentation and user experience +- Testing and reporting bugs + +There are opportunities to contribute at all skill levels. See our [Contributing Guide](contributing.md) to learn more about getting involved in the project. + +--- + +**Next Steps**: +- Set up your development environment with our [Getting Started](getting-started.md) guide +- Learn about the technologies used in our [Technology Overview](technology-overview.md) \ No newline at end of file diff --git a/docs/source-guide.md b/docs/source-guide.md new file mode 100644 index 00000000..f1879170 --- /dev/null +++ b/docs/source-guide.md @@ -0,0 +1,380 @@ +# Source File Guide + +This guide provides a comprehensive overview of the orcpub codebase structure, explaining the purpose and organization of major files and directories. Understanding this structure will help you navigate the code and contribute effectively. + +## Project Structure Overview + +``` +orcpub/ +├── src/ +│ ├── clj/ # Server-side Clojure code +│ ├── cljc/ # Shared code (client & server) +│ └── cljs/ # Client-side ClojureScript code +├── web/cljs/ # Additional frontend code +├── resources/ # Static assets, config files +├── test/ # Test files +├── dev/ # Development utilities +└── docs/ # Project documentation +``` + +## Code Organization Principles + +### By File Extension +- **`.clj`** - Server-only Clojure code (JVM) +- **`.cljs`** - Client-only ClojureScript code (Browser) +- **`.cljc`** - Cross-platform code (both JVM and Browser) + +### By Functionality +- **Infrastructure** - Web servers, database, routing, authentication +- **Game Logic** - D&D rules, character building, calculations +- **UI Components** - User interface, forms, displays +- **Data Models** - Character templates, rules definitions + +## Directory Deep Dive + +### `src/clj/orcpub/` - Server-Side Code + +The server-side code handles HTTP requests, database operations, authentication, and business logic that shouldn't run in the browser. + +#### Core Infrastructure Files + +**`server.clj`** - Application entry point +```clojure +(defn -main [] + (component/start (s/system :prod))) +``` +- Application bootstrap and main entry point +- Starts the web server and all components + +**`system.clj`** - Component system configuration +- Defines application components (database, web server, etc.) +- Manages component lifecycle and dependencies +- Uses Stuart Sierra's Component library + +**`pedestal.clj`** - HTTP service configuration +- Configures Pedestal web framework +- Defines interceptors for request processing +- Sets up routes and middleware + +**`routes.clj`** - HTTP route definitions +- API endpoints for character operations +- Authentication routes +- Static file serving + +#### Database & Persistence + +**`datomic.clj`** - Database connection and utilities +- Datomic database connection management +- Query helpers and database utilities +- Transaction functions + +**`db/schema.clj`** - Database schema definitions +- Datomic schema for characters, users, etc. +- Entity relationships and constraints +- Migration functions + +#### Business Logic + +**`pdf.clj`** - PDF generation +- Character sheet PDF creation +- Uses Apache PDFBox for PDF manipulation +- Renders character data into printable forms + +**`email.clj`** - Email utilities +- User registration emails +- Password reset functionality +- Error notification emails + +#### Security & Authentication + +**`oauth.clj`** - OAuth authentication +- Third-party login integration +- Token management +- User session handling + +**`security.clj`** - Security middleware +- Authentication checks +- Authorization logic +- CSRF protection + +**`privacy.clj`** - Privacy and terms handling +- Privacy policy management +- Terms of service +- User consent tracking + +#### UI Server-Side Rendering + +**`index.clj`** - Main HTML page generation +- Generates the initial HTML page +- Includes ClojureScript application +- Sets up client-side configuration + +**`styles/core.clj`** - CSS generation +- Uses Garden library for CSS +- Programmatic stylesheet generation +- Component-specific styling + +### `src/cljc/orcpub/` - Shared Code + +Code that runs on both client and server, primarily game logic and data structures. + +#### Core Entity System + +**`entity.cljc`** - Core entity-building engine +```clojure +(defn build-entity [raw-entity template] + ;; Applies modifiers to create computed character + ) +``` +- The heart of the character building system +- Applies modifiers to create final character state +- Handles dependency resolution between modifiers + +**`entity_spec.cljc`** - Entity validation +- Clojure specs for entity data structures +- Validation of character data +- Type checking and constraints + +**`modifiers.cljc`** - Modifier system implementation +- Defines how modifiers work +- Modifier application logic +- Dependency graph resolution + +**`template.cljc`** - Character option templates +- Template parsing and processing +- Option selection validation +- Template merging and inheritance + +#### D&D 5e Game Rules + +**`dnd/e5/character.cljc`** - Core character logic +- Character creation and advancement +- Ability score calculations +- Level-up mechanics + +**`dnd/e5/races.cljc`** - Race definitions +```clojure +{:name "Elf" + :key :elf + :modifiers [(modifier ?dex-bonus (+ ?dex-bonus 2))] + :selections [...]} +``` +- All D&D races with their bonuses and features +- Subrace options and modifiers +- Racial spell lists and proficiencies + +**`dnd/e5/classes.cljc`** - Class definitions +- All D&D classes and subclasses +- Class features by level +- Spell progressions and abilities + +**`dnd/e5/backgrounds.cljc`** - Background definitions +- Character backgrounds with skills and equipment +- Background features and roleplay hooks + +**`dnd/e5/spells.cljc`** - Spell definitions +- Complete D&D spell list +- Spell descriptions, components, and mechanics + +**`dnd/e5/equipment.cljc`** - Equipment and items +- Weapons, armor, and adventuring gear +- Equipment stats and properties + +**`dnd/e5/feats.cljc`** - Feat definitions +- Optional feats with prerequisites +- Feat bonuses and special abilities + +#### UI Components & Utilities + +**`components.cljc`** - Reusable UI components +- Form inputs, buttons, modals +- Shared component logic +- Style utilities + +**`common.cljc`** - Common utilities +- Helper functions used throughout the app +- Data transformation utilities +- Validation helpers + +**`dice.cljc`** - Dice rolling mechanics +- Dice notation parsing ("2d6+3") +- Random number generation +- Dice roll statistics + +### `src/cljs/orcpub/` - Client-Side Code + +ClojureScript code that runs in the browser, handling UI, user interactions, and client-side state. + +#### Main Application + +**`dnd/e5.cljc`** - Main D&D 5e application entry +- Application initialization +- Route configuration +- Global event handlers + +**`character_builder.cljs`** - Character builder UI +- Step-by-step character creation interface +- Option selection forms +- Real-time character preview + +#### re-frame Architecture + +**`dnd/e5/events.cljs`** - Event handlers +```clojure +(reg-event-db + :character/update-race + (fn [db [_ race-key]] + (assoc-in db [:current-character :race] race-key))) +``` +- All application events +- State update logic +- Side effect coordination + +**`dnd/e5/subs.cljs`** - Subscriptions (queries) +```clojure +(reg-sub + :character/current-level + (fn [db _] + (get-in db [:current-character :level]))) +``` +- Data queries for UI components +- Computed properties and derived state +- Performance optimizations + +**`dnd/e5/db.cljs`** - Database schema +- Client-side application state structure +- Initial state definition +- State validation schemas + +**`dnd/e5/views.cljs`** - UI components +- Main character sheet display +- Form inputs and controls +- Navigation and layout components + +#### Specialized Subscriptions + +**`dnd/e5/equipment_subs.cljs`** - Equipment-specific queries +- Equipment lists and filtering +- Inventory management +- Equipment stat calculations + +**`dnd/e5/spell_subs.cljs`** - Spell-specific queries +- Spell lists by class and level +- Known spells and spell slots +- Spell filtering and search + +#### Development Tools + +**`dnd/e5/autosave_fx.cljs`** - Autosave functionality +- Automatic character saving +- Debounced save operations +- Error handling for save failures + +**`user_agent.cljs`** - Browser detection +- User agent parsing +- Browser capability detection +- Mobile/desktop detection + +## Key Architectural Patterns + +### Entity-Modifier Pattern + +The core of orcpub's architecture is the entity-modifier system: + +1. **Templates** define available options (races, classes, etc.) +2. **Entities** represent character choices as hierarchical selections +3. **Modifiers** from selected options are applied to create final character +4. **Built Characters** are the computed result with all bonuses applied + +### re-frame Pattern (Client-Side) + +The frontend follows re-frame's unidirectional data flow: + +1. **Events** represent user actions or system events +2. **Event Handlers** update application state +3. **Subscriptions** query state for UI display +4. **Views** render UI based on subscription data + +### Component System (Server-Side) + +The server uses Stuart Sierra's Component pattern: + +1. **Components** have start/stop lifecycle +2. **Dependencies** are injected at startup +3. **System** orchestrates component initialization +4. **Reloaded workflow** enables REPL-driven development + +## Data Flow Examples + +### Character Creation Flow + +1. User selects race in UI (`views.cljs`) +2. Dispatches `:character/select-race` event (`events.cljs`) +3. Event handler updates application state (`db.cljs`) +4. Subscription queries updated character data (`subs.cljs`) +5. UI re-renders with new race bonuses (`views.cljs`) +6. Entity system computes final stats (`entity.cljc`) + +### Character Save Flow + +1. Auto-save triggers save event (`autosave_fx.cljs`) +2. Character data serialized to Transit format +3. HTTP request sent to server (`routes.cljs`) +4. Server validates and stores in Datomic (`datomic.clj`) +5. Success/failure response returned to client +6. UI shows save status indicator + +## Common Development Tasks + +### Adding a New Race + +1. **Define race data** in `dnd/e5/races.cljc` +2. **Add modifiers** for racial bonuses +3. **Update templates** if needed +4. **Test with character builder** + +### Adding a New UI Component + +1. **Create component function** in appropriate views file +2. **Add subscriptions** if needing app state +3. **Add event handlers** for user interactions +4. **Style with Garden CSS** in `styles/core.clj` + +### Adding a New API Endpoint + +1. **Define route** in `routes.clj` +2. **Create handler function** with business logic +3. **Add database queries** if needed +4. **Update client-side HTTP calls** + +## Testing Strategy + +### Test Organization +- `test/clj/` - Server-side tests +- `test/cljc/` - Shared logic tests +- `test/cljs/` - Client-side tests + +### Key Test Areas +- **Entity building** - Core character logic +- **Modifier application** - Rules engine +- **HTTP APIs** - Server endpoints +- **UI components** - User interface + +## Development Tools Integration + +### REPL Integration +- **Server REPL** - `lein with-profile +start-server repl` +- **Client REPL** - Available through Figwheel +- **Component reloading** - Modify running system without restart + +### Hot Reloading +- **Server code** - Requires REPL reload +- **Client code** - Automatic via Figwheel +- **CSS** - Live updates via Garden + +--- + +**Next Steps:** +- Learn the daily development workflow in [Development Workflow](development-workflow.md) +- Understand how to contribute in [Contributing Guide](contributing.md) +- Practice with the [Getting Started](getting-started.md) setup guide \ No newline at end of file diff --git a/docs/technology-overview.md b/docs/technology-overview.md new file mode 100644 index 00000000..c5eaa147 --- /dev/null +++ b/docs/technology-overview.md @@ -0,0 +1,407 @@ +# Technology Overview + +This document provides an introduction to the technologies used in Dungeon Master's Vault, with special focus on helping developers new to the Clojure ecosystem understand the stack. + +## Technology Stack Overview + +### Architecture Layers + +``` +┌─────────────────────────────────────┐ +│ Browser (Client) │ +│ ┌─────────────┐ ┌─────────────────┐ │ +│ │ Reagent │ │ re-frame │ │ +│ │ (React UI) │ │ (State Mgmt) │ │ +│ └─────────────┘ └─────────────────┘ │ +│ ┌─────────────────────────────────┐ │ +│ │ ClojureScript │ │ +│ │ (Functional Frontend) │ │ +│ └─────────────────────────────────┘ │ +└─────────────────────────────────────┘ + │ + HTTP/Transit + │ +┌─────────────────────────────────────┐ +│ Server (JVM) │ +│ ┌─────────────┐ ┌─────────────────┐ │ +│ │ Pedestal │ │ Ring │ │ +│ │ (Web App) │ │ (HTTP Server) │ │ +│ └─────────────┘ └─────────────────┘ │ +│ ┌─────────────────────────────────┐ │ +│ │ Clojure │ │ +│ │ (Functional Backend) │ │ +│ └─────────────────────────────────┘ │ +└─────────────────────────────────────┘ + │ + Database + │ +┌─────────────────────────────────────┐ +│ Datomic │ +│ (Immutable Database) │ +└─────────────────────────────────────┘ +``` + +## Core Technologies + +### 1. Clojure + +**What is Clojure?** +Clojure is a functional programming language that runs on the Java Virtual Machine (JVM). It emphasizes immutability, functional composition, and interactive development. + +**Key Characteristics:** +- **Functional Programming**: Functions are first-class citizens, emphasis on pure functions +- **Immutable Data**: Data structures don't change, preventing many classes of bugs +- **Lisp Syntax**: Code is data (homoiconicity), enabling powerful macros +- **JVM Integration**: Access to Java libraries and mature JVM ecosystem +- **REPL-driven Development**: Interactive programming for rapid feedback + +**Example Clojure Code:** +```clojure +;; Define a function to calculate ability modifier +(defn ability-modifier [ability-score] + (-> ability-score + (- 10) + (/ 2) + (Math/floor) + (int))) + +;; Use the function +(ability-modifier 16) ;; => 3 + +;; Data transformation with threading macro +(-> {:strength 16, :dexterity 14} + (update :strength ability-modifier) + (update :dexterity ability-modifier)) +;; => {:strength 3, :dexterity 2} +``` + +**Why Clojure for orcpub?** +- **Immutable data** prevents character state bugs +- **Functional approach** makes complex D&D rules easier to compose +- **Interactive development** enables rapid iteration on game mechanics +- **Java ecosystem** provides access to PDF generation, web servers, etc. + +**Learning Resources:** +- [Clojure Official Guide](https://clojure.org/guides/getting_started) +- [Clojure for the Brave and True](https://www.braveclojure.com/) +- [Living Clojure](https://www.oreilly.com/library/view/living-clojure/9781491909270/) + +### 2. ClojureScript + +**What is ClojureScript?** +ClojureScript compiles Clojure code to JavaScript, allowing you to use Clojure's syntax and functional programming on the frontend. + +**Key Benefits:** +- **Same Language**: Frontend and backend use the same syntax and concepts +- **Google Closure Compiler**: Advanced optimizations and dead code elimination +- **React Integration**: Seamless integration with React ecosystem +- **Functional UI**: Immutable state makes UI behavior predictable + +**Example ClojureScript Code:** +```clojure +;; Component definition with Reagent +(defn character-name-input [character] + [:div.form-group + [:label "Character Name:"] + [:input {:type "text" + :value (:name character) + :on-change #(dispatch [:character/update-name + (-> % .-target .-value)])}]]) + +;; Event handling with re-frame +(reg-event-db + :character/update-name + (fn [db [_ new-name]] + (assoc-in db [:current-character :name] new-name))) +``` + +**Compilation Process:** +1. ClojureScript source → Google Closure Compiler +2. Dead code elimination and optimization +3. Single JavaScript bundle or advanced compilation + +**Learning Resources:** +- [ClojureScript Quick Start](https://clojurescript.org/guides/quick-start) +- [ClojureScript Unraveled](https://funcool.github.io/clojurescript-unraveled/) + +### 3. Reagent + +**What is Reagent?** +Reagent is a ClojureScript wrapper around React that provides a simpler, more functional approach to building user interfaces. + +**Key Features:** +- **Hiccup Syntax**: HTML represented as Clojure data structures +- **Reactive Components**: Automatically re-render when data changes +- **Atoms**: Simple state management with reactive updates +- **React Ecosystem**: Can use React components and libraries + +**Component Examples:** +```clojure +;; Simple component +(defn welcome-message [name] + [:h1 "Welcome, " name "!"]) + +;; Component with local state +(defn counter [] + (let [count (r/atom 0)] + (fn [] + [:div + [:p "Count: " @count] + [:button {:on-click #(swap! count inc)} "Increment"]]))) + +;; Using components +(defn app [] + [:div + [welcome-message "Adventurer"] + [counter]]) +``` + +**Hiccup Syntax:** +```clojure +;; Clojure data structure +[:div.character-sheet + [:h2 "Character Details"] + [:ul + [:li "Name: " (:name character)] + [:li "Level: " (:level character)]]] + +;; Compiles to HTML +