# Feature Research **Domain:** PF2e TTRPG companion app — next milestone (Level-Up + PWA + Battle-Display + Dice/Chat + GM Live Tools + Obsidian Vault) **Researched:** 2026-04-27 **Confidence:** HIGH (PF2e rules + PWA tech are HIGH; competitor UX details are MEDIUM) ## Scope Note This is a **subsequent milestone** for an existing app. Already-shipped features (HP, conditions, skills, saves, inventory, alchemy, rest, alchemy-tab, character-import, battle-MVP, GM-library, JWT-auth) are NOT re-evaluated here. The categorization below applies **only to the new milestone scope**. The bar for "table stakes" is calibrated to the actual user — the **own gaming group at the table**. Things that would be table-stakes for a public SaaS (multi-tenant onboarding, account recovery flows, etc.) are not table-stakes here. ## Feature Landscape ### Table Stakes (Without these, the milestone fails its goal) #### Level-Up System | Feature | Why Expected | Complexity | Notes | |---------|--------------|------------|-------| | **Attribute Boosts at level 5/10/15/20** (4 free boosts; +2 to four different attributes, capped at +4 / 18) | PF2e core rule, every PF2e tool implements it | MEDIUM | Trigger HP-Max recompute on CON-Boost; +1 trained skill on INT-Boost | | **Class feat at every even level** (2, 4, 6, 8, 10, 12, 14, 16, 18, 20) | PF2e core rule | HIGH | Filter by class + level + prerequisites; many feats have multi-condition prereqs (skill rank, other feat, ancestry) | | **Skill feat at every even level** (2, 4, 6, ...) | PF2e core rule | MEDIUM | Filter by skill rank prereq; some require Trained/Expert/Master/Legendary in named skill | | **General feat every 4 levels** (3, 7, 11, 15, 19) | PF2e core rule | MEDIUM | Skill feats ALSO count as general feats (one-way) | | **Skill increase at level 3 and every 2 levels thereafter** (3, 5, 7, 9, 11, 13, 15, 17, 19) | PF2e core rule, Rogues earlier/more | MEDIUM | Untrained→Trained, Trained→Expert (level 3+), Expert→Master (level 7+), Master→Legendary (level 15+) | | **Ancestry feat at level 5, 9, 13, 17** | PF2e core rule | MEDIUM | Filter by ancestry, heritage, prerequisites | | **Class features per class table** (e.g. Fighter Bravery at 3, Weapon Mastery at 5, etc.) | PF2e core rule, class-specific | HIGH | Per-class lookup table; some grant additional choices (e.g. specialization) | | **Prerequisite validation** (e.g. "Trained in Athletics required") | Without this it's not "regelkonform" | HIGH | Need to evaluate prerequisite expressions: skill rank, feat ownership, level, ancestry, deity, spellcasting tradition | | **Auto-recompute derived stats** (HP-Max, Save proficiency increases, AC proficiency, Class DC) | Core promise of "regelkonform" — values must be correct after Level-Up | HIGH | Class-specific proficiency progression tables; HP-Max = ancestry HP + (class HP + CON-Mod) × Level | | **Undo / Cancel before commit; commit creates change record** | Already in PROJECT.md as requirement; users will misclick | MEDIUM | Implement as draft state; on commit, write all changes atomically | | **Free Archetype variant rule** (extra archetype-only feat at every even level) | Group's preferred PF2e variant; Pathbuilder + Foundry's PF2e Leveler both support it | MEDIUM | Toggle per character; second feat slot, restricted to archetype feats only | | **Spellcaster slot/cantrip progression on Level-Up** | Spellcasters need correct slot tables to play | HIGH | Per-tradition progression; spell repertoire/preparation also needs increment for spontaneous casters | #### PWA | Feature | Why Expected | Complexity | Notes | |---------|--------------|------------|-------| | **Web App Manifest + Icons + Splash + Service Worker registration** | Without manifest, app can't be installed | LOW | Standard Vite PWA plugin (`vite-plugin-pwa`) handles boilerplate | | **Cache-first read of own character sheet (offline)** | "Always-on companion at the table" with flaky table Wi-Fi | MEDIUM | Cache GET responses for `/characters/:id`, `/equipment/:id`, `/feats/:id` etc.; show "offline" indicator | | **"Add to Home Screen" prompt** (Android automatic via `beforeinstallprompt`, iOS guided manual) | Without it users won't install and miss push | LOW | iOS needs in-app instruction overlay since no programmatic prompt — see PITFALLS | | **Web Push for GM→player ping** (turn alert, dice request, custom message) | Whole point of having a PWA at the table | HIGH | VAPID keys, Service Worker `push` event handler, Push subscription persisted per device, opt-in flow per user | #### Multi-Screen Battle Display | Feature | Why Expected | Complexity | Notes | |---------|--------------|------------|-------| | **Read-only Display-Mode route** (e.g. `/battle/:id/display`) | Existing battle page is GM-only mixed; table screen needs a "no controls" view | MEDIUM | Same WebSocket subscription, conditionally hide drag handles + controls; optimize layout for landscape table screen | | **Display-Mode auth model** (player or shared GM session, no controls) | Tisch-Display likely runs as a shared/auto-login terminal | MEDIUM | Either anonymous read-only via session token OR dedicated "display" pseudo-user with read-only role | | **Initiative Tracker as sortable list with current-turn highlight** | Currently only badges on tokens; players need to see "wer ist dran" at a glance from across the table | LOW-MEDIUM | Sorted list; large-font for table-display readability; "next" button on GM side; advances turn via WebSocket event | | **Token effects/conditions/auras on Display-Mode** | Players need to see "I'm flat-footed and frightened 2" without asking GM | MEDIUM | Already have conditions on character; need same model on tokens; per-token condition list rendered on/near token + in init list | | **Token add/remove broadcast as WebSocket event** (not just query-invalidate) | Currently mid-battle changes desync until refresh | LOW | Existing gateway pattern; add `token:added` / `token:removed` events | #### Dice + Chat | Feature | Why Expected | Complexity | Notes | |---------|--------------|------------|-------| | **In-app dice with PF2e notation (`1d20+7`, `2d6+3`)** | Primary play mechanic; no external dice tabs | MEDIUM | Use `@dice-roller/rpg-dice-roller` or `dice-notation-js`; standard d4/6/8/10/12/20/100 | | **Crit success / crit failure flagging** (PF2e: nat 20 / +10 / +0 / -10) | PF2e's defining mechanic — degree of success | MEDIUM | Compare result vs DC; degree-of-success calc lives in app (not in dice lib) | | **Roll log per campaign + per battle, visible to all** | Without log, contested rolls become arguments | LOW | Append-only log table; WebSocket broadcast on new roll | | **Roll attribution** (who rolled, what for, when) | Logs without attribution are useless | LOW | User + character + label (e.g. "Athletics Check") + timestamp | | **In-game chat per campaign + per battle** | GM/player coordination during play | LOW-MEDIUM | Append-only message table; same WebSocket pattern; rendered with roll embeds inline | #### GM Live Tools | Feature | Why Expected | Complexity | Notes | |---------|--------------|------------|-------| | **GM can set HP / damage / heal on player character** | Already infra exists; just needs GM-facing UI | LOW | Reuse existing `character:update` events; add GM permission check + "GM action" log entry | | **GM can add/remove/update conditions on player character** | Same | LOW | Reuse existing condition gateway events | | **GM can give item to player character** | Loot distribution | LOW | Reuse existing inventory events; pick from equipment DB | | **GM can adjust money (credits)** | Loot/cost management | LOW | Reuse existing money events | | **GM can send push/chat ping to specific player(s) or all** | "Du bist dran" workflow | MEDIUM | Combines push (Web Push) with in-app chat — see Pitfalls about double-delivery | #### Obsidian Vault Read-Only | Feature | Why Expected | Complexity | Notes | |---------|--------------|------------|-------| | **Markdown rendering** (CommonMark + GFM tables/code blocks/images) | Bare-minimum vault reader | LOW | `react-markdown` + `remark-gfm` + `rehype-sanitize` | | **Wikilinks `[[Note]]` and `[[Note\|Alias]]`** | Obsidian's primary linking syntax — without this, every link is broken | MEDIUM | `@portaljs/remark-wiki-link` or `@flowershow/remark-wiki-link` (handles shortest-path) | | **Image embeds `![[image.png]]`** | Notes are useless if maps/illustrations don't render | MEDIUM | Custom remark plugin or extension of wiki-link; serve via vault endpoint | | **Folder tree navigation** | Vaults aren't flat; navigation must mirror structure | LOW | Tree control over directory listing endpoint | | **Full-text search** | Vaults grow large; finding "the inn name" without search is painful | MEDIUM | Server-side grep-like or `flexsearch`-style index over markdown body; Postgres FTS is acceptable | | **Cache last-N read notes for offline** | "I want to look up that NPC" while at the table without Wi-Fi | MEDIUM | Service-Worker cache-on-read with LRU eviction; server stays source-of-truth | ### Differentiators (would make Dimension47 noticeably better than Pathbuilder/Foundry/Owlbear for this group) | Feature | Value Proposition | Complexity | Notes | |---------|-------------------|------------|-------| | **German UI everywhere — including PF2e rules text** | Pathbuilder is English-only; Foundry's PF2e is partial-German with Babele/translation modules. Dimension47 already has a translation pipeline (Claude-API cached) | MEDIUM | Extend existing translation cache to feats and class-features text on Level-Up | | **One-screen, integrated experience** (character sheet ↔ battle ↔ vault notes ↔ chat) without context-switching apps | At the table users today juggle Pathbuilder + Discord + Obsidian + a dice-roller — all in one app reduces friction | MEDIUM | Architecture choice: deep-linking + state-preserving navigation; vault note can be opened side-by-side with character | | **PF2e dice with degree-of-success + auto-condition application** (e.g. "Frightened 1 on critical hit with X spell") | Most VTTs roll dice but leave degree-of-success and condition-application to player; auto-application removes one-step-per-attack friction | HIGH | Spell/attack-templates with embedded "on-hit"/"on-crit" effects; data model heavy — defer to v1.x | | **Animated transition: GM "Du bist dran" ping → player phone vibrates → in-app initiative-card pop-up** | Combines push + visual + haptic; nobody else does it well at-the-table because nobody else is PWA-first | MEDIUM | Layer Web Push + Vibration API + in-app modal | | **Battle-Display dark/cinematic mode** (large initiative card for active turn, dimmed for off-turn) | The table screen is part of the table aesthetic; sterile Foundry UI breaks immersion | LOW | CSS-only theme variant for `/battle/:id/display` route | | **Vault note → character "see also" chips** (note marked with frontmatter `npc: true` shows as hoverable chip in chat / battle) | Connects worldbuilding (Obsidian) to play (battle/chat) without manual lookup | HIGH | Frontmatter parsing + tag/type indexing; defer to v1.x | | **Roll history per character is exportable** (matches existing HTML-export ethos) | Group keeps session memory beyond runtime | LOW | Reuse export-character-html pattern | | **Offline-cached vault search** (FlexSearch index served as static asset for installed PWA) | Read-and-search Obsidian notes with zero connectivity | HIGH | Build-step or on-demand index download; defer to v1.x or call out as risky | | **GM can assign initiative roll-prompt** ("Roll Initiative for Perception" → all players get push + dice button pre-populated) | Removes 30-second "everyone roll initiative" coordination at the table | MEDIUM | Combines GM-tools + dice + push | ### Anti-Features (Commonly tempting, deliberately NOT building) | Feature | Why Tempting | Why Problematic | Alternative | |---------|--------------|-----------------|-------------| | **Bidirectional Obsidian sync** (write-back from app to vault) | "Wouldn't it be great to edit notes from phone too" | Conflict resolution is its own product; group already uses Obsidian on desktop for editing | Read-only is explicitly in PROJECT.md Out of Scope | | **Offline editing with sync queue** (offline character changes that re-sync later) | Looks pro, modern PWAs have it | Two players editing same character offline = last-write-wins corruption; complexity vs value at the table is bad — game is online anyway | PROJECT.md already excludes this; offline is read-only | | **Native app (Capacitor / React Native wrapper)** | "Better push reliability, better install UX, app-store presence" | App-store overhead, build pipelines, two more codebases. PWA solves 95 % of need | PWA + careful Service-Worker; iOS Safari supports installed-PWA Push since 16.4 | | **In-app character creation from scratch** | "Why force users out to Pathbuilder?" | Pathbuilder is a 5-year-mature character builder; rebuilding it duplicates years of work for one-time-per-character benefit | Pathbuilder import stays. Level-Up in app handles ongoing changes | | **Generic VTT (other systems, D&D 5e, etc.)** | "More users" | Self-hosted for own group; data model is PF2e-specific (action-economy, proficiency tiers, archetypes); generalizing kills sharpness | Keep PF2e-only | | **Public multi-tenant SaaS / signup flow** | Default mental model for "web app" | Self-hosted for own group; account-onboarding is 0-value | No public registration; ADMIN provisions accounts | | **Presence indicators** ("Alex is viewing the map", "Spieler X tippt...") | Social-app default | Real value tiny vs WebSocket complexity, especially with mobile screen-locks | PROJECT.md already excludes this | | **Fog of War on battle map** | Owlbear/Foundry have it | Group plays in-person with 3D minis on a table screen; fog of war with a flat overhead in-person doesn't make sense | Already out-of-scope in PROJECT.md | | **Voice chat / video** | Discord-replacement temptation | Discord works fine; reinventing it costs a milestone for zero gain | Use existing Discord | | **3D dice physics** (rolling animation, ringtone) | Feels premium | Burns CPU on mobile, distracts from in-person play, every player has real dice on the table anyway | Plain text "rolled 17" with crit-color highlight | | **Real-time collaborative vault editing** (Obsidian Live-style) | Trendy | Group edits Obsidian on desktop; collaborative-CRDT for Markdown is a quarter-of-engineering for unclear gain | Read-only stays read-only | | **AI-generated NPCs / encounters** | LLM hype | Out of scope; group's GM has Obsidian for prep | Vault read is enough | | **Dynamic lighting** (Foundry's flagship feature) | "Looks like a real VTT" | In-person with table screen and minis; lighting is the room's lighting | No | | **Token vision / line-of-sight calc** | Same | Same — minis on a table | No | | **Auto-applying attack rolls to enemy HP** | "PF2e is so click-heavy, just automate it!" | High data-model cost (every attack-feat needs structured "on hit"/"on crit"/save-DC linking); error-recovery is messy when GM disagrees | GM applies HP changes manually via Live-Tools — already in-scope | | **Marketplace for community NPCs / maps** | "GMs would love to share" | Group of 1 GM + N players; library is internal; sharing is out-of-scope (self-hosted, single-tenant) | GM-Library is internal-only | ## Feature Dependencies ``` PWA Manifest + Service Worker ├──enables──> Web Push │ └──used-by──> GM "Du bist dran" ping │ └──used-by──> Dice-roll-request push └──enables──> Offline-cache ├──used-by──> Character sheet offline read └──used-by──> Vault notes offline read Web Push subscription endpoint persistence └──requires──> Per-user device-list table (server-side) Level-Up system ├──requires──> Feat-prerequisite evaluator (DSL or interpreter) ├──requires──> Class-progression-table data (per-class proficiency by level) ├──requires──> Boost-cap recomputation (HP, save bonuses, AC) └──enables──> "Level" WebSocket event already exists, Level-Up can broadcast Battle Display-Mode read-only route ├──requires──> Auth model decision (anon-token vs display-pseudo-user) ├──requires──> Token-effect data model (new schema) └──requires──> WebSocket event for token-add/remove (not query-invalidate) Initiative Tracker upgrade └──depends-on──> Existing battle-session schema; pure UI + small server change Dice roller ├──requires──> Roll-log table (campaign + battle scoped) ├──enables──> Chat with embedded rolls └──enables──> GM "request roll" feature (combines push + dice) In-game Chat ├──requires──> Message table (campaign + battle scoped) ├──depends-on──> Existing JWT/role for whisper/visibility └──integrates-with──> Dice-roll-log (rolls render inline) GM Live-Tools UI └──reuses──> All existing character WebSocket events (HP, conditions, items, money) └──just-needs──> GM-facing UI surface (no new server events) Obsidian Vault ├──requires──> Vault-endpoint protocol decision (HTTP-served-files vs Git-pull vs custom) ├──requires──> Markdown renderer (react-markdown + remark-wiki-link) ├──requires──> Image proxy for ![[image.png]] └──enables──> Vault-search (FlexSearch or Postgres FTS) GM Push-Ping → Player feature ├──requires──> Web Push (PWA prerequisite) ├──requires──> In-game Chat (so the message has a destination) └──requires──> GM Live-Tools UI (the trigger surface) ``` ### Dependency Notes - **Web Push depends on PWA Manifest + Service Worker.** Cannot ship Push before installable PWA exists. - **iOS Push requires installed-to-Home-Screen PWA** (Safari 16.4+). Test plan must include "is the PWA actually installed?" check. - **Level-Up auto-recompute depends on per-class progression tables.** These are not currently in the DB schema (the existing app reads class-features from Pathbuilder import only, no progression model). New table needed: class progression by level, per-class. - **Free Archetype is a per-character toggle**, not a global config. UI must show this toggle on character creation/edit. - **GM-Live-Tools requires no new server events** — everything reuses existing character/inventory/condition/money WebSocket events. Risk: existing events probably don't enforce "is the actor a GM in this campaign" — needs server-side authorization audit. - **Display-Mode auth needs a decision early.** Anonymous-token vs pseudo-user has long downstream effects on chat/roll attribution from the table screen. - **Vault endpoint protocol is unresolved.** PROJECT.md says "selbst-gehosteter Endpoint, Protokoll noch zu wählen" — research/spike needed before vault phase. ## MVP Definition (For the new milestone — not the whole app) ### Launch With (milestone v1) Minimum viable to ship the milestone: - [ ] **Level-Up regelkonform** — all six choice points (boost / class feat / skill feat / general feat / skill increase / ancestry feat / class feature) with prerequisite validation, auto-recompute, undo-before-commit, Free Archetype variant. Spellcaster slot/cantrip progression included. - [ ] **PWA Manifest + Service Worker + Add-to-Home-Screen flow** — Android automatic, iOS guided - [ ] **Cache-first offline read** for character sheet, inventory, feats, actions, alchemy, vault notes (already-visited only) - [ ] **Web Push for GM→player ping** — VAPID keys, subscription persistence, GM-trigger UI - [ ] **Battle Display-Mode route** — read-only, large initiative tracker, token effects/conditions visible - [ ] **Token-effect data model + GM editor** — per-token list of named effects with optional duration - [ ] **Token add/remove WebSocket event** — convert existing query-invalidate - [ ] **Initiative Tracker upgrade** — sortable list, current-turn highlight, GM next-turn button - [ ] **In-app dice with PF2e notation + degree-of-success + roll log** per campaign and battle, broadcast via WebSocket - [ ] **In-game chat** per campaign and battle, with inline roll embeds - [ ] **GM Live-Tools UI** — set HP/conditions/items/money on player character via existing events; send-message-to-player UI - [ ] **Obsidian Vault read-only browser** — folder tree, file read, markdown + wikilinks + image embeds, full-text search, last-N offline-cached - [ ] **German translation cache extension** for new feat-prereq text and class-feature descriptions ### Add After Milestone (v1.x — defer if scope tight) - [ ] **Animated push-ping arrival** with vibration + in-app initiative-card overlay - [ ] **Battle Display cinematic theme** — dim off-turn, large active-turn card - [ ] **GM "request roll" from player** — combined push + pre-populated dice button - [ ] **Roll-history export** to HTML/PDF - [ ] **Vault frontmatter NPC chips** — type-tagged notes auto-link in chat/battle - [ ] **Level-up history view** on character — what was chosen at each level ### Future Consideration (post-milestone) - [ ] **Auto-condition application from spells/attacks** — heavy data-model cost, defer until Level-Up + Battle stabilize - [ ] **Vault offline FlexSearch index** — full vault offline-search; only matters if vault grows large - [ ] **Background-sync of stale character data** — limited iOS support; complex; nice-to-have - [ ] **Multi-language UI beyond German** — only relevant if new players join who don't read German ## Feature Prioritization Matrix | Feature | User Value | Implementation Cost | Priority | |---------|------------|---------------------|----------| | Level-Up: 6 choice points + validation + auto-recompute | HIGH | HIGH | P1 | | Level-Up: Free Archetype variant | HIGH (group uses it) | MEDIUM | P1 | | Level-Up: Spellcaster progression | HIGH (group has casters) | HIGH | P1 | | PWA installable + offline character read | HIGH | MEDIUM | P1 | | Web Push GM→player | HIGH | HIGH | P1 | | Battle Display-Mode read-only route | HIGH | MEDIUM | P1 | | Initiative tracker upgrade | HIGH | LOW-MEDIUM | P1 | | Token effects/conditions | HIGH | MEDIUM | P1 | | Token add/remove WebSocket | MEDIUM | LOW | P1 | | Dice roller + roll log | HIGH | MEDIUM | P1 | | In-app chat | HIGH | LOW-MEDIUM | P1 | | GM Live-Tools (HP/conditions/items/money) | HIGH | LOW | P1 | | Obsidian read + wikilinks + images | HIGH | MEDIUM | P1 | | Vault search | MEDIUM-HIGH | MEDIUM | P1 | | Vault offline-cache (last-N) | MEDIUM | MEDIUM | P1 | | Battle cinematic theme | MEDIUM | LOW | P2 | | Animated push-ping with vibration | MEDIUM | MEDIUM | P2 | | GM "request roll" feature | MEDIUM-HIGH | MEDIUM | P2 | | Level-up history view | MEDIUM | LOW | P2 | | Vault frontmatter NPC chips | MEDIUM | HIGH | P3 | | Auto-condition from spells | MEDIUM | HIGH | P3 | | Vault offline FlexSearch full-index | LOW-MEDIUM | HIGH | P3 | ## PF2e-Specific Complexity Notes (Level-Up) The Level-Up feature is structurally the most complex single piece in this milestone. Worth calling out: 1. **Six independent choice axes per level** (not all triggered every level): attribute boost, class feat, skill feat, general feat, skill increase, ancestry feat, class feature. Each has its own filter logic. 2. **Prerequisites are a mini-DSL.** Examples: - `"Trained in Athletics"` → simple skill-rank check - `"Strength 14, trained in Intimidation"` → composite check - `"Power Attack, level 4"` → feat ownership + level - `"Cleric"` → class check - Roughly 200+ feats have non-trivial prereqs; treating each as a free-text string and asking the GM is the cheap way out — but kills the "regelkonform" promise. 3. **Class progression tables vary widely.** Fighter has 5 weapon-specialization steps; Wizard has school-specific arcana progressions; Rogue has skill-increases at every level (not every other). No single shared table. 4. **Boost rules have an "above 18" cap rule.** Each boost is +2, but if attribute is already 18+, only +1. This is one of the most frequently-misunderstood PF2e rules — must be implemented correctly. 5. **Free Archetype variant** doubles the class-feat slots but restricts to archetype feats only AFTER dedication is taken. Once a dedication is chosen, the slot can take any feat from THAT archetype's list. 6. **Skill-increase scaling caps.** Trained→Expert allowed at level 3+; Expert→Master at level 7+; Master→Legendary at level 15+. Pre-cap selections must be filtered out. 7. **Multiple-class-feature characters.** A Champion at level 9 might have: Champion's Reaction, Deity's Domain Spell, Divine Ally, an Ancestry feat slot, a Class feat slot, plus a Free Archetype slot. UI needs to make this navigable, not overwhelming. **Recommendation:** Phase Level-Up as its own implementation phase. Treat prerequisite-DSL as a sub-deliverable. Plan for an "escape hatch" where a non-evaluated prerequisite shows as a warning ("kann nicht automatisch geprüft werden") rather than a hard block, so unusual feats don't break the flow. ## Competitor Feature Analysis | Feature | Pathbuilder 2e | Wanderer's Guide | Foundry VTT (PF2e) | Owlbear Rodeo | Our Approach | |---------|----------------|------------------|---------------------|---------------|--------------| | Level-Up | Full, mature, English-only | Full, web-based, English-only | Full via PF2e Leveler / PF2e Level-Up Wizard modules | N/A (no character system) | Full, German, integrated, with Free Archetype | | Dice roller | Basic | Basic | Excellent (PF2e-specific) | Built-in, simple | PF2e degree-of-success + roll log + chat embed | | Chat | None | None | Yes, with whisper/blind | Yes, simple | Yes, with roll embed + push-ping | | Battle map | None | None | Heavy, feature-rich (lighting, vision, fog) | Lightweight, fast, in-person-friendly | Lightweight + dedicated table-display mode | | Player display screen | N/A | N/A | Possible via second browser, not optimized | Cast feature (Chromecast/separate monitor) — fully read-only player view | Dedicated `/battle/:id/display` route, read-only, optimized for embedded table screen | | Push notifications | None | None | None (it's Electron, not PWA) | None | Web Push with VAPID, GM→player ping | | Offline | No (web app) | No (web app) | Local install, but no field offline | Browser-cached after load | Service Worker cache-first for read | | Obsidian integration | No | No | Possible via 3rd-party module | No | Native vault browser | | German UI | No | No | Partial via Babele + community pack | Partial | Full, including auto-translated PF2e text | | Hosting model | SaaS | SaaS | Self-hosted | SaaS (free + paid tiers) | Self-hosted (matches PROJECT.md) | | Mobile-first | Tablet-first | Desktop+tablet | Desktop, mobile painful | Mobile-acceptable | Yes (already shipped for character sheet) | | Cost | One-time app purchase | Free | One-time license fee | Free + paid tiers | Self-hosted, group only | ### Key Takeaways - **No competitor combines all six target areas** of this milestone in one app. Pathbuilder excels at character (esp. level-up) but is character-only. Foundry has battle + chat + dice but desktop-heavy and module-fragmented. Owlbear has the cleanest player-display-screen story but no character system. Obsidian is its own thing entirely. - **The "all-in-one for our group, in German, on mobile-first PWA" niche is unoccupied.** This is the differentiator. - **PF2e Leveler and PF2e Level-Up Wizard (Foundry modules) prove that prerequisite-validating Level-Up is feasible** — they exist and are maintained. We can study their data models without using their code (license / system difference). - **Owlbear's "cast" feature is the closest to our table-display goal** — read-only, joins as fake-player, cannot see GM-only content. That's a solid mental model. ## Sources - [Pathfinder 2e Leveling Up — Archives of Nethys](https://2e.aonprd.com/Rules.aspx?ID=2065) - [Pathfinder 2e Ability Boosts — Archives of Nethys](https://2e.aonprd.com/Rules.aspx?ID=75) - [Pathfinder 2e Skill Increases — Archives of Nethys](https://2e.aonprd.com/Rules.aspx?ID=2109) - [Pathfinder 2e Free Archetype — Archives of Nethys](https://2e.aonprd.com/Rules.aspx?ID=2751) - [Wanderer's Guide character builder](https://wanderersguide.app/) - [PF2e Leveler — Foundry VTT module](https://foundryvtt.com/packages/pf2e-leveler) - [PF2e Level-Up Wizard — Foundry VTT module](https://foundryvtt.com/packages/pf2e-level-up-wizard) - [Owlbear Rodeo Casting documentation](https://docs.owlbear.rodeo/docs/casting/) - [Foundry VTT Basic Dice](https://foundryvtt.com/article/dice/) - [Roll20 Dice Reference](https://help.roll20.net/hc/en-us/articles/360037773133-Dice-Reference) - [PWA Best Practices 2026 — Wirefuture](https://wirefuture.com/post/progressive-web-apps-pwa-best-practices-for-2026) - [PWA iOS Limitations and Safari Support 2026 — MagicBell](https://www.magicbell.com/blog/pwa-ios-limitations-safari-support-complete-guide) - [Apple reverses decision about blocking web apps in EU — TechCrunch](https://techcrunch.com/2024/03/01/apple-reverses-decision-about-blocking-web-apps-on-iphones-in-the-eu/) - [@portaljs/remark-wiki-link — npm](https://www.npmjs.com/package/@portaljs/remark-wiki-link) - [react-markdown documentation](https://remarkjs.github.io/react-markdown/) - [airjp73/dice-notation — GitHub](https://github.com/airjp73/dice-notation) - [Foundry VTT vs Roll20 vs Owlbear Rodeo 2026](https://gmcrafttavern.com/foundry-vs-roll20-owlbear-2026/) --- *Feature research for: Dimension47 next milestone (PWA + multi-screen battle + extended WebSockets + Obsidian read-only vault + full PF2e Level-Up)* *Researched: 2026-04-27*