尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A single-page app for keeping tabletop RPG characters — OSR / old-school systems (Shadowdark, Worlds Without Number, OSE, …), Unknown Armies 3rd Edition, Basic Roleplaying (BRP), and Silent Legions — and running basic combat. Settings → System switches which ruleset's characters, Compendium, and Bestiary you're looking at. BRP ships with its own bundled Compendium (Powers and Equipment) and Bestiary (creatures and sample NPCs). All bundled BRP data comes only from the Basic Roleplaying: Universal Game Engine core book (Chapters 4, 8, and 11), which is published under the ORC license; nothing comes from Basic Roleplaying: Creatures. Combat shows its characteristics/Armor/Damage Bonus instead of the OSR AC/HD. Silent Legions book content (Compendium, Bestiary, random tables) can be loaded from your own PDF; see Silent Legions below. Unknown Armies Combat counts wounds up to the wound threshold, and its book content can be loaded from your own PDFs; see Unknown Armies. Plain HTML/CSS/JS — no build step, no backend, no account, nothing leaves your browser (unless you turn on the optional Dropbox sync).
main (see the repo's Pages settings for the URL).python3 -m http.server,
then open http://localhost:8000/. Opening index.html as a file (file://) does not work: the
app loads its data files over http.Everything is stored in your browser's IndexedDB (database osr_store). It survives reloads
and browser restarts, but it is per-browser and per-machine. (Older versions used localStorage;
the first start of this version moves that data into a campaign named "Default".)
Campaigns. The selector at the top right, next to the Dropbox and Export buttons, switches between campaigns. Its last option, + New campaign…, creates one. Each campaign has its own characters, Journal, log, trackers, combat, Bestiary, Compendium, and settings (theme and System too). A new campaign starts with the default Bestiary and Compendium of every system, and no example characters. Settings → Campaign renames or deletes the current campaign. Export, Import, and Dropbox sync work on the current campaign.
osr-manager-YYYYMMDD.json with all your data —
characters, notes, consumables, the monster library, the current encounter, map scenes, settings
and the log. When the campaign has map images, Export asks first: with Include map images,
you get osr-manager-YYYYMMDD.zip with the same data and every map image. Import reads both.pack header, such as the Unknown Armies catalog below) never
replaces the whole campaign. Import opens a window that lists the pack's items:
Use Export/Import to back up, move between machines, or share a party.
Settings → Dropbox sync keeps the campaign in your Dropbox, so every browser where you connect has the same data. It is off until you click Connect.
Connect.
If you cannot register the app's address (step 3 of Setup), use connect with a code under Setup instead. Dropbox opens in a new tab and shows a code. Paste the code into the box under Dropbox sync, and click Finish.
Setup (once). The app needs a Dropbox app key:
http://localhost:8000/.DEFAULT_APP_KEY in js/dropbox.js, so its users
don't have to.) The app key is not a secret. Never paste the app secret.A new Dropbox app is in Development status. In that status, up to 500 Dropbox accounts can connect, which is enough for a gaming group.
If Connect fails:
missing_scope: tick the permissions in step 2, click
Submit, then click Disconnect and Connect again. A token keeps the permissions the app
had when you connected.[WWN] / [BRP] tag: pasting # John [BRP] makes
a character named John. The tag (or "Shadowdark" in the text) sets the system badge, and
View mode shows the heading without it. Keep the tag in the text: [BRP] is what marks a BRP sheet.--- line in its Markdown (text before it on the left,
text after it on the right); with two characters shown, --- is just a normal rule.2d6+3, 1d20+4, 4d6kh3, 1d8 + 2 → rolled as written.+1 / -2 / +0 → rolled as 1d20 ± that.[square brackets] are underlined (violet, dashed) and looked up
in the Compendium on hover — see that tab. Short all-caps tags like [WWN] are left alone.Write Name: value anywhere in a sheet — value a plain, optionally-signed integer — and it's
picked up as a variable you can reference in dice formulas. In View mode the name is highlighted
in its own colour and the value keeps its usual blue, clickable-roll underline:
CON: -1, STR: 0, DEX: +1
detects CON = -1, STR = 0, DEX = +1. Several fields can share a line, separated by a comma,
semicolon, or | (in addition to each just being its own line) — e.g. HP: 10 | AC: 14 | AB: +0
detects AC and AB.
A value can have more after it, as long as a space separates them — parsing simply stops at the first number, so a common "modifier with the score in parentheses" layout works too:
ATTRIBUTES
STR: +1 (14)
DEX: +0 (9)
CON: +1 (14)
detects STR = +1, DEX = +0, CON = +1 (the (14), (9) are never looked at). The same rule
applies whichever number comes first — STR: 14 (+1) instead detects STR = 14. A number with
no separating space, like the 19 in HP: 19/19, doesn't count — only HP: 19 (or HP: 19, …) would.
Use a variable in a dice formula with $Name — e.g. 1d6+$CON+2 rolls 1d6 plus that
character's current CON plus 2. The rendered formula shows just the name (1d6+CON+2); hover
it to see each variable's current value in the tooltip (1d6+CON (-1)+2). Typing $ in the sheet
editor or the Dice Roller's custom-formula box pops up a list of that character's detected variables
to pick from. If a name changes or a sheet is edited, $Name always resolves against whatever the
sheet says right now.
Right-click any dice roll (in a sheet, in Combat, in a Compendium popup, or a Dice Roller preset) to open a small popup with a flat modifier field and a dropdown to add one of the character's variables to the roll — picking one adds another dropdown so you can stack several — before rolling.
A campaign-wide Markdown composer below the sheet (a proper editor —
EasyMDE, with the [ Compendium autocomplete).
Press Enter to log the current text to the Session Log as a Journal entry (rendered as
Markdown there) and clear the box; Shift+Enter inserts a new line. The unsent draft is saved and
survives reloads.
Campaign-wide trackers with − / value / + and an optional max, shared across every character.
The list is grouped by character (every system): a heading with the character's name, then one line
per tracker with its short label, for example HP 24 / 24 and PP 10 / 10 under Edith Jensen.
A tracker named Label (Character name) belongs to that character; you can name your own that way
(Arrows (Leo Sato)). Other trackers (Rations, Torches) follow under Shared. Editing a short
label keeps the tracker in its group. A character's trackers show only while the System matches
that character.
Each character gets an HP (Name) line (starts 0 / 0; auto-filled from that character's
sheet HP: x/y when you add them to combat, and renamed if you rename the character).
Sheet resources: every Name: current/max on a sheet gets its own line when you create or save
the character, for example HP: 13/13; PP: 17/17; FP: 27/27 makes HP (Ada), PP (Ada), and
FP (Ada). Write each resource on its own line, or separate them with ; (also | or ,).
HP and Hit Points use the HP line. A new line starts at the sheet's values; after that the line
holds the current value and the sheet sets only the max. A rename moves the lines, and deleting the
character removes them.
Add lines for rations, torches, arrows, rage uses… Delete a line with ✕.
Blank or 0 max means "no upper limit".
Silent Legions characters also get a Madness (Name) line (0 / 100) — see
Silent Legions.
Preset buttons: d20, Adv (2d20 keep-highest), Dis (2d20 keep-lowest), d4–d12, d100,
2d6, 3d6, 4d6kh3. Plus a custom formula field.
Formula grammar: NdM (e.g. 3d6), +/- chains (2d6+3, 1d8-1), keep/drop
(kh/kl/dh/dl + number, e.g. 4d6kh3), and d%. Typing a bare number/modifier rolls a d20.
After a roll, on the Combat tab, an Apply damage button appears — it subtracts the result from the currently selected combatant (HP, or HD/HP under Scarlet Heroes rules — see Settings). The button also shows on the Maps tab: there it applies the damage to the combatant of the one selected token, or to the selected combatant when no token in combat is selected. On the other tabs the button does not show.
Every roll, status change, side change and library roll is logged with a timestamp (and, in combat, the round number). Copy puts the log on your clipboard; Clear empties it. Capped at 500 lines.
(1), (2)… suffix.DEX: N / INT: N on a character's sheet. A creature with no DEX
acts on DEX rank 1 (core book p.222); one with no INT goes last in INT order. Each row has a box
for the active rank and a chip for the other one. Change the box for this combat (for example a
spell that delays the caster), then click Sort by DEX / Sort by INT. Clear the box to use
the characteristic again. On a tie the book lets the higher relevant skill go first: drag the rows.◀ turn)
through the order; going past the end bumps the round.↑ / ↓ move the selection, N / P advance / rewind the turn./ max, AC, saves and
attacks (monsters), and status tags.− / + adjust by 1; you can also type directly. HD keeps any * / +
suffix.Opens a menu with:
All status add/removes are logged with the round they happened.
1d20 + bonus; a damage button rolls just the damage dice and enables Apply damage);
clickable saves and a Morale roll; special abilities (dice inside them are clickable); and
the raw stat block.; separates them), with clickable NN% and damage
dice; skills, powers, and the description.Reached via Add monster…. Seeded on first run with the full Shadowdark core bestiary (Title Case) plus a couple of Old-School Essentials examples.
matches / total.+ Populate by HD… spends a total Hit Dice budget on monsters from the current Bestiary. Type the Total HD and, if you want, the Number of monsters. Keeper always spends the whole budget exactly. It shows the proposal first: the dice icon on a row rerolls that one monster for another with the same HD, Reroll makes a new proposal, and Add to Combat adds them.
For Basic Roleplaying, the button reads + Populate by EL…. BRP has no Hit Dice, so it uses the monster's Encounter Level (EL). EL 1 is a fair fight for one starting Normal-level PC, and ELs add up. A BRP monster without an EL is never picked. A party calculator fills the total for you:
The bundled BRP Bestiary has no ELs. The BRP content pack from the brp_character repo
(tools/extract_monsters.py) adds rated monsters from your own PDFs, or type an EL in the form.
A persistent, filterable view of the whole monster library — same idea as the Compendium tab, but for monsters. + New monster and Combat's own + Add monster… open the exact same modal described above; Search and HD min/max filter the list the same way the modal's own do (for BRP the filter reads EL, the Encounter Level). Per row: Add to Combat, Edit, ✕ (remove from library).
Instead of pasting a stat block, switch the add/edit modal to Fill in fields and pick a Format — Shadowdark (a single AC, and S/D/C/I/W/Ch stat modifiers), Old-School Essentials (a descending AC — the matching ascending AC is derived automatically — THAC0, D/W/P/B/S save targets, and Morale), Basic Roleplaying (BRP), or Silent Legions (a descending AC, Morale, Skill, one Save target — leave it blank for the book's 15 − ½HD — Madness, Slaughter die, and an AC* box for creatures that ordinary harm doesn't work on). The BRP form has an EL field (Encounter Level; leave it blank for an unrated monster). BRP and Silent Legions have no paste parser, so the modal opens straight into the form when one of them is the active System. Add as many Attacks (label, count, to-hit, damage, note) and Abilities (name + description) rows as the monster needs with + Add; ✕ removes a row. Saving builds the monster's stat-block text from whatever you entered, so it displays (and can be switched back to Paste text) just like a pasted one.
Click Random monster…, to the right of the HD filter, to open the generator. A click outside it, or Escape, closes it. It rolls a monster following the Shadowdark core rulebook's Monster Generator and Monster Mutations tables, for a given Party Level:
Party Level + 10; a Combat roll sets its Level (and attack bonus) somewhere around
that Party Level, and picks a flavor Quality (e.g. Draconic, Undead, Ooze) with a
matching Strength and Weakness.Generate… doesn't add the result straight to the library — it lands in the add modal's Fill in fields form (with an editable placeholder name like "PL 3 Draconic Creature") so you can review, rename, or tweak anything before saving it for real.
A personal reference of Items, Spells, Abilities, Rules and Other entries. Each entry has a name, a category, a source, and a Markdown body edited in a proper Markdown editor (EasyMDE, vendored). It comes seeded with the Shadowdark RPG core gear (weapons, armor, basic gear) as Items sourced Shadowdark Core.
Put an entry's name in [square brackets] in a sheet (View mode), the Journal, or another
Compendium entry's body. It renders underlined in violet; hover it for a popup:
1d6, 2d6+3 — not in backticks) are clickable and logged under the
entry's name. Nested [refs] in the body are themselves hoverable. Matching is
case-insensitive exact first, then fuzzy; with several matches, the ‹ n / N › arrows in the
header (or ↑ / ↓ while hovering) page through them. The body scrolls normally when it's long.Make a link from the sheet: in View mode, select some text, right-click → "Add … to
Compendium". The editor opens with that text as the name; on Save, the sheet's Markdown source
has that text replaced with [Entry Name], so it becomes a live link.
Popups stack — hovering a link inside a popup opens another, and the whole chain stays while the mouse is anywhere in it. Each popup has a 📌 pin (keeps it open after the mouse leaves) and an ×. Esc closes every popup; clicking elsewhere closes the unpinned ones. A pinned popup can be dragged by its header to reposition it. Drag the corner grip (bottom right) to resize a popup; a resized popup stays pinned. A popup shows only on the tab you opened it from, even when pinned: it hides when you change tabs and comes back when you return to that tab. On the Maps tab, a popup also belongs to the scene you opened it on, and it hides on other scenes. This browser keeps the pinned popups of each scene (place and size too), so they come back after a reload. Esc closes only the popups that show.
[ autocompleteIn the sheet editor, the Journal, and the Compendium entry editor, typing [ followed by 2+
characters pops a search of Compendium entry names. ↑ / ↓ to move, Enter / Tab or click to
insert [Name], Esc to dismiss. With text selected, pressing [ or ] in any of those editors
wraps the selection in [ ] instead of replacing it.
Battle maps and world maps, one scene at a time. Each scene belongs to the current System.
New scene. Choose + New scene… in the scene selector. Give it a name, and choose an image file or enter the address of an image. You can also paste an image (Ctrl/Cmd+V) on the Maps tab, or drop an image file on the map. With no image, the scene is a blank map.
Scenes. The selector at the right of the toolbar switches scenes. Rename, Duplicate (the copy shares the image), and Delete work on the open scene.
Hotkeys. Alt plus a key chooses a toolbar button: Alt+1 to Alt+4 the hand, ruler, grid, and pin tools; Alt+5 to Alt+0 and Alt+- the drawing tools; Alt+= the hexcrawl tool; Alt+S sticky mode; Alt+F show the whole map; Alt+O pop out; Alt+G the Grid menu; Alt+K the Tokens menu. Alt is the Alt key on Windows and the Option (⌥) key on Mac. Hover a button to see its key, or click the ? button at the end of the toolbar for the list.
Sticky mode (the thumbtack button, on by default). On: a tool stays chosen after you use it. Off: after one drawing, text, measure, pin, or grid drag, the hand tool comes back.
Right-click pan (the mouse button next to sticky mode, off by default). On: drag with the right mouse button on the map to move the view, and the browser's menu does not open. Off: a right-click on the map opens a menu to add a pin there or, in hexcrawl mode, to mark the hex explored. A right-click on a token, a drawing, or a pin always opens its own menu.
Grid, Tokens, and ? (the hotkeys) are menus at the end of the toolbar. They open over the map, so the map does not move. A click on the map closes them.
Move and zoom. With the hand tool, drag to move the view. The mouse wheel zooms around the pointer. The middle mouse button, or Space held, moves the view with any tool. The expand button shows the whole map again. This browser keeps the view (center and zoom) of each scene, so a reload or a switch to another scene and back shows the same place.
Grid. A new scene has hexes. Open Grid to choose squares or hexes (flat-top or pointy-top), the cell size in image pixels, the offset, and what one cell is (for example 5 ft, or 6 miles for a hexcrawl).
A library of random tables. The built-in ones are Shadowdark encounter tables (one per terrain/district — Arctic, Cave, Market, Tavern, Tomb, and so on), each rollable with its own dice formula (usually d100). A content pack can add tables (for example the Silent Legions pack). You can also make your own tables, and a table can roll on other tables (a master table).
Every campaign and every System sees the same tables.
[Name] link shows it.[Name] in a row is a link: click it
to open that table.``` lines, with its indents. For a master table, every sub-roll in the result is underlined: click one to roll
only that part again.Origin: [Artifact Origin]; Curse: [Artifact Curse], shows its result as an outline: one line
per lookup ("Origin: …"), and a sub-table that is itself such a list goes indented under its
label. Click the label to roll that whole group again. A ; ends a line. Text like
A [Color] [Shape] stays on one line. The Session Log shows the same lines.d10
1-2: [Ruin]
3-5: [Camp]
6-7: The [Words.Group] of the [Words.Hue] [Words.Thing]
8-0: [2x Ruin]
d12, 2d6, d100. Add named columns with |: d12 | Group | Hue | Thing.range: text. A range is 4 or 1-2 (1–2 works too). On a d10, 0 means 10;
on a d100, 00 means 100. A line without a range takes the next number, so a plain list of 12
lines under d12 is a full table.|, one cell per column: 1: Circle | Grey | Lamp.[Name] rolls on another table. [Name.Column] rolls on a table with columns and
takes one column ([Name] alone gives every cell). [2x Name] or [1d4x Name] rolls more than
once, joined with commas. [2d6] rolls dice in the text.# are skipped.The editor colors the text as you type: ranges, lookups to known tables, dice, and lookups to
tables that do not exist (red). Type [ for a list of table names; pick a table with columns and
the list shows its columns. Below the text, the editor lists problems: a bad die (Save is blocked),
values with no entry, overlapping ranges, and unknown tables. Test roll rolls the draft without
logging it. If you rename a table, the lookups to it in your other tables change too.
A content pack can carry tables too (a tables list of { name, source, origin, settings, output },
where source is the table text and settings is a list such as ["Modern", "Horror"]), so you can
keep the tables from your books in a private pack. A pack table without origin gets the pack
name; without settings, the pack's System gives them. An older single setting string works too.
The full format is in docs/content-pack-format.md.
Set Settings → System to Unknown Armies 3rd Ed.
```ua block (identities, passions,
relationships, Wound Threshold: N, and the five shock meters). View mode shows it as a sheet:
abilities follow from the hardened notches, and you click the notch dots to change them. Every
NN% is a percentile roll.[Name] links to those Compendium entries; paste it with Paste from clipboard.Type:, Book:,
Wound Threshold: and Obsession: lines, then the same sections as a ```ua block. An
identity can be rated with a range or dice (3d10+40%) and an Abilities section gives an
ability directly (Struggle 70%). Put a line of --- between two GMCs. There is no
Fill in fields form and no HD filter for Unknown Armies.Set Settings → System to Silent Legions.
```sl block (attributes and a starting
Madness: N line). That block is what marks a character as Silent Legions, the same way ```ua
does for Unknown Armies. A BRP sheet has no block: [BRP] at the end of its first line marks it. Write skill checks as Perception 2d6+1 and the attack bonus as +1 so they
stay clickable.Madness: line. After that the tracker is what you update.node tools/extract.mjs "Silent Legions.pdf") writes keeper-sl-pack.json. Load it with
Import. It adds:
6* = ordinary harm doesn't work). A
to-hit roll's log line says which ACs it hits (1d20 + bonus + AC ≥ 20). The detail panel adds
Skill (2d6 + skill), Slaughter (6+ triples the damage), and Madness buttons.1 → 0, 2–5 → 1, 6–9 → 2, 10+ → 4 — sums the results, and
applies that to a monster's HD or a character's HP. A flat damage bonus is folded into the
single highest die before translating. If a monster is already at 0 HD but still has HP, the hit
drops its HP to 0. Off: the raw rolled total comes off HP.Pasted monsters (and the character-sheet examples) are parsed automatically. Two monster formats:
Shadowdark
BEAR, POLAR
A mighty, white bear that thrives in arctic environments.
AC 13, HP 34, ATK 2 claw +6 (2d6), MV near (climb), S +4, D +1, C +3, I -2, W +1, Ch -2, AL N, LV 7
Crush. Deals an extra die of damage if it hits the same target with both claws.
Thick Fur. Cold immune.
Old-School Essentials
Bulette
15′ long, hard-shelled reptiles with huge maws...
AC 0 [19] Hd 9* (40hp) Att Bite (4d12) + 2 × claw (3d6) THAC0 12 [+7] Mv 150′ (50′) sv D8 W9 P10 B10 S12 (9) ML 11 AL Neutral XP 1,600 TT None
▶ Ravenous: Will attack anything living.
▶ Leap: If cornered, can leap forward 20′, attacking with all 4 claws.
Paste several at once — a blank line between them is ideal, but back-to-back blocks are handled too.
data/bestiary_data.json.data/token-icons.json. Settings lists the authors of the icons your campaign uses.See AGENTS.md if you want to work on the code.
Measure. With the ruler tool, drag from one point to another. The app shows the distance in cells and in your unit, for example "3 cells · 15 ft". A diagonal step on squares counts as one cell.
Tokens. Open Tokens and click an icon: a token appears in the middle of the view, on the grid. Choose its Size (cells across; on hexes, rings) and Color (black at first) first.
Drawing. The second group of tools draws on the map: pen, line, rectangle, ellipse, polygon, text, and eraser. The bar at the top of the map sets the color, the line width, Fill (for shapes), and the opacity.
Pop out. The window button opens the map in a window of its own, for example on a second screen for the players. Both windows show the same campaign: a token moved or a line drawn in one shows in the other at once, and Ctrl+Z in either undoes the last map change. Keep the main window open: the map window shows nothing without it. If your browser blocks the window, allow pop-ups for this site.
Undo and redo. Ctrl+Z (Cmd+Z on a Mac) undoes the last change to the scene: tokens, drawings, grid, and name. Ctrl+Shift+Z or Ctrl+Y redoes it. The undo and redo buttons do the same. Each scene has its own history until you reload the page.
Location notes. With the pin tool, click a place on the map: a pin appears, and a new
Compendium entry (category Journal) opens for its note. The note belongs to the current
System and works like any Compendium entry: search it, or link it with [name] in a sheet. The
note starts with the map's name and, on a hex grid, the hex number. The app writes them once: a
later rename of the scene or move of the pin does not change them. With
the hand tool, hover a pin to read its note (the popup's 📌 pin keeps it open), click a pin
to open the note pinned, double-click to edit it, or drag the pin. Right-click a pin for a menu:
Edit journal entry, Delete pin and journal entry, or Delete pin, keep journal entry.
The bar at the bottom of the map does the same.
Hexcrawl. On a hex grid, tick Hexcrawl under Grid. Hexes you have not explored are shaded; the binoculars tool marks a hex explored (click again to undo). Hex numbers shows each hex's column and row, for example 0412. In hexcrawl mode, a pin sits in the middle of its hex, and its note is named after the hex.