Compare commits

...

71 Commits

Author SHA1 Message Date
silverwizard b111f67737 Fixed Femme/Homme Fatale cost 7 months ago
silverwizard 0b47e3c2ba Merge pull request 'Make Citadel Born a born path' (#17) from citadel-born into main 10 months ago
Daniel Asher Resnick 6c7f6b6892 Make Citadel Born a born path 10 months ago
silverwizard 4c7c465d90 Merge pull request 'revised_updates' (#16) from revised_updates into main 11 months ago
silverwizard e1a4b0d5a0 Fixed Catalyst trait name 11 months ago
silverwizard c9ef5c471b Updated catamite to catalyst 11 months ago
silverwizard ff880ad070 Updated Ganymede 11 months ago
silverwizard 9e6c927b94 Added Knight changes for Gold's revision 11 months ago
Daniel Asher Resnick 32c91f437d Merge pull request 'Custom stock files and data' (#11) from custom-stocks into main 1 year ago
Daniel Asher Resnick 381c65d44d Version bump for 3.0.0 release 1 year ago
Daniel Asher Resnick 55e8b907b9 3.0.0 Changelog draft 1 year ago
Daniel Asher Resnick cc968e00e6 Merge branch 'main' into born-expansion 1 year ago
silverwizard a70066040d Merge pull request 'ruby3.1' (#15) from ruby3.1 into main 1 year ago
silverwizard ae5d477767 Added Building comments and tools for running without Docker 1 year ago
silverwizard fbbcb5c786 Updated to allow Ruby 3.1 1 year ago
Daniel Asher Resnick 52ec9d5db7 Fix settings logic 2 years ago
Daniel Asher Resnick 63a8e05401 Check subsetting based on new born property 2 years ago
Daniel Asher Resnick e9361b625b Check for born using property instead of name 2 years ago
Daniel Asher Resnick bac1626f31 Add 'born' field to born lifepaths 2 years ago
Daniel Asher Resnick 2d6d534798 Denote intended release of 3.0 2 years ago
Daniel Asher Resnick 071ebe801d Use ko_deep_merge for incremental data removal 2 years ago
Daniel Asher Resnick 582379787f Introduce deep_merge 2 years ago
Daniel Asher Resnick 00e3f569fe Increase information in burning-service debugging 2 years ago
Daniel Asher Resnick c7306cbacf Add data for a test stock 2 years ago
Daniel Asher Resnick 2fd4b625ce Fix custom stock loading using put_or_merge 2 years ago
Daniel Asher Resnick 6e7c8237a7 Define put_or_merge 2 years ago
Daniel Asher Resnick 0b3e725c85 Actually implement custom stock loading... 2 years ago
Daniel Asher Resnick 48cda4860a Merge branch 'main' into custom-stocks 2 years ago
Daniel Asher Resnick a3fe5f508a Merge branch 'stock-ruby-class' into custom-stocks 2 years ago
Daniel Asher Resnick c8adc19846 Load stock data on stock change or char upload 2 years ago
Daniel Asher Resnick 30f477a2e0 Replace BurningData events with Promise handlers 2 years ago
Daniel Asher Resnick 0782b4465e Debug behaviour should default to false 2 years ago
Daniel Asher Resnick 42ffa31a3f Remove debug logging 2 years ago
Daniel Asher Resnick a98115c647 Use Fetch API and thenify BurningData 2 years ago
Daniel Asher Resnick 849b957a7b Wrap (and update loading of) resources 2 years ago
Daniel Asher Resnick 38a49c8327 Switch all lifepath files to wrapped format 2 years ago
Daniel Asher Resnick 4b4b847644 Move some lifepaths to wrapped format 2 years ago
Daniel Asher Resnick f5d94d1d67 wip 2 years ago
Daniel Asher Resnick 5091396638 Merge branch 'stock-ruby-class' into custom-stocks 2 years ago
Daniel Asher Resnick c4e93b2142 Merge branch 'main' into custom-stocks 2 years ago
silverwizard bc14e42e94 Merge pull request 'Fix spite shade calculation' (#7) from fix-spite-shade into main 2 years ago
Daniel Asher Resnick 74ed09d830 Lookup stocks by adjective field 2 years ago
Daniel Asher Resnick bb908d9bfd Add adjectives to stock files 2 years ago
Daniel Asher Resnick 117365ed8e Fix angular interpolation error 2 years ago
Daniel Asher Resnick fc9edd2b48 On demand data loading 2 years ago
Daniel Asher Resnick 302f758bf0 Replace references to stock_objs with just stocks 2 years ago
Daniel Asher Resnick 897b9ca58c Remove now-redundant stocks key in the data object 2 years ago
Daniel Asher Resnick e1b52b08f5 Fixed some code referencing starting starts 2 years ago
Daniel Asher Resnick e3077d6048 Delete starting stats files 2 years ago
Daniel Asher Resnick a6366b0c7b Remove common traits from lifepaths 2 years ago
Daniel Asher Resnick 4e7d70c51f Use starting stat data from stock objects 2 years ago
Daniel Asher Resnick e7b487f8a3 Remove settings from stock object 2 years ago
Daniel Asher Resnick 0d92d0beb2 Use common traits from stock object 2 years ago
Daniel Asher Resnick 19e2ba9657 Use stride data from stock objects 2 years ago
Daniel Asher Resnick c7a3335bec Load new-style stock files 2 years ago
Daniel Asher Resnick 9d3c8b8870 Add new style stock files for Gold stocks 2 years ago
Daniel Asher Resnick e5d478786e In js, load stock data from stock_objs 2 years ago
Daniel Asher Resnick 8ec40eba13 Load troll data 2 years ago
Daniel Asher Resnick cf351b0c24 wip 2 years ago
Daniel Asher Resnick 3f5b2f4219 Stub expanded stock class 2 years ago
Daniel Asher Resnick 43cca46dde Begin moving stock data to objects 2 years ago
Daniel Asher Resnick d4596c9934 Fix spite shade calculation 2 years ago
Daniel Asher Resnick 988312d9c4 Merge pull request 'add_test_characters' (#6) from add_test_characters into main 2 years ago
silverwizard e8b978dfc6 Added a bonkers and weird human sorcerer/priest 2 years ago
silverwizard df40f50768 Added a dark elf in order to confirm how spite works 2 years ago
silverwizard 180bd6533b Merge pull request 'fix link syntax in README' (#2) from fix-readme-links into main 2 years ago
Daniel Asher Resnick a0bf078d52 fix link syntax in README 2 years ago
Daniel Asher Resnick c4c9c9fc39 Merge pull request 'Updated to new Charred Gold branding' (#1) from improve-branding into main 2 years ago
sdjfhsihfjkdsahafjklsadh ee3350764d Updated to new Charred Gold branding 2 years ago
Daniel Asher Resnick 7d8540d69a Stub custom stock parsing 2 years ago
Daniel Asher Resnick cbcbd23955 wip 2 years ago
  1. 10
      CHANGELOG.md
  2. 5
      Gemfile
  3. 82
      Gemfile.lock
  4. 47
      README.md
  5. 16
      src/app.rb
  6. 1
      src/data/custom/.gitignore
  7. 549
      src/data/dark_elf/lifepaths.json
  8. 231
      src/data/dark_elf/resources.json
  9. 2
      src/data/dark_elf/traits.json
  10. 3837
      src/data/gold/lifepaths/dwarf.json
  11. 3968
      src/data/gold/lifepaths/elf.json
  12. 23369
      src/data/gold/lifepaths/man.json
  13. 3059
      src/data/gold/lifepaths/orc.json
  14. 3323
      src/data/gold/lifepaths/roden.json
  15. 1833
      src/data/gold/lifepaths/wolf.json
  16. 307
      src/data/gold/resources/dwarf.json
  17. 355
      src/data/gold/resources/elf.json
  18. 871
      src/data/gold/resources/man.json
  19. 425
      src/data/gold/resources/orc.json
  20. 281
      src/data/gold/resources/roden.json
  21. 87
      src/data/gold/resources/wolf.json
  22. 114
      src/data/gold/starting_stat_pts/dwarf.json
  23. 146
      src/data/gold/starting_stat_pts/elf.json
  24. 90
      src/data/gold/starting_stat_pts/man.json
  25. 98
      src/data/gold/starting_stat_pts/orc.json
  26. 74
      src/data/gold/starting_stat_pts/roden.json
  27. 58
      src/data/gold/starting_stat_pts/wolf.json
  28. 130
      src/data/gold/stocks/dwarf.json
  29. 161
      src/data/gold/stocks/elf.json
  30. 99
      src/data/gold/stocks/man.json
  31. 114
      src/data/gold/stocks/orc.json
  32. 90
      src/data/gold/stocks/roden.json
  33. 75
      src/data/gold/stocks/wolf.json
  34. 8
      src/data/gold/traits.json
  35. 1149
      src/data/troll/lifepaths.json
  36. 117
      src/data/troll/resources.json
  37. 82
      src/data/troll/starting_stat_pts.json
  38. 100
      src/data/troll/stock.json
  39. 2330
      src/data/wizard/lifepaths.json
  40. 13
      src/lib/data.rb
  41. 27
      src/lib/data/custom.rb
  42. 6
      src/lib/data/dark_elf.rb
  43. 20
      src/lib/data/gold.rb
  44. 15
      src/lib/data/troll.rb
  45. 3
      src/lib/data/wizard.rb
  46. 34
      src/lib/stock.rb
  47. 11
      src/public/js/burning-serialize.js
  48. 197
      src/public/js/burning-service.js
  49. 230
      src/public/js/burning.js
  50. 2
      src/public/js/server_settings.js
  51. 2
      src/views/index.erb
  52. 2
      src/views/partials/help.erb
  53. 9
      src/views/partials/main.erb
  54. 1
      tests/Algoric the Apologist Character Sheet.char
  55. 1
      tests/Algoric the Apologist Character Sheet.model
  56. 1
      tests/Tyastanarphen Character Sheet.char
  57. 1
      tests/Tyastanarphen Character Sheet.model
  58. 133
      tests/data/custom/test.lifepaths
  59. 25
      tests/data/custom/test.resources
  60. 39
      tests/data/custom/test.skills
  61. 95
      tests/data/custom/test.stock
  62. 55
      tests/data/custom/test.traits

@ -11,6 +11,16 @@ and this project adheres to [Semantic Versioning](semver).
- Custom upload for your own data files
- Updates to Roden and Great Wolves files (currently the data comes from Monster Burner and not Codex)
## [3.0.0] - 2023-09-03
### Added
- Custom stocks can now be added to a server
- Stock data moved from code to dedicated data file
- Data files split into stock, lifepath, skills, and traits files, with designated extensions
- "Born" lifepaths with arbitrary names
### Fixed
- Spite shade calculation
## [2.3.0] - 2019-07-28
### Added
- Display emotional attribute traits on PDF

@ -3,8 +3,9 @@ source 'https://rubygems.org'
gem 'thin'
gem 'sinatra'
gem 'sinatra-contrib'
gem 'prawn', '2.2.2'
gem 'prawn-templates', '0.1.1'
gem 'prawn'
gem 'prawn-templates'
gem 'deep_merge', '~> 1.2', '>= 1.2.1'
group :development do
gem 'rerun'

@ -1,71 +1,71 @@
GEM
remote: https://rubygems.org/
specs:
Ascii85 (1.0.3)
Ascii85 (1.1.0)
afm (0.2.2)
backports (3.15.0)
daemons (1.3.1)
daemons (1.4.1)
deep_merge (1.2.2)
eventmachine (1.2.7)
ffi (1.11.1)
ffi (1.15.5)
hashery (2.1.2)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
multi_json (1.13.1)
mustermann (1.0.3)
pdf-core (0.7.0)
pdf-reader (2.2.0)
Ascii85 (~> 1.0.0)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
multi_json (1.15.0)
mustermann (3.0.0)
ruby2_keywords (~> 0.0.1)
pdf-core (0.9.0)
pdf-reader (2.11.0)
Ascii85 (~> 1.0)
afm (~> 0.2.1)
hashery (~> 2.0)
ruby-rc4
ttfunk
prawn (2.2.2)
pdf-core (~> 0.7.0)
ttfunk (~> 1.5)
prawn-templates (0.1.1)
prawn (2.4.0)
pdf-core (~> 0.9.0)
ttfunk (~> 1.7)
prawn-templates (0.1.2)
pdf-reader (~> 2.0)
prawn (~> 2.2)
rack (2.0.7)
rack-protection (2.0.5)
rack
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
rack (2.2.8)
rack-protection (3.1.0)
rack (~> 2.2, >= 2.2.4)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rerun (0.13.0)
rerun (0.14.0)
listen (~> 3.0)
ruby-rc4 (0.1.5)
ruby_dep (1.5.0)
sinatra (2.0.5)
mustermann (~> 1.0)
rack (~> 2.0)
rack-protection (= 2.0.5)
ruby2_keywords (0.0.5)
sinatra (3.1.0)
mustermann (~> 3.0)
rack (~> 2.2, >= 2.2.4)
rack-protection (= 3.1.0)
tilt (~> 2.0)
sinatra-contrib (2.0.5)
backports (>= 2.8.2)
sinatra-contrib (3.1.0)
multi_json
mustermann (~> 1.0)
rack-protection (= 2.0.5)
sinatra (= 2.0.5)
tilt (>= 1.3, < 3)
thin (1.7.2)
mustermann (~> 3.0)
rack-protection (= 3.1.0)
sinatra (= 3.1.0)
tilt (~> 2.0)
thin (1.8.2)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
tilt (2.0.9)
ttfunk (1.5.1)
tilt (2.2.0)
ttfunk (1.7.0)
PLATFORMS
ruby
x86_64-linux
DEPENDENCIES
prawn (= 2.2.2)
prawn-templates (= 0.1.1)
deep_merge (~> 1.2, >= 1.2.1)
prawn
prawn-templates
rerun
sinatra
sinatra-contrib
thin
BUNDLED WITH
1.17.2
2.3.7

@ -1,14 +1,10 @@
# Charred Gold
This is a fork of [https://github.com/modality/charred-black](Charred Black)
Below is the original README of Charred Black, possibly to be updated in the future;
especially since there is a departure from some of the original values.
The unofficial, online, Burning Wheel Gold (+Codex) character burner. Adapted from [Charred](https://charred.herokuapp.com/).
This is a fork of [Charred Black](https://github.com/modality/charred-black) Below is a partial fork of the original README of Charred Black; especially since there is a departure from some of the original values. The unofficial, online, Burning Wheel Gold (+Codex) character burner. Adapted from [Charred](https://charred.herokuapp.com/). Later adapted from [Charred Black](https://github.com/modality/charred-black)
## Project Structure
* `Dockerfile` and `Dockerfile.dev` - Container definition files. The dev container has automated reloading if you mount the container's filesystem to the host machine. If you are unfamiliar with Docker, this app uses Sinatra and you can _probably_ get by with a bundle install and `ruby ./src/app.rb`.
* `Dockerfile` and `Dockerfile.dev` - Container definition files. The dev container has automated reloading if you mount the container's filesystem to the host machine. These mostly serve as examples to launch the app yourself, and are no longer supported. The app uses Sinatra to hope, and you should just be able to `bundle install` and then run `ruby app.rb` from the source directory. I will try to publish a SysV initscript soon.
* `src/data` - Binaries and data files for lifepaths live here, see `dark_elf` and `wizard` directory for well-defined examples
* `src/lib` - Ruby scripts for caching, PDF generation, and data loading
* `src/public` - Javascript and CSS
@ -17,38 +13,27 @@ The unofficial, online, Burning Wheel Gold (+Codex) character burner. Adapted fr
## Beliefs
I welcome community contributions, and you are welcome to fork this source code if you want to go your own way. As the maintainer,
here's what you can expect from me when I judge contributions.
We welcome community contributions, and you are welcome to fork this source code if you want to go your own way. As the maintainer, here's what you can expect from me when I judge contributions.
### Do One Thing Well
Charred Black is a character creation utility. You are welcome to use the data, source code, or character files in the creation
of other gaming tools, but let's keep this tool focused on one thing and do it really well.
Charred Gold is a character creation utility. You are welcome to use the data, source code, or character files in the creation of other gaming tools, but let's keep this tool focused on one thing and do it really well.
### Stick To Published Material
In order to keep the scope of my maintainership finite, I'm not planning to accept community-made lifepaths et al. for inclusion
in this codebase. Each additional data set increases Charred Black's startup time and memory requirements. The design of your lifepath
requirements and emotional attributes may not be supported by the editor, or may be convoluted to implement. Most importantly, deciding to include any community-made content makes me an arbiter of quality, and I'd prefer not to have the Enmity Clause invoked because I rejected
someone's homebrew.
In order to keep the scope of my maintainership finite, I'm not planning to accept community-made lifepaths et al. for inclusion in this codebase. Each additional data set increases Charred Gold's startup time and memory requirements. The design of your lifepath requirements and emotional attributes may not be supported by the editor, or may be convoluted to implement. Most importantly, deciding to include any community-made content makes me an arbiter of quality, and I'd prefer not to have the Enmity Clause invoked because I rejected someone's homebrew.
**However**, I am working on a solution for uploading lifepaths et. al which would be stored locally in your browser and not permanently on
a server. This way, you can create data files to use with this tool and share them with your friends. If someone else
wants to keep a repository or forum thread of data files known to work with Charred Black, I am happy to link to it in this
documentation and from the website itself. I don't want to discourage contributions, I just want do one thing well.
The current maintainers of Charred Gold are working on some tooling to allow "easy" creation of new settings, stocks, LPs, and so on. The exact method for handling has not been decided precisely.
### Keep It Mostly Stateless
Charred Black uses an in-memory cache to allow users to upload JSON and then download .char and .pdf files. I don't know how the
original Charred handled this, but the tradeoffs of this approach are:
Charred Gold uses an in-memory cache to allow users to upload JSON and then download .char and .pdf files. I don't know how the original Charred handled this, but the tradeoffs of this approach are:
1. Works as expected without an update to the frontend
2. PDF generation happens entirely in one process, limiting the amount of futzing you have to do with distributed systems
3. Because the cache is in memory, you can't scale processes horizontally
The cache has a limited number of keys, and only the first 16kb of data are used, with the aim of making this this app useless
for nefarious purposes. The average size of a 4-lifepath character is around 4kb, so this should be more than enough. If you're
trying to do something weird and your character file is bigger than this, consider using a pencil and paper.
The cache has a limited number of keys, and only the first 16kb of data are used, with the aim of making this this app useless for nefarious purposes. The average size of a 4-lifepath character is around 4kb, so this should be more than enough. If you're trying to do something weird and your character file is bigger than this, consider using a pencil and paper.
More guidelines:
@ -141,3 +126,19 @@ Some notes:
}
}
```
# Building
Requires Ruby 3.1 or better for support.
On Debian or derivatives this requires `apt-get install ruby-dev` in order to allow eventmachine to work (which is a hard dependency for thin, the webserver we're using for charred.
In order to run in normal use, simply run:
```
# sudo apt-get install ruby-dev bundler
# bundler install # on some distros this might be bundler3.1
# cd src
# HOST=0.0.0.0 PORT=7878 RACK_ENV=production ruby app.rb
```

@ -49,24 +49,20 @@ get '/traits' do
json DATA[:traits]
end
get '/lifepaths/:stock' do
if DATA[:stocks].include? params['stock']
json DATA[:lifepaths][params['stock']]
else
404
end
get '/stocks' do
json DATA[:stocks]
end
get '/starting_stat_pts/:stock' do
if DATA[:stocks].include? params['stock']
json DATA[:stat_pts][params['stock']]
get '/lifepaths/:stock' do
if DATA[:stocks].keys.include? params['stock']
json DATA[:lifepaths][params['stock']]
else
404
end
end
get '/resources/:stock' do
if DATA[:stocks].include? params['stock']
if DATA[:stocks].keys.include? params['stock']
json DATA[:resources][params['stock']]
else
404

@ -1,296 +1,299 @@
{
"Path Of Spite Subsetting": {
"Griever": {
"time": 3,
"res": 0,
"skills": [
[
3,
"Sorrow Of Truth",
"Dark Elf-wise"
]
],
"traits": [
1,
"Spite"
]
},
"Wastrel": {
"time": 25,
"res": 3,
"skills": [
[
6,
"Scavenging",
"Brawling",
"Forest-wise",
"Wasteland-wise",
"Animal-wise"
]
],
"traits": [
2,
"Filthy",
"Feral Elf"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
},
"Thief": {
"time": 18,
"res": 6,
"stat": [
[
"stock": "elf",
"settings": {
"Path Of Spite Subsetting": {
"Griever": {
"time": 3,
"res": 0,
"skills": [
[
3,
"Sorrow Of Truth",
"Dark Elf-wise"
]
],
"traits": [
1,
"pm"
"Spite"
]
],
"skills": [
[
6,
"Lock Pick",
"Stealthy",
"Climbing",
"Sleight Of Hand",
"Dirge Of Night"
},
"Wastrel": {
"time": 25,
"res": 3,
"skills": [
[
6,
"Scavenging",
"Brawling",
"Forest-wise",
"Wasteland-wise",
"Animal-wise"
]
],
"traits": [
2,
"Filthy",
"Feral Elf"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
],
"traits": [
1,
"Thief"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
},
"Assassin": {
"time": 15,
"res": 6,
"stat": [
[
},
"Thief": {
"time": 18,
"res": 6,
"stat": [
[
1,
"pm"
]
],
"skills": [
[
6,
"Lock Pick",
"Stealthy",
"Climbing",
"Sleight Of Hand",
"Dirge Of Night"
]
],
"traits": [
1,
"p"
]
],
"skills": [
[
7,
"Intimidation",
"Poisons",
"Escape Artist",
"Knives",
"Garotte",
"Keen Of Terror"
]
],
"traits": [
1,
"Murderous",
"Callous",
"Cold Blooded"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
},
"Stalker": {
"time": 20,
"res": 8,
"skills": [
[
8,
"Hunting",
"Elf-wise",
"Tracking",
"Trapper",
"Observation",
"Stealthy",
"Throwing",
"Javelin",
"Supplication To Shadows"
"Thief"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
],
"traits": [
1,
"Saturnine"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
},
"Deceiver": {
"time": 35,
"res": 10,
"stat": [
[
},
"Assassin": {
"time": 15,
"res": 6,
"stat": [
[
1,
"p"
]
],
"skills": [
[
7,
"Intimidation",
"Poisons",
"Escape Artist",
"Knives",
"Garotte",
"Keen Of Terror"
]
],
"traits": [
1,
"m"
]
],
"skills": [
[
7,
"Sleight Of Hand",
"Disguise",
"Inconspicuous",
"Rhyme Of The Unraveller"
"Murderous",
"Callous",
"Cold Blooded"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
],
"traits": [
1,
"Deceptive"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
},
"Liar": {
"time": 25,
"res": 8,
"stat": [
[
},
"Stalker": {
"time": 20,
"res": 8,
"skills": [
[
8,
"Hunting",
"Elf-wise",
"Tracking",
"Trapper",
"Observation",
"Stealthy",
"Throwing",
"Javelin",
"Supplication To Shadows"
]
],
"traits": [
1,
"m"
]
],
"skills": [
[
6,
"Falsehood",
"Soothing Platitudes",
"Persuasion",
"Twisted Tongue"
"Saturnine"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
],
"traits": [
1,
"Compulsive Liar"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
},
"Siren": {
"time": 55,
"res": 20,
"stat": [
[
},
"Deceiver": {
"time": 35,
"res": 10,
"stat": [
[
1,
"m"
]
],
"skills": [
[
7,
"Sleight Of Hand",
"Disguise",
"Inconspicuous",
"Rhyme Of The Unraveller"
]
],
"traits": [
1,
"pm"
]
],
"skills": [
[
9,
"Seduction",
"Etiquette",
"Persuasion",
"Soothing Platitudes",
"Gossip-wise",
"Fugue Of Discord",
"Litany Of Fools"
"Deceptive"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
],
"traits": [
2,
"Charismatic",
"Femme Fatale/Homme Fatale"
],
"requires": "Assassin, Deceiver or Liar",
"requires_expr": [
"assassin",
"deceiver",
"liar"
]
},
"Eremite": {
"time": 150,
"res": 15,
"stat": [
[
},
"Liar": {
"time": 25,
"res": 8,
"stat": [
[
1,
"m"
]
],
"skills": [
[
6,
"Falsehood",
"Soothing Platitudes",
"Persuasion",
"Twisted Tongue"
]
],
"traits": [
1,
"m"
]
],
"skills": [
[
12,
"Philosophy",
"Ugly Truth",
"Obscure History",
"Symbology",
"Strategy",
"Elf-wise",
"Orc-wise",
"Dwarf-wise",
"Man-wise",
"Paean To The Dark Fire"
"Compulsive Liar"
],
"requires": "Griever",
"requires_expr": [
"griever"
]
],
"traits": [
2,
"Remote",
"Cold"
],
"requires": "Siren, Wastrel or Stalker",
"requires_expr": [
"siren",
"wastrel",
"stalker"
]
},
"Recluse": {
"time": 225,
"res": 25,
"stat": [
[
1,
"p"
},
"Siren": {
"time": 55,
"res": 20,
"stat": [
[
1,
"pm"
]
],
"skills": [
[
9,
"Seduction",
"Etiquette",
"Persuasion",
"Soothing Platitudes",
"Gossip-wise",
"Fugue Of Discord",
"Litany Of Fools"
]
],
"traits": [
2,
"Charismatic",
"Femme Fatale/Homme Fatale"
],
"requires": "Assassin, Deceiver or Liar",
"requires_expr": [
"assassin",
"deceiver",
"liar"
]
],
"skills": [
[
},
"Eremite": {
"time": 150,
"res": 15,
"stat": [
[
1,
"m"
]
],
"skills": [
[
12,
"Philosophy",
"Ugly Truth",
"Obscure History",
"Symbology",
"Strategy",
"Elf-wise",
"Orc-wise",
"Dwarf-wise",
"Man-wise",
"Paean To The Dark Fire"
]
],
"traits": [
2,
"Ancient History",
"Dwarf-wise",
"Elven Politics-wise",
"Cut Of The Quickened Mind"
"Remote",
"Cold"
],
[
5,
"General"
"requires": "Siren, Wastrel or Stalker",
"requires_expr": [
"siren",
"wastrel",
"stalker"
]
],
"traits": [
1,
"Vengeful"
],
"requires": "Eremite or any three Dark Elf lifepaths",
"requires_expr": [
"+or",
[
"eremite"
},
"Recluse": {
"time": 225,
"res": 25,
"stat": [
[
1,
"p"
]
],
"skills": [
[
2,
"Ancient History",
"Dwarf-wise",
"Elven Politics-wise",
"Cut Of The Quickened Mind"
],
[
5,
"General"
]
],
"traits": [
1,
"Vengeful"
],
[
"+has_n_lifepaths_in",
3,
"path of spite subsetting:griever",
"path of spite subsetting:wastrel",
"path of spite subsetting:thief",
"path of spite subsetting:assassin",
"path of spite subsetting:stalker",
"path of spite subsetting:deceiver",
"path of spite subsetting:liar",
"path of spite subsetting:siren"
"requires": "Eremite or any three Dark Elf lifepaths",
"requires_expr": [
"+or",
[
"eremite"
],
[
"+has_n_lifepaths_in",
3,
"path of spite subsetting:griever",
"path of spite subsetting:wastrel",
"path of spite subsetting:thief",
"path of spite subsetting:assassin",
"path of spite subsetting:stalker",
"path of spite subsetting:deceiver",
"path of spite subsetting:liar",
"path of spite subsetting:siren"
]
]
]
}
}
}
}

@ -1,114 +1,117 @@
[
{
"name": "Bitter Poison",
"type": "gear",
"rp": 10
},
{
"name": "Spiteful Poison",
"type": "gear",
"rp": 20
},
{
"name": "Lock Picks",
"type": "gear",
"rp": 10
},
{
"name": "Long Knife",
"type": "gear",
"rp": 5
},
{
"name": "Barbed Javelins",
"type": "gear",
"rp": 3
},
{
"name": "Garrote",
"type": "gear",
"rp": 3
},
{
"name": "Caltrops",
"type": "gear",
"rp": 3
},
{
"name": "Tools Of The Trade",
"type": "gear",
"rp": 9
},
{
"name": "Cloak Of Darkness",
"type": "gear",
"rp": 30
},
{
"name": "Climbing Claws",
"type": "gear",
"rp": 5
},
{
"name": "Remote Refuge",
"type": "property",
"resources": [
{
"name": "Wasteland",
"rp": 20
},
{
"name": "Isolated Manor And Moorland",
"rp": 50
},
{
"name": "Hidden Fortress",
"rp": 100
},
{
"name": "Dark Forest, Cove Or Lonely Mountain",
"rp": 150
},
{
"name": "Safe House",
"rp": 25
}
]
},
{
"name": "Morlin Armor",
"type": "gear",
"resources": [
{
"name": "Light Mail",
"rp": 30
},
{
"name": "Heavy Mail",
"rp": 40
},
{
"name": "Plated Mail",
"rp": 100
}
]
},
{
"name": "Morlin Weapons",
"type": "gear",
"resources": [
{
"name": "+1 speed",
"rp": 15
},
{
"name": "+1 VA",
"rp": 15
},
{
"name": "+1 Power",
"rp": 30
}
]
}
]
{
"stock": "elf",
"resources": [
{
"name": "Bitter Poison",
"type": "gear",
"rp": 10
},
{
"name": "Spiteful Poison",
"type": "gear",
"rp": 20
},
{
"name": "Lock Picks",
"type": "gear",
"rp": 10
},
{
"name": "Long Knife",
"type": "gear",
"rp": 5
},
{
"name": "Barbed Javelins",
"type": "gear",
"rp": 3
},
{
"name": "Garrote",
"type": "gear",
"rp": 3
},
{
"name": "Caltrops",
"type": "gear",
"rp": 3
},
{
"name": "Tools Of The Trade",
"type": "gear",
"rp": 9
},
{
"name": "Cloak Of Darkness",
"type": "gear",
"rp": 30
},
{
"name": "Climbing Claws",
"type": "gear",
"rp": 5
},
{
"name": "Remote Refuge",
"type": "property",
"resources": [
{
"name": "Wasteland",
"rp": 20
},
{
"name": "Isolated Manor And Moorland",
"rp": 50
},
{
"name": "Hidden Fortress",
"rp": 100
},
{
"name": "Dark Forest, Cove Or Lonely Mountain",
"rp": 150
},
{
"name": "Safe House",
"rp": 25
}
]
},
{
"name": "Morlin Armor",
"type": "gear",
"resources": [
{
"name": "Light Mail",
"rp": 30
},
{
"name": "Heavy Mail",
"rp": 40
},
{
"name": "Plated Mail",
"rp": 100
}
]
},
{
"name": "Morlin Weapons",
"type": "gear",
"resources": [
{
"name": "+1 speed",
"rp": 15
},
{
"name": "+1 VA",
"rp": 15
},
{
"name": "+1 Power",
"rp": 30
}
]
}
]
}

@ -10,7 +10,7 @@
"desc": "The Deceptive trait acts as a call-on for Sleight of Hand and Falsehood. However this trait so infuses the liar, he has a hard time telling the truth. Deceptive also incurs a +1 Ob penalty to Oratory, Command tests and a +2 Ob to Ugly Truth or Litany of Fools."
},
"Femme Fatale/Homme Fatale": {
"cost": 1,
"cost": 2,
"type": "call_on",
"desc": "Call-on for Seduction."
},

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,152 +1,155 @@
[
{
"name": "Shoddy Arms",
"rp": 5,
"type": "gear"
},
{
"name": "Dwarven Arms",
"rp": 20,
"type": "gear"
},
{
"name": "Shoddy Crossbow",
"rp": 6,
"type": "gear"
},
{
"name": "Dwarven Arbalest",
"rp": 20,
"type": "gear"
},
{
"name": "Dwarven-made Light Mail",
"rp": 9,
"type": "gear"
},
{
"name": "Dwarven-made Heavy Mail",
"rp": 10,
"type": "gear"
},
{
"name": "Dwarven-made Plated Mail",
"rp": 20,
"type": "gear"
},
{
"name": "Dwarven Mail",
"rp": 100,
"type": "gear"
},
{
"name": "Forge Mask",
"rp": 40,
"type": "gear"
},
{
"name": "Dwarven Shield",
"rp": 20,
"type": "gear"
},
{
"name": "Riding Mount Or Pack Animal",
"rp": 8,
"type": "gear"
},
{
"name": "Clothes",
"rp": 1,
"type": "gear"
},
{
"name": "Traveling Gear",
"rp": 1,
"type": "gear"
},
{
"name": "Sturdy Shoes",
"rp": 1,
"type": "gear"
},
{
"name": "Finery",
"rp": 5,
"type": "gear"
},
{
"name": "Chronicles",
"rp": 15,
"type": "gear"
},
{
"name": "Keg O' Nog",
"rp": 20,
"type": "gear"
},
{
"name": "Small Dwarven House",
"rp": 10,
"type": "property"
},
{
"name": "Large Dwarven House",
"rp": 15,
"type": "property"
},
{
"name": "A Dwarven Hall",
"rp": 30,
"type": "property"
},
{
"name": "A Graybeard's Hold",
"rp": 40,
"type": "property"
},
{
"name": "An Engineer's Hold",
"rp": 45,
"type": "property"
},
{
"name": "A Master Artificer's Hold",
"rp": 60,
"type": "property"
},
{
"name": "A Warden's Hold",
"rp": 75,
"type": "property"
},
{
"name": "A High Captain's Hold",
"rp": 90,
"type": "property"
},
{
"name": "A Prince's Hold",
"rp": 105,
"type": "property"
},
{
"name": "A Workshop",
"rp": 60,
"type": "property"
},
{
"name": "Dwarven Tools",
"rp": 10,
"type": "gear"
},
{
"name": "Shoddy Tools",
"rp": 5,
"type": "gear"
},
{
"name": "Carts And Baggage",
"rp": 15,
"type": "gear"
}
]
{
"stock": "dwarf",
"resources": [
{
"name": "Shoddy Arms",
"rp": 5,
"type": "gear"
},
{
"name": "Dwarven Arms",
"rp": 20,
"type": "gear"
},
{
"name": "Shoddy Crossbow",
"rp": 6,
"type": "gear"
},
{
"name": "Dwarven Arbalest",
"rp": 20,
"type": "gear"
},
{
"name": "Dwarven-made Light Mail",
"rp": 9,
"type": "gear"
},
{
"name": "Dwarven-made Heavy Mail",
"rp": 10,
"type": "gear"
},
{
"name": "Dwarven-made Plated Mail",
"rp": 20,
"type": "gear"
},
{
"name": "Dwarven Mail",
"rp": 100,
"type": "gear"
},
{
"name": "Forge Mask",
"rp": 40,
"type": "gear"
},
{
"name": "Dwarven Shield",
"rp": 20,
"type": "gear"
},
{
"name": "Riding Mount Or Pack Animal",
"rp": 8,
"type": "gear"
},
{
"name": "Clothes",
"rp": 1,
"type": "gear"
},
{
"name": "Traveling Gear",
"rp": 1,
"type": "gear"
},
{
"name": "Sturdy Shoes",
"rp": 1,
"type": "gear"
},
{
"name": "Finery",
"rp": 5,
"type": "gear"
},
{
"name": "Chronicles",
"rp": 15,
"type": "gear"
},
{
"name": "Keg O' Nog",
"rp": 20,
"type": "gear"
},
{
"name": "Small Dwarven House",
"rp": 10,
"type": "property"
},
{
"name": "Large Dwarven House",
"rp": 15,
"type": "property"
},
{
"name": "A Dwarven Hall",
"rp": 30,
"type": "property"
},
{
"name": "A Graybeard's Hold",
"rp": 40,
"type": "property"
},
{
"name": "An Engineer's Hold",
"rp": 45,
"type": "property"
},
{
"name": "A Master Artificer's Hold",
"rp": 60,
"type": "property"
},
{
"name": "A Warden's Hold",
"rp": 75,
"type": "property"
},
{
"name": "A High Captain's Hold",
"rp": 90,
"type": "property"
},
{
"name": "A Prince's Hold",
"rp": 105,
"type": "property"
},
{
"name": "A Workshop",
"rp": 60,
"type": "property"
},
{
"name": "Dwarven Tools",
"rp": 10,
"type": "gear"
},
{
"name": "Shoddy Tools",
"rp": 5,
"type": "gear"
},
{
"name": "Carts And Baggage",
"rp": 15,
"type": "gear"
}
]
}

@ -1,176 +1,179 @@
[
{
"name": "Run Of The Mill Bow",
"type": "gear",
"rp": 5
},
{
"name": "Run Of The Mill Arms",
"type": "gear",
"rp": 5
},
{
"name": "Reinforced Leather",
"type": "gear",
"rp": 3
},
{
"name": "Light Mail",
"type": "gear",
"rp": 6
},
{
"name": "Heavy Mail",
"type": "gear",
"rp": 10
},
{
"name": "Plated Mail",
"type": "gear",
"rp": 20
},
{
"name": "Elven Armor",
"type": "gear",
"resources": [
{
"name": "Gambeson",
"rp": 9
},
{
"name": "Reinforced Leather",
"resources": null,
"rp": 20
},
{
"name": "Light Mail",
"resources": null,
"rp": 30
},
{
"name": "Heavy Mail",
"rp": 40
},
{
"name": "Plated Mail",
"rp": 75
}
]
},
{
"name": "Elven Arms",
"type": "gear",
"rp": 15
},
{
"name": "Elven Bow",
"type": "gear",
"rp": 25
},
{
"name": "Elven Cloak",
"type": "gear",
"rp": 30
},
{
"name": "Elven Steed",
"type": "gear",
"rp": 8
},
{
"name": "Elven Clothes",
"type": "gear",
"rp": 2
},
{
"name": "Elven Shoes",
"type": "gear",
"rp": 1
},
{
"name": "Elven Finery",
"type": "gear",
"rp": 5
},
{
"name": "Elven Rope",
"type": "gear",
"rp": 12
},
{
"name": "Elven Bread",
"type": "gear",
"rp": 10
},
{
"name": "Elven Mirrorwine",
"type": "gear",
"rp": 8
},
{
"name": "Starlight",
"type": "gear",
"rp": 50
},
{
"name": "Tome Of Lore",
"type": "gear",
"rp": 20
},
{
"name": "Elven Instrument",
"type": "gear",
"rp": 6
},
{
"name": "Personal Effects",
"type": "gear",
"rp": 1
},
{
"name": "Elven Smithy",
"type": "property",
"rp": 50
},
{
"name": "Artisan's Shop",
"type": "property",
"rp": 60
},
{
"name": "Skill Tools",
"type": "gear",
"rp": 9
},
{
"name": "Elven Ship",
"type": "gear",
"rp": 80
},
{
"name": "Elven Land",
"type": "property",
"resources": [
{
"name": "Pastoral",
"rp": 20
},
{
"name": "Large Country Manor And Land",
"rp": 50
},
{
"name": "Palace",
"rp": 100
},
{
"name": "A Forest, Bay Or Mountain",
"rp": 150
},
{
"name": "Apartment In The Citadel",
"rp": 25
}
]
}
]
{
"stock": "elf",
"resources": [
{
"name": "Run Of The Mill Bow",
"type": "gear",
"rp": 5
},
{
"name": "Run Of The Mill Arms",
"type": "gear",
"rp": 5
},
{
"name": "Reinforced Leather",
"type": "gear",
"rp": 3
},
{
"name": "Light Mail",
"type": "gear",
"rp": 6
},
{
"name": "Heavy Mail",
"type": "gear",
"rp": 10
},
{
"name": "Plated Mail",
"type": "gear",
"rp": 20
},
{
"name": "Elven Armor",
"type": "gear",
"resources": [
{
"name": "Gambeson",
"rp": 9
},
{
"name": "Reinforced Leather",
"resources": null,
"rp": 20
},
{
"name": "Light Mail",
"resources": null,
"rp": 30
},
{
"name": "Heavy Mail",
"rp": 40
},
{
"name": "Plated Mail",
"rp": 75
}
]
},
{
"name": "Elven Arms",
"type": "gear",
"rp": 15
},
{
"name": "Elven Bow",
"type": "gear",
"rp": 25
},
{
"name": "Elven Cloak",
"type": "gear",
"rp": 30
},
{
"name": "Elven Steed",
"type": "gear",
"rp": 8
},
{
"name": "Elven Clothes",
"type": "gear",
"rp": 2
},
{
"name": "Elven Shoes",
"type": "gear",
"rp": 1
},
{
"name": "Elven Finery",
"type": "gear",
"rp": 5
},
{
"name": "Elven Rope",
"type": "gear",
"rp": 12
},
{
"name": "Elven Bread",
"type": "gear",
"rp": 10
},
{
"name": "Elven Mirrorwine",
"type": "gear",
"rp": 8
},
{
"name": "Starlight",
"type": "gear",
"rp": 50
},
{
"name": "Tome Of Lore",
"type": "gear",
"rp": 20
},
{
"name": "Elven Instrument",
"type": "gear",
"rp": 6
},
{
"name": "Personal Effects",
"type": "gear",
"rp": 1
},
{
"name": "Elven Smithy",
"type": "property",
"rp": 50
},
{
"name": "Artisan's Shop",
"type": "property",
"rp": 60
},
{
"name": "Skill Tools",
"type": "gear",
"rp": 9
},
{
"name": "Elven Ship",
"type": "gear",
"rp": 80
},
{
"name": "Elven Land",
"type": "property",
"resources": [
{
"name": "Pastoral",
"rp": 20
},
{
"name": "Large Country Manor And Land",
"rp": 50
},
{
"name": "Palace",
"rp": 100
},
{
"name": "A Forest, Bay Or Mountain",
"rp": 150
},
{
"name": "Apartment In The Citadel",
"rp": 25
}
]
}
]
}

@ -1,434 +1,437 @@
[
{
"name": "Arms",
"type": "gear",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 5
},
{
"name": "Superior Quality",
"rp": 20
}
]
},
{
"name": "Missile Weapons",
"type": "gear",
"resources": [
{
"name": "Throwing Weapons",
"resources": [
{
"name": "Poor Quality",
"rp": 2
},
{
"name": "Run Of The Mill Quality",
"rp": 3
},
{
"name": "Superior Quality",
"rp": 9
}
]
},
{
"name": "Hunting Bow",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 5
},
{
"name": "Superior Quality",
"rp": 15
}
]
},
{
"name": "Great Bow",
"resources": [
{
"name": "Poor Quality",
"rp": 5
},
{
"name": "Run Of The Mill Quality",
"rp": 10
},
{
"name": "Superior Quality",
"rp": 30
}
]
},
{
"name": "Crossbow",
"resources": [
{
"name": "Poor Quality",
"rp": 4
},
{
"name": "Run Of The Mill Quality",
"rp": 7
},
{
"name": "Superior Quality",
"rp": 21
}
]
},
{
"name": "Heavy Crossbow",
"resources": [
{
"name": "Poor Quality",
"rp": 6
},
{
"name": "Run Of The Mill Quality",
"rp": 12
},
{
"name": "Superior Quality",
"rp": 36
}
]
},
{
"name": "Pistol",
"resources": [
{
"name": "Poor Quality",
"rp": 8
},
{
"name": "Run Of The Mill Quality",
"rp": 15
},
{
"name": "Superior Quality",
"rp": 45
}
]
},
{
"name": "Arquebus",
"resources": [
{
"name": "Poor Quality",
"rp": 10
},
{
"name": "Run Of The Mill Quality",
"rp": 20
},
{
"name": "Superior Quality",
"rp": 60
}
]
}
]
},
{
"name": "Armor",
"type": "gear",
"resources": [
{
"name": "Gambeson",
"resources": [
{
"name": "Poor Quality",
"rp": 2
},
{
"name": "Run Of The Mill Quality",
"rp": 3
},
{
"name": "Superior Quality",
"rp": 12
}
]
},
{
"name": "Reinforced Leather",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 6
},
{
"name": "Superior Quality",
"rp": 24
}
]
},
{
"name": "Light Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 5
},
{
"name": "Run Of The Mill Quality",
"rp": 10
},
{
"name": "Superior Quality",
"rp": 40
}
]
},
{
"name": "Heavy Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 8
},
{
"name": "Run Of The Mill Quality",
"rp": 15
},
{
"name": "Superior Quality",
"rp": 60
}
]
},
{
"name": "Plated Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 10
},
{
"name": "Run Of The Mill Quality",
"rp": 20
},
{
"name": "Superior Quality",
"rp": 80
}
]
},
{
"name": "Full Plated Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 25
},
{
"name": "Run Of The Mill Quality",
"rp": 50
},
{
"name": "Superior Quality",
"rp": 200
}
]
}
]
},
{
"name": "Riding Mount Or Pack Animal",
"rp": 5,
"type": "gear"
},
{
"name": "Warhorse",
"rp": 12,
"type": "gear"
},
{
"name": "Clothes",
"rp": 1,
"type": "gear"
},
{
"name": "Traveling Gear",
"rp": 1,
"type": "gear"
},
{
"name": "Shoes",
"rp": 1,
"type": "gear"
},
{
"name": "Personal Effects",
"rp": 1,
"type": "gear"
},
{
"name": "Finery",
"rp": 5,
"type": "gear"
},
{
"name": "Cash",
"rp": 6,
"type": "gear"
},
{
"name": "Skill Toolkit",
"rp": 8,
"type": "gear"
},
{
"name": "Workshop",
"rp": 20,
"type": "property"
},
{
"name": "Companion Animal",
"rp": 3,
"type": "gear"
},
{
"name": "Herd Of Animals",
"rp": 20,
"type": "property"
},
{
"name": "Rent",
"rp": 5,
"type": "property"
},
{
"name": "Property",
"type": "property",
"resources": [
{
"name": "A Leaky Shack",
"rp": 1
},
{
"name": "A Small Cottage",
"rp": 3
},
{
"name": "A House",
"rp": 10
},
{
"name": "A \"Cottage Industry\" Like A Weaver",
"rp": 10
},
{
"name": "A Villa Or Farm",
"rp": 15
},
{
"name": "A Small Business",
"rp": 20
},
{
"name": "Moderate-sized Business",
"rp": 30
},
{
"name": "A Manor Or Small Estate",
"rp": 40
},
{
"name": "An Urban Hotel",
"rp": 40
},
{
"name": "A Well-paid Position (Like Mayor)",
"rp": 45
},
{
"name": "A Successful Small Business",
"rp": 60
},
{
"name": "A Large Business",
"rp": 60
},
{
"name": "A Keep",
"rp": 60
},
{
"name": "A Fortress",
"rp": 75
},
{
"name": "A Moderate-sized Estate",
"rp": 75
},
{
"name": "A Castle With Attendant Town",
"rp": 90
},
{
"name": "A Large Estate",
"rp": 90
},
{
"name": "A Palace",
"rp": 105
},
{
"name": "A Government Position In A Prosperous Town",
"rp": 105
}
]
},
{
"name": "Boat",
"type": "property",
"resources": [
{
"name": "A Rowboat Or Skiff",
"rp": 5
},
{
"name": "A Longboat",
"rp": 10
},
{
"name": "A Junk",
"rp": 15
},
{
"name": "A Felucca",
"rp": 30
},
{
"name": "A Carrack",
"rp": 60
},
{
"name": "A Caravel",
"rp": 75
},
{
"name": "Treasure Ship",
"rp": 105
}
]
}
]
{
"stock": "man",
"resources": [
{
"name": "Arms",
"type": "gear",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 5
},
{
"name": "Superior Quality",
"rp": 20
}
]
},
{
"name": "Missile Weapons",
"type": "gear",
"resources": [
{
"name": "Throwing Weapons",
"resources": [
{
"name": "Poor Quality",
"rp": 2
},
{
"name": "Run Of The Mill Quality",
"rp": 3
},
{
"name": "Superior Quality",
"rp": 9
}
]
},
{
"name": "Hunting Bow",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 5
},
{
"name": "Superior Quality",
"rp": 15
}
]
},
{
"name": "Great Bow",
"resources": [
{
"name": "Poor Quality",
"rp": 5
},
{
"name": "Run Of The Mill Quality",
"rp": 10
},
{
"name": "Superior Quality",
"rp": 30
}
]
},
{
"name": "Crossbow",
"resources": [
{
"name": "Poor Quality",
"rp": 4
},
{
"name": "Run Of The Mill Quality",
"rp": 7
},
{
"name": "Superior Quality",
"rp": 21
}
]
},
{
"name": "Heavy Crossbow",
"resources": [
{
"name": "Poor Quality",
"rp": 6
},
{
"name": "Run Of The Mill Quality",
"rp": 12
},
{
"name": "Superior Quality",
"rp": 36
}
]
},
{
"name": "Pistol",
"resources": [
{
"name": "Poor Quality",
"rp": 8
},
{
"name": "Run Of The Mill Quality",
"rp": 15
},
{
"name": "Superior Quality",
"rp": 45
}
]
},
{
"name": "Arquebus",
"resources": [
{
"name": "Poor Quality",
"rp": 10
},
{
"name": "Run Of The Mill Quality",
"rp": 20
},
{
"name": "Superior Quality",
"rp": 60
}
]
}
]
},
{
"name": "Armor",
"type": "gear",
"resources": [
{
"name": "Gambeson",
"resources": [
{
"name": "Poor Quality",
"rp": 2
},
{
"name": "Run Of The Mill Quality",
"rp": 3
},
{
"name": "Superior Quality",
"rp": 12
}
]
},
{
"name": "Reinforced Leather",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 6
},
{
"name": "Superior Quality",
"rp": 24
}
]
},
{
"name": "Light Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 5
},
{
"name": "Run Of The Mill Quality",
"rp": 10
},
{
"name": "Superior Quality",
"rp": 40
}
]
},
{
"name": "Heavy Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 8
},
{
"name": "Run Of The Mill Quality",
"rp": 15
},
{
"name": "Superior Quality",
"rp": 60
}
]
},
{
"name": "Plated Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 10
},
{
"name": "Run Of The Mill Quality",
"rp": 20
},
{
"name": "Superior Quality",
"rp": 80
}
]
},
{
"name": "Full Plated Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 25
},
{
"name": "Run Of The Mill Quality",
"rp": 50
},
{
"name": "Superior Quality",
"rp": 200
}
]
}
]
},
{
"name": "Riding Mount Or Pack Animal",
"rp": 5,
"type": "gear"
},
{
"name": "Warhorse",
"rp": 12,
"type": "gear"
},
{
"name": "Clothes",
"rp": 1,
"type": "gear"
},
{
"name": "Traveling Gear",
"rp": 1,
"type": "gear"
},
{
"name": "Shoes",
"rp": 1,
"type": "gear"
},
{
"name": "Personal Effects",
"rp": 1,
"type": "gear"
},
{
"name": "Finery",
"rp": 5,
"type": "gear"
},
{
"name": "Cash",
"rp": 6,
"type": "gear"
},
{
"name": "Skill Toolkit",
"rp": 8,
"type": "gear"
},
{
"name": "Workshop",
"rp": 20,
"type": "property"
},
{
"name": "Companion Animal",
"rp": 3,
"type": "gear"
},
{
"name": "Herd Of Animals",
"rp": 20,
"type": "property"
},
{
"name": "Rent",
"rp": 5,
"type": "property"
},
{
"name": "Property",
"type": "property",
"resources": [
{
"name": "A Leaky Shack",
"rp": 1
},
{
"name": "A Small Cottage",
"rp": 3
},
{
"name": "A House",
"rp": 10
},
{
"name": "A \"Cottage Industry\" Like A Weaver",
"rp": 10
},
{
"name": "A Villa Or Farm",
"rp": 15
},
{
"name": "A Small Business",
"rp": 20
},
{
"name": "Moderate-sized Business",
"rp": 30
},
{
"name": "A Manor Or Small Estate",
"rp": 40
},
{
"name": "An Urban Hotel",
"rp": 40
},
{
"name": "A Well-paid Position (Like Mayor)",
"rp": 45
},
{
"name": "A Successful Small Business",
"rp": 60
},
{
"name": "A Large Business",
"rp": 60
},
{
"name": "A Keep",
"rp": 60
},
{
"name": "A Fortress",
"rp": 75
},
{
"name": "A Moderate-sized Estate",
"rp": 75
},
{
"name": "A Castle With Attendant Town",
"rp": 90
},
{
"name": "A Large Estate",
"rp": 90
},
{
"name": "A Palace",
"rp": 105
},
{
"name": "A Government Position In A Prosperous Town",
"rp": 105
}
]
},
{
"name": "Boat",
"type": "property",
"resources": [
{
"name": "A Rowboat Or Skiff",
"rp": 5
},
{
"name": "A Longboat",
"rp": 10
},
{
"name": "A Junk",
"rp": 15
},
{
"name": "A Felucca",
"rp": 30
},
{
"name": "A Carrack",
"rp": 60
},
{
"name": "A Caravel",
"rp": 75
},
{
"name": "Treasure Ship",
"rp": 105
}
]
}
]
}

@ -1,211 +1,214 @@
[
{
"name": "Rags",
"rp": 1,
"type": "gear"
},
{
"name": "Traveling Gear",
"rp": 3,
"type": "gear"
},
{
"name": "Hobnailed Boots",
"rp": 1,
"type": "gear"
},
{
"name": "Orc Arms",
"type": "gear",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 5
}
]
},
{
"name": "Armor",
"type": "gear",
"resources": [
{
"name": "Hides",
"resources": [
{
"name": "Poor Quality",
"rp": 1
}
]
},
{
"name": "Reinforced Hides",
"resources": [
{
"name": "Poor Quality",
"rp": 3
}
]
},
{
"name": "Reinforced Leather",
"resources": [
{
"name": "Run Of The Mill Quality",
"rp": 8
},
{
"name": "Superior Quality",
"rp": 25
}
]
},
{
"name": "Light Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 5
},
{
"name": "Run Of The Mill Quality",
"rp": 12
}
]
},
{
"name": "Heavy Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 8
},
{
"name": "Run Of The Mill Quality",
"rp": 20
}
]
}
]
},
{
"name": "Missile Weapons",
"type": "gear",
"resources": [
{
"name": "Bow",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 5
}
]
},
{
"name": "Crossbow",
"resources": [
{
"name": "Poor Quality",
"rp": 4
},
{
"name": "Run Of The Mill Quality",
"rp": 6
}
]
},
{
"name": "Iron-cased Bombs",
"resources": null,
"rp": 10
}
]
},
{
"name": "Black Iron Helmet",
"rp": 5,
"type": "gear"
},
{
"name": "Black Iron Shield",
"rp": 4,
"type": "gear"
},
{
"name": "Riding Mount Or Pack Animal",
"rp": 5,
"type": "gear"
},
{
"name": "Great Wolf Mount",
"rp": 15,
"type": "gear"
},
{
"name": "Whip",
"rp": 2,
"type": "gear"
},
{
"name": "Poison",
"rp": 5,
"type": "gear"
},
{
"name": "Brazen Horn",
"rp": 9,
"type": "gear"
},
{
"name": "Clan Banner",
"rp": 9,
"type": "gear"
},
{
"name": "Skill Tools",
"rp": 9,
"type": "gear"
},
{
"name": "Riding Harness For Wolf",
"rp": 5,
"type": "gear"
},
{
"name": "Servant's Black Robes",
"rp": 1,
"type": "gear"
},
{
"name": "Servant's Leather Apron",
"rp": 1,
"type": "gear"
},
{
"name": "Ceremonial Knives",
"rp": 3,
"type": "gear"
},
{
"name": "Ceremonial Axe Or Sword",
"rp": 7,
"type": "gear"
},
{
"name": "Servant's Tools Of The Trade",
"rp": 7,
"type": "gear"
},
{
"name": "Poisoner's Toolkit",
"rp": 7,
"type": "gear"
}
]
{
"stock": "orc",
"resources": [
{
"name": "Rags",
"rp": 1,
"type": "gear"
},
{
"name": "Traveling Gear",
"rp": 3,
"type": "gear"
},
{
"name": "Hobnailed Boots",
"rp": 1,
"type": "gear"
},
{
"name": "Orc Arms",
"type": "gear",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 5
}
]
},
{
"name": "Armor",
"type": "gear",
"resources": [
{
"name": "Hides",
"resources": [
{
"name": "Poor Quality",
"rp": 1
}
]
},
{
"name": "Reinforced Hides",
"resources": [
{
"name": "Poor Quality",
"rp": 3
}
]
},
{
"name": "Reinforced Leather",
"resources": [
{
"name": "Run Of The Mill Quality",
"rp": 8
},
{
"name": "Superior Quality",
"rp": 25
}
]
},
{
"name": "Light Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 5
},
{
"name": "Run Of The Mill Quality",
"rp": 12
}
]
},
{
"name": "Heavy Mail",
"resources": [
{
"name": "Poor Quality",
"rp": 8
},
{
"name": "Run Of The Mill Quality",
"rp": 20
}
]
}
]
},
{
"name": "Missile Weapons",
"type": "gear",
"resources": [
{
"name": "Bow",
"resources": [
{
"name": "Poor Quality",
"rp": 3
},
{
"name": "Run Of The Mill Quality",
"rp": 5
}
]
},
{
"name": "Crossbow",
"resources": [
{
"name": "Poor Quality",
"rp": 4
},
{
"name": "Run Of The Mill Quality",
"rp": 6
}
]
},
{
"name": "Iron-cased Bombs",
"resources": null,
"rp": 10
}
]
},
{
"name": "Black Iron Helmet",
"rp": 5,
"type": "gear"
},
{
"name": "Black Iron Shield",
"rp": 4,
"type": "gear"
},
{
"name": "Riding Mount Or Pack Animal",
"rp": 5,
"type": "gear"
},
{
"name": "Great Wolf Mount",
"rp": 15,
"type": "gear"
},
{
"name": "Whip",
"rp": 2,
"type": "gear"
},
{
"name": "Poison",
"rp": 5,
"type": "gear"
},
{
"name": "Brazen Horn",
"rp": 9,
"type": "gear"
},
{
"name": "Clan Banner",
"rp": 9,
"type": "gear"
},
{
"name": "Skill Tools",
"rp": 9,
"type": "gear"
},
{
"name": "Riding Harness For Wolf",
"rp": 5,
"type": "gear"
},
{
"name": "Servant's Black Robes",
"rp": 1,
"type": "gear"
},
{
"name": "Servant's Leather Apron",
"rp": 1,
"type": "gear"
},
{
"name": "Ceremonial Knives",
"rp": 3,
"type": "gear"
},
{
"name": "Ceremonial Axe Or Sword",
"rp": 7,
"type": "gear"
},
{
"name": "Servant's Tools Of The Trade",
"rp": 7,
"type": "gear"
},
{
"name": "Poisoner's Toolkit",
"rp": 7,
"type": "gear"
}
]
}

@ -1,139 +1,142 @@
[
{
"name": "Arms",
"rp": 5,
"type": "gear"
},
{
"name": "Roden Throwing Blades",
"rp": 15,
"type": "gear"
},
{
"name": "Wooden Shield",
"rp": 2,
"type": "gear"
},
{
"name": "Armor",
"type": "gear",
"resources": [
{
"name": "Gambeson",
"rp": 5
},
{
"name": "Reinforced Leather",
"rp": 10
},
{
"name": "Light Mail",
"rp": 15
},
{
"name": "Heavy Mail",
"rp": 20
}
]
},
{
"name": "Property",
"type": "property",
"resources": [
{
"name": "Rat's Nest Property",
"resources": [
{
"name": "Den",
"rp": 7
},
{
"name": "Nest",
"rp": 10
},
{
"name": "Apiary",
"rp": 10
},
{
"name": "Fields",
"rp": 15
}
]
}
]
},
{
"name": "Workshop",
"type": "property",
"rp": 20
},
{
"name": "Animal Herd",
"type": "property",
"rp": 10
},
{
"name": "Clothes",
"type": "gear",
"rp": 1
},
{
"name": "Traveling Gear",
"type": "gear",
"rp": 1
},
{
"name": "Shoes",
"type": "gear",
"rp": 3
},
{
"name": "Tool Kit",
"type": "gear",
"rp": 9
},
{
"name": "Firebombs",
"type": "gear",
"rp": 20
},
{
"name": "Robes Of The Ordained",
"type": "gear",
"rp": 1
},
{
"name": "Honeyed Oatcakes",
"type": "gear",
"rp": 5
},
{
"name": "Dandewine",
"type": "gear",
"rp": 5
},
{
"name": "Blood Blossom",
"type": "gear",
"rp": 5
},
{
"name": "Visionary Cult",
"type": "affiliation",
"resources": [
{
"name": "1d Cult",
"rp": 10
},
{
"name": "2d Cult",
"rp": 25
},
{
"name": "3d Cult",
"rp": 50
}
]
}
]
{
"stock": "roden",
"resources": [
{
"name": "Arms",
"rp": 5,
"type": "gear"
},
{
"name": "Roden Throwing Blades",
"rp": 15,
"type": "gear"
},
{
"name": "Wooden Shield",
"rp": 2,
"type": "gear"
},
{
"name": "Armor",
"type": "gear",
"resources": [
{
"name": "Gambeson",
"rp": 5
},
{
"name": "Reinforced Leather",
"rp": 10
},
{
"name": "Light Mail",
"rp": 15
},
{
"name": "Heavy Mail",
"rp": 20
}
]
},
{
"name": "Property",
"type": "property",
"resources": [
{
"name": "Rat's Nest Property",
"resources": [
{
"name": "Den",
"rp": 7
},
{
"name": "Nest",
"rp": 10
},
{
"name": "Apiary",
"rp": 10
},
{
"name": "Fields",
"rp": 15
}
]
}
]
},
{
"name": "Workshop",
"type": "property",
"rp": 20
},
{
"name": "Animal Herd",
"type": "property",
"rp": 10
},
{
"name": "Clothes",
"type": "gear",
"rp": 1
},
{
"name": "Traveling Gear",
"type": "gear",
"rp": 1
},
{
"name": "Shoes",
"type": "gear",
"rp": 3
},
{
"name": "Tool Kit",
"type": "gear",
"rp": 9
},
{
"name": "Firebombs",
"type": "gear",
"rp": 20
},
{
"name": "Robes Of The Ordained",
"type": "gear",
"rp": 1
},
{
"name": "Honeyed Oatcakes",
"type": "gear",
"rp": 5
},
{
"name": "Dandewine",
"type": "gear",
"rp": 5
},
{
"name": "Blood Blossom",
"type": "gear",
"rp": 5
},
{
"name": "Visionary Cult",
"type": "affiliation",
"resources": [
{
"name": "1d Cult",
"rp": 10
},
{
"name": "2d Cult",
"rp": 25
},
{
"name": "3d Cult",
"rp": 50
}
]
}
]
}

@ -1,42 +1,45 @@
[
{
"name": "Territory",
"type": "property",
"resources": [
{
"name": "Barren",
"rp": 5
},
{
"name": "Wild Grounds",
"rp": 10
},
{
"name": "Plentiful Range",
"rp": 15
}
]
},
{
"name": "Armor",
"type": "gear",
"resources": [
{
"name": "Plated Leather Chanfron",
"rp": 3
},
{
"name": "Leather Collar",
"rp": 2
},
{
"name": "Plated Body Armor",
"rp": 6
},
{
"name": "Leather Greaves And Cuissarts",
"rp": 2
}
]
}
]
{
"stock": "wolf",
"resources": [
{
"name": "Territory",
"type": "property",
"resources": [
{
"name": "Barren",
"rp": 5
},
{
"name": "Wild Grounds",
"rp": 10
},
{
"name": "Plentiful Range",
"rp": 15
}
]
},
{
"name": "Armor",
"type": "gear",
"resources": [
{
"name": "Plated Leather Chanfron",
"rp": 3
},
{
"name": "Leather Collar",
"rp": 2
},
{
"name": "Plated Body Armor",
"rp": 6
},
{
"name": "Leather Greaves And Cuissarts",
"rp": 2
}
]
}
]
}

@ -1,114 +0,0 @@
[
{
"range": [
1,
20
],
"m": 6,
"p": 13
},
{
"range": [
21,
30
],
"m": 7,
"p": 13
},
{
"range": [
31,
50
],
"m": 7,
"p": 14
},
{
"range": [
51,
76
],
"m": 8,
"p": 15
},
{
"range": [
77,
111
],
"m": 8,
"p": 16
},
{
"range": [
112,
151
],
"m": 9,
"p": 16
},
{
"range": [
152,
199
],
"m": 9,
"p": 17
},
{
"range": [
200,
245
],
"m": 10,
"p": 18
},
{
"range": [
246,
300
],
"m": 11,
"p": 17
},
{
"range": [
301,
345
],
"m": 11,
"p": 16
},
{
"range": [
346,
396
],
"m": 12,
"p": 15
},
{
"range": [
397,
445
],
"m": 11,
"p": 14
},
{
"range": [
446,
525
],
"m": 11,
"p": 13
},
{
"range": [
526,
600
],
"m": 10,
"p": 12
}
]

@ -1,146 +0,0 @@
[
{
"range": [
1,
25
],
"m": 7,
"p": 13
},
{
"range": [
26,
60
],
"m": 8,
"p": 13
},
{
"range": [
61,
100
],
"m": 9,
"p": 14
},
{
"range": [
101,
125
],
"m": 9,
"p": 15
},
{
"range": [
126,
160
],
"m": 10,
"p": 16
},
{
"range": [
161,
225
],
"m": 10,
"p": 17
},
{
"range": [
226,
325
],
"m": 11,
"p": 17
},
{
"range": [
326,
425
],
"m": 12,
"p": 17
},
{
"range": [
426,
525
],
"m": 13,
"p": 18
},
{
"range": [
526,
625
],
"m": 13,
"p": 19
},
{
"range": [
626,
725
],
"m": 14,
"p": 19
},
{
"range": [
726,
825
],
"m": 14,
"p": 20
},
{
"range": [
826,
925
],
"m": 15,
"p": 20
},
{
"range": [
926,
1025
],
"m": 15,
"p": 21
},
{
"range": [
1026,
1125
],
"m": 15,
"p": 22
},
{
"range": [
1126,
1225
],
"m": 15,
"p": 23
},
{
"range": [
1226,
1325
],
"m": 15,
"p": 24
},
{
"range": [
1326,
9999
],
"m": 16,
"p": 24
}
]

@ -1,90 +0,0 @@
[
{
"range": [
1,
10
],
"m": 5,
"p": 10
},
{
"range": [
11,
14
],
"m": 6,
"p": 13
},
{
"range": [
15,
16
],
"m": 6,
"p": 16
},
{
"range": [
17,
25
],
"m": 7,
"p": 16
},
{
"range": [
26,
29
],
"m": 7,
"p": 15
},
{
"range": [
30,
35
],
"m": 7,
"p": 14
},
{
"range": [
36,
40
],
"m": 7,
"p": 13
},
{
"range": [
41,
55
],
"m": 7,
"p": 12
},
{
"range": [
56,
65
],
"m": 7,
"p": 11
},
{
"range": [
66,
79
],
"m": 7,
"p": 10
},
{
"range": [
80,
100
],
"m": 6,
"p": 9
}
]

@ -1,98 +0,0 @@
[
{
"range": [
1,
10
],
"m": 3,
"p": 10
},
{
"range": [
11,
16
],
"m": 4,
"p": 11
},
{
"range": [
17,
22
],
"m": 5,
"p": 12
},
{
"range": [
23,
30
],
"m": 5,
"p": 13
},
{
"range": [
31,
40
],
"m": 6,
"p": 14
},
{
"range": [
41,
50
],
"m": 6,
"p": 15
},
{
"range": [
51,
60
],
"m": 7,
"p": 16
},
{
"range": [
61,
80
],
"m": 7,
"p": 17
},
{
"range": [
81,
99
],
"m": 8,
"p": 17
},
{
"range": [
100,
125
],
"m": 8,
"p": 18
},
{
"range": [
126,
150
],
"m": 9,
"p": 18
},
{
"range": [
151,
9999
],
"m": 9,
"p": 19
}
]

@ -1,74 +0,0 @@
[
{
"range": [
1,
5
],
"m": 6,
"p": 10
},
{
"range": [
6,
9
],
"m": 7,
"p": 13
},
{
"range": [
10,
15
],
"m": 7,
"p": 14
},
{
"range": [
16,
24
],
"m": 8,
"p": 15
},
{
"range": [
25,
30
],
"m": 8,
"p": 14
},
{
"range": [
31,
36
],
"m": 7,
"p": 13
},
{
"range": [
37,
40
],
"m": 7,
"p": 12
},
{
"range": [
41,
45
],
"m": 7,
"p": 11
},
{
"range": [
46,
49
],
"m": 6,
"p": 10
}
]

@ -1,58 +0,0 @@
[
{
"range": [
1,
1.5
],
"m": 6,
"p": 12
},
{
"range": [
2,
3.5
],
"m": 7,
"p": 16
},
{
"range": [
4,
5.5
],
"m": 7,
"p": 17
},
{
"range": [
6,
7.5
],
"m": 7,
"p": 16
},
{
"range": [
8,
9.5
],
"m": 6,
"p": 14
},
{
"range": [
10,
11.5
],
"m": 6,
"p": 12
},
{
"range": [
12,
15.5
],
"m": 5,
"p": 10
}
]

@ -0,0 +1,130 @@
{
"key": "dwarf",
"name": "Dwarf",
"stride": 6,
"adjective": "dwarven",
"common_traits": [
"Accustomed To The Dark",
"Bearded",
"Greed",
"Oathsworn",
"Shaped From Earth And Stone",
"Stout",
"Tough"
],
"starting_stats":
[
{
"range": [
1,
20
],
"m": 6,
"p": 13
},
{
"range": [
21,
30
],
"m": 7,
"p": 13
},
{
"range": [
31,
50
],
"m": 7,
"p": 14
},
{
"range": [
51,
76
],
"m": 8,
"p": 15
},
{
"range": [
77,
111
],
"m": 8,
"p": 16
},
{
"range": [
112,
151
],
"m": 9,
"p": 16
},
{
"range": [
152,
199
],
"m": 9,
"p": 17
},
{
"range": [
200,
245
],
"m": 10,
"p": 18
},
{
"range": [
246,
300
],
"m": 11,
"p": 17
},
{
"range": [
301,
345
],
"m": 11,
"p": 16
},
{
"range": [
346,
396
],
"m": 12,
"p": 15
},
{
"range": [
397,
445
],
"m": 11,
"p": 14
},
{
"range": [
446,
525
],
"m": 11,
"p": 13
},
{
"range": [
526,
600
],
"m": 10,
"p": 12
}
]
}

@ -0,0 +1,161 @@
{
"key": "elf",
"name": "Elf",
"stride": 8,
"adjective": "elven",
"common_traits": [
"Born Under The Silver Stars",
"Essence Of The Earth",
"Fair And Statuesque",
"First Born",
"Grief",
"Keen Sight"
],
"starting_stats":
[
{
"range": [
1,
25
],
"m": 7,
"p": 13
},
{
"range": [
26,
60
],
"m": 8,
"p": 13
},
{
"range": [
61,
100
],
"m": 9,
"p": 14
},
{
"range": [
101,
125
],
"m": 9,
"p": 15
},
{
"range": [
126,
160
],
"m": 10,
"p": 16
},
{
"range": [
161,
225
],
"m": 10,
"p": 17
},
{
"range": [
226,
325
],
"m": 11,
"p": 17
},
{
"range": [
326,
425
],
"m": 12,
"p": 17
},
{
"range": [
426,
525
],
"m": 13,
"p": 18
},
{
"range": [
526,
625
],
"m": 13,
"p": 19
},
{
"range": [
626,
725
],
"m": 14,
"p": 19
},
{
"range": [
726,
825
],
"m": 14,
"p": 20
},
{
"range": [
826,
925
],
"m": 15,
"p": 20
},
{
"range": [
926,
1025
],
"m": 15,
"p": 21
},
{
"range": [
1026,
1125
],
"m": 15,
"p": 22
},
{
"range": [
1126,
1225
],
"m": 15,
"p": 23
},
{
"range": [
1226,
1325
],
"m": 15,
"p": 24
},
{
"range": [
1326,
9999
],
"m": 16,
"p": 24
}
]
}

@ -0,0 +1,99 @@
{
"key": "man",
"name": "Man",
"stride": 7,
"adjective": "mannish",
"common_traits": [
],
"starting_stats":
[
{
"range": [
1,
10
],
"m": 5,
"p": 10
},
{
"range": [
11,
14
],
"m": 6,
"p": 13
},
{
"range": [
15,
16
],
"m": 6,
"p": 16
},
{
"range": [
17,
25
],
"m": 7,
"p": 16
},
{
"range": [
26,
29
],
"m": 7,
"p": 15
},
{
"range": [
30,
35
],
"m": 7,
"p": 14
},
{
"range": [
36,
40
],
"m": 7,
"p": 13
},
{
"range": [
41,
55
],
"m": 7,
"p": 12
},
{
"range": [
56,
65
],
"m": 7,
"p": 11
},
{
"range": [
66,
79
],
"m": 7,
"p": 10
},
{
"range": [
80,
100
],
"m": 6,
"p": 9
}
]
}

@ -0,0 +1,114 @@
{
"key": "orc",
"name": "Orc",
"stride": 7,
"adjective": "orcish",
"common_traits": [
"Cannibal",
"Cold Black Blood",
"Breeder",
"Fanged And Clawed",
"Loathsome And Twisted",
"Lynx-eyed, Like Burning Coals",
"Vile Language"
],
"starting_stats":
[
{
"range": [
1,
10
],
"m": 3,
"p": 10
},
{
"range": [
11,
16
],
"m": 4,
"p": 11
},
{
"range": [
17,
22
],
"m": 5,
"p": 12
},
{
"range": [
23,
30
],
"m": 5,
"p": 13
},
{
"range": [
31,
40
],
"m": 6,
"p": 14
},
{
"range": [
41,
50
],
"m": 6,
"p": 15
},
{
"range": [
51,
60
],
"m": 7,
"p": 16
},
{
"range": [
61,
80
],
"m": 7,
"p": 17
},
{
"range": [
81,
99
],
"m": 8,
"p": 17
},
{
"range": [
100,
125
],
"m": 8,
"p": 18
},
{
"range": [
126,
150
],
"m": 9,
"p": 18
},
{
"range": [
151,
9999
],
"m": 9,
"p": 19
}
]
}

@ -0,0 +1,90 @@
{
"key": "roden",
"name": "Roden",
"stride": 8,
"adjective": "roden",
"common_traits": [
"Aecer's Likeness",
"Coat Of Fur",
"Communal",
"Enlarged Incisors",
"Quick-blooded",
"Tail",
"Large Ears"
],
"starting_stats":
[
{
"range": [
1,
5
],
"m": 6,
"p": 10
},
{
"range": [
6,
9
],
"m": 7,
"p": 13
},
{
"range": [
10,
15
],
"m": 7,
"p": 14
},
{
"range": [
16,
24
],
"m": 8,
"p": 15
},
{
"range": [
25,
30
],
"m": 8,
"p": 14
},
{
"range": [
31,
36
],
"m": 7,
"p": 13
},
{
"range": [
37,
40
],
"m": 7,
"p": 12
},
{
"range": [
41,
45
],
"m": 7,
"p": 11
},
{
"range": [
46,
49
],
"m": 6,
"p": 10
}
]
}

@ -0,0 +1,75 @@
{
"key": "wolf",
"name": "Wolf",
"stride": 11,
"adjective": "wolfish",
"common_traits": [
"Crushing Jaws",
"Deep Fur",
"Great Lupine Form",
"Lupine Intellect",
"Long-legged",
"Wolf's Eyes",
"Wolf's Snout",
"Woodland Ear"
],
"starting_stats":
[
{
"range": [
1,
1.5
],
"m": 6,
"p": 12
},
{
"range": [
2,
3.5
],
"m": 7,
"p": 16
},
{
"range": [
4,
5.5
],
"m": 7,
"p": 17
},
{
"range": [
6,
7.5
],
"m": 7,
"p": 16
},
{
"range": [
8,
9.5
],
"m": 6,
"p": 14
},
{
"range": [
10,
11.5
],
"m": 6,
"p": 12
},
{
"range": [
12,
15.5
],
"m": 5,
"p": 10
}
]
}

@ -632,14 +632,14 @@
],
"desc": "So vile are they, Orcs will not hesitate to slay and eat their companions."
},
"Catamite": {
"cost": 1,
"type": "character",
"Catalyst": {
"cost": 3,
"type": "die",
"restrict": [
"mannish",
"special"
],
"desc": "Catamite has been chosen as the trait name to represent the openly homosexual characters in the Burning Wheel. Honestly it was a pejorative medieval term -- a slur. It is how society would refer to them, not necessarily how they refer to themselves. Any Character may be homosexual via the player's choice, but by taking the Catamite trait the player is acknowledging that his character is open about his orientation. The ramifications of such a decision in a conservative medieval society are grist for great game situations"
"desc": "You are the center of something great and terrible. Earn a persona point each time your actions cause a conflict between two powerful personas or organizations."
},
"Charging Blindly": {
"cost": 0,

File diff suppressed because it is too large Load Diff

@ -1,57 +1,60 @@
[
{
"name": "Rags",
"type": "gear",
"rp": 1
},
{
"name": "Troll Shoes",
"type": "gear",
"rp": 1
},
{
"name": "Sack",
"type": "gear",
"rp": 1
},
{
"name": "Chest or Footlocker",
"type": "gear",
"rp": 3
},
{
"name": "Trophies",
"type": "gear",
"rp": 3
},
{
"name": "Shiny Trophies",
"type": "gear",
"rp": 7
},
{
"name": "Pile of Rocks",
"type": "gear",
"rp": 2
},
{
"name": "Troll Lash",
"type": "gear",
"rp": 5
},
{
"name": "Mattock",
"type": "gear",
"rp": 10
},
{
"name": "Black Iron Shield",
"type": "gear",
"rp": 5
},
{
"name": "Cave Hole",
"type": "property",
"rp": 5
}
]
{
"stock": "troll",
"resources": [
{
"name": "Rags",
"type": "gear",
"rp": 1
},
{
"name": "Troll Shoes",
"type": "gear",
"rp": 1
},
{
"name": "Sack",
"type": "gear",
"rp": 1
},
{
"name": "Chest or Footlocker",
"type": "gear",
"rp": 3
},
{
"name": "Trophies",
"type": "gear",
"rp": 3
},
{
"name": "Shiny Trophies",
"type": "gear",
"rp": 7
},
{
"name": "Pile of Rocks",
"type": "gear",
"rp": 2
},
{
"name": "Troll Lash",
"type": "gear",
"rp": 5
},
{
"name": "Mattock",
"type": "gear",
"rp": 10
},
{
"name": "Black Iron Shield",
"type": "gear",
"rp": 5
},
{
"name": "Cave Hole",
"type": "property",
"rp": 5
}
]
}

@ -1,82 +0,0 @@
[
{
"range": [
1,
5
],
"m": 3,
"p": 11
},
{
"range": [
6,
12
],
"m": 4,
"p": 14
},
{
"range": [
13,
19
],
"m": 4,
"p": 17
},
{
"range": [
20,
27
],
"m": 4,
"p": 19
},
{
"range": [
28,
57
],
"m": 4,
"p": 20
},
{
"range": [
58,
80
],
"m": 4,
"p": 19
},
{
"range": [
81,
124
],
"m": 4,
"p": 18
},
{
"range": [
125,
213
],
"m": 5,
"p": 17
},
{
"range": [
214,
390
],
"m": 5,
"p": 16
},
{
"range": [
391,
712
],
"m": 6,
"p": 15
}
]

@ -0,0 +1,100 @@
{
"key": "troll",
"name": "Troll",
"stride": 7,
"adjective": "trollish",
"common_traits": [
"Black Nails",
"Fangs",
"Night Blooded",
"Night Eyed (Troll)",
"Massive Stature (Troll)",
"Stone's Age",
"Tough (Troll)",
"Troll Skin",
"Voracious Carnivore"
],
"starting_stats":
[
{
"range": [
1,
5
],
"m": 3,
"p": 11
},
{
"range": [
6,
12
],
"m": 4,
"p": 14
},
{
"range": [
13,
19
],
"m": 4,
"p": 17
},
{
"range": [
20,
27
],
"m": 4,
"p": 19
},
{
"range": [
28,
57
],
"m": 4,
"p": 20
},
{
"range": [
58,
80
],
"m": 4,
"p": 19
},
{
"range": [
81,
124
],
"m": 4,
"p": 18
},
{
"range": [
125,
213
],
"m": 5,
"p": 17
},
{
"range": [
214,
390
],
"m": 5,
"p": 16
},
{
"range": [
391,
712
],
"m": 6,
"p": 15
}
]
}

File diff suppressed because it is too large Load Diff

@ -1,7 +1,11 @@
require 'deep_merge'
require_relative 'data/gold'
require_relative 'data/wizard'
require_relative 'data/dark_elf'
require_relative 'data/troll'
require_relative 'stock'
require_relative 'data/custom'
module Charred
class Data
@ -9,11 +13,13 @@ module Charred
include Charred::Wizard
include Charred::DarkElf
include Charred::Troll
include Charred::Custom
attr :data
def initialize
@data = {}
@data[:stocks] = {}
puts 'loading gold'
load_gold(@data)
@ -27,6 +33,9 @@ module Charred
puts 'loading trolls'
load_troll(@data)
puts 'loading custom stocks'
load_custom(@data)
@data[:traits] = @data[:traits].sort.to_h
@data[:skills] = @data[:skills].sort.to_h
end
@ -53,5 +62,9 @@ module Charred
[]
end
end
def json_get(filename)
JSON.parse(File.read(filename))
end
end
end

@ -0,0 +1,27 @@
require 'json'
module Charred
module Custom
def load_custom(data)
Dir.glob("data/custom/**/*") { |file|
if File.file?(file)
case File.extname(file)
when ".skills"
verbose_merge data[:skills], json_get(file)
when ".traits"
verbose_merge data[:traits], json_get(file)
when ".stock"
stock = Stock.new(json_get(file))
data[:stocks].deep_merge!({ stock.key => stock })
when ".lifepaths"
contents = json_get(file)
data[:lifepaths].ko_deep_merge!({ contents["stock"] => contents["settings"]})
when ".resources"
contents = json_get(file)
data[:resources].ko_deep_merge!({ contents["stock"] => contents["resources"]})
end
end
}
end
end
end

@ -12,10 +12,12 @@ module Charred
verbose_merge data[:traits], traits
file = File.read('data/dark_elf/lifepaths.json')
lifepaths = JSON.parse(file)
contents = JSON.parse(file)
lifepaths = contents["settings"]
file = File.read("data/dark_elf/resources.json")
resources = JSON.parse(file)
contents = JSON.parse(file)
resources = contents["resources"]
data[:resources]['elf'] += resources
elf = data[:lifepaths]['elf']

@ -1,4 +1,5 @@
require 'json'
require_relative '../stock'
module Charred
module Gold
@ -11,28 +12,29 @@ module Charred
lifepaths = {}
resources = {}
stat_pts = {}
stocks = {}
stocks = ['dwarf', 'elf', 'man', 'orc', 'roden', 'wolf']
gold_stocks = ['dwarf', 'elf', 'man', 'orc', 'roden', 'wolf']
stocks.each do |stock|
gold_stocks.each do |stock|
file = File.read("data/gold/lifepaths/#{stock}.json")
lifepaths[stock] = JSON.parse(file)
contents = JSON.parse(file)
lifepaths[stock] = contents["settings"]
file = File.read("data/gold/resources/#{stock}.json")
resources[stock] = JSON.parse(file)
contents = JSON.parse(file)
resources[stock] = contents["resources"]
file = File.read("data/gold/starting_stat_pts/#{stock}.json")
stat_pts[stock] = JSON.parse(file)
file = File.read("data/gold/stocks/#{stock}.json")
stocks[stock] = Stock.new(JSON.parse(file))
end
data.merge!({
:stocks => stocks,
:skills => skills,
:traits => traits,
:lifepaths => lifepaths,
:resources => resources,
:stat_pts => stat_pts
:stocks => stocks
})
end
end

@ -1,10 +1,9 @@
require 'json'
require_relative '../stock'
module Charred
module Troll
def load_troll(data)
data[:stocks] << 'troll'
file = File.read('data/troll/skills.json')
skills = JSON.parse(file)
verbose_merge data[:skills], skills
@ -14,16 +13,18 @@ module Charred
verbose_merge data[:traits], traits
file = File.read('data/troll/lifepaths.json')
lifepaths = JSON.parse(file)
contents = JSON.parse(file)
lifepaths = contents["settings"]
data[:lifepaths]['troll'] = lifepaths
file = File.read("data/troll/resources.json")
resources = JSON.parse(file)
contents = JSON.parse(file)
resources = contents["resources"]
data[:resources]['troll'] = resources
file = File.read("data/troll/starting_stat_pts.json")
stats = JSON.parse(file)
data[:stat_pts]['troll'] = stats
file = File.read("data/troll/stock.json")
stock = JSON.parse(file)
data[:stocks]['troll'] = Stock.new(stock)
end
end
end

@ -4,7 +4,8 @@ module Charred
module Wizard
def load_wizard(data)
file = File.read('data/wizard/lifepaths.json')
wizard_data = JSON.parse(file)
contents = JSON.parse(file)
wizard_data = contents["settings"]
file = File.read('data/wizard/skills.json')
wizard_skills = JSON.parse(file)

@ -0,0 +1,34 @@
module Charred
class Stock
@@default_stride = 7
attr :key
attr :name
attr :stride
attr :common_traits
attr :starting_stats
def initialize(h)
@key = h["key"]
@name = h["name"] || @key
@stride = h["stride"] || @@default_stride
@adjective = h["adjective"] || @key+"ish"
@common_traits = h["common_traits"]
@starting_stats = h["starting_stats"]
end
def as_json(options = {})
{
"key" => @key,
"name" => @name,
"stride" => @stride,
"adjective" => @adjective,
"common_traits" => @common_traits,
"starting_stats" => @starting_stats
}
end
def to_json(*a)
as_json.to_json(*a)
end
end
end

@ -1,8 +1,8 @@
function loadCurrentCharacterFromStruct($scope, charStruct, burningData, appropriateWeapons){
$scope.name = charStruct.name;
$scope.gender = charStruct.gender;
$scope.stock = charStruct.stock;
$scope.name = charStruct.name;
$scope.gender = charStruct.gender;
$scope.stock = charStruct.stock;
$scope.ensureStockLoaded($scope.stock).then(() => {
// Appropriate weapons must be loaded before calculateLifepathSkills is called.
if(serverSettings.storageType != 'server'){
appropriateWeapons.appropriateWeapons = charStruct.approp_weapons;
@ -173,7 +173,8 @@ function loadCurrentCharacterFromStruct($scope, charStruct, burningData, appropr
$scope.attributeModifierQuestionResults = loadAttributeModifierQuestionResultsFromSave($scope, charStruct.attr_mod_questions);
$scope.brutalLifeWithdrawn = charStruct.brutal_life_withdrawn;
$scope.$digest();
});
}
function convertCurrentCharacterToStruct($scope, appropriateWeapons) {

@ -1,4 +1,4 @@
var DEBUG = false;
/**** Class Settings (Angular Service) ****/
function Settings() {
this.enforceLifepathReqts = true;
@ -218,13 +218,14 @@ function CharacterStorageService($http) {
/* Load character names from server */
this.loadCharacterNames = function(){
$http.get("/list_chars/user1", {'timeout': 3000} ).
success(function(data,status,headers,config){
fetch("/list_chars/user1")
.then((response) => response.json())
.then((data) => {
myself.characterIdAndNames = data;
console.log("Loaded saved character names");
}).
error(function(data,status,headers,config){
console.log("Error: Loading saved character names from server failed: HTTP code " + status + ": " + data);
})
.catch((error) => {
console.log("Error: Loading saved character names from server failed: "+error);
});
}
@ -236,6 +237,10 @@ function CharacterStorageService($http) {
/**** Class BurningDataService (Angular Service) ****/
// This service is used to load the lifepaths, skills, traits, etc. from the server.
function BurningDataService($http) {
// Used to reference the object from within functions and callbacks
var myself = this;
/* JSON Data structure representing lifepaths. The structure is:
stock:
setting_name:
@ -263,122 +268,88 @@ function BurningDataService($http) {
// A hash of StartingStatPoints objects keyed by stock.
this.startingStatPts = {};
this.dataSetsLoaded = 0;
// Total data sets:
// lifepaths: 7 (man, dwarf, elf, orc, roden, wolf, troll)
// stat points: 7 (man, dwarf, elf, orc, roden, wolf, troll)
// skills
// traits
// resources: 7 (man, dwarf, elf, orc, roden, wolf. troll)
// TOTAL: 23
this.totalDataSets = 23;
this.onAllDatasetsLoaded = null;
this.registerOnAllDatasetsLoaded = function(callback){
if ( this.dataSetsLoaded >= this.totalDataSets ){
callback();
}
this.onAllDatasetsLoaded = callback;
}
this.datasetLoaded = function(){
this.dataSetsLoaded += 1;
if ( this.onAllDatasetsLoaded && (this.dataSetsLoaded >= this.totalDataSets) ){
this.onAllDatasetsLoaded();
}
if ( this.dataSetsLoaded > this.totalDataSets){
console.log("Error: the totalDataSets setting in BurningDataService is too low! This will cause wierd errors. Please adjust it");
}
}
var stocks = ["man", "dwarf", "elf", "orc", "roden", "wolf", "troll"];
var myself = this;
/* Load lifepaths from server */
var loadLifepathsForStock = function(stock){
if( ! isValidStock(stock) ){
console.log("Loading lifepaths failed: asked to load lifepaths for invalid stock " + stock);
return
}
$http.get("/lifepaths/" + stock, {'timeout': 3000} ).
success(function(data,status,headers,config){
myself.lifepaths[stock] = data;
myself.datasetLoaded();
console.log("Loaded "+stock+" lifepaths. " + Object.keys(myself.lifepaths).length + " settings");
}).
error(function(data,status,headers,config){
myself.datasetLoaded();
console.log("Error: Getting "+stock+" lifepaths from server failed: HTTP code " + status + ": " + data);
});
}
/* Load starting stat points table from server */
var loadStartingStatPtsForStock = function(stock){
if( ! isValidStock(stock) ){
console.log("Loading starting stat points failed: asked to load pts for invalid stock " + stock);
return
}
$http.get("/starting_stat_pts/" + stock, {'timeout': 3000} ).
success(function(data,status,headers,config){
myself.startingStatPts[stock] = new StartingStatPoints(data);
myself.datasetLoaded();
console.log("Loaded "+stock+" starting stat points. ");
}).
error(function(data,status,headers,config){
myself.datasetLoaded();
console.log("Error: Getting "+stock+" stat points from server failed: HTTP code " + status + ": " + data);
});
}
/* Load starting stat points table from server */
var loadResourcesForStock = function(stock){
if( ! isValidStock(stock) ){
console.log("Loading resources failed: asked to load for invalid stock " + stock);
return
}
/* Loading of stocks, skills, and traits begins on initializing the service
$http.get("/resources/" + stock, {'timeout': 3000} ).
success(function(data,status,headers,config){
myself.resources[stock] = data;
myself.datasetLoaded();
console.log("Loaded "+stock+" resources. ");
}).
error(function(data,status,headers,config){
myself.datasetLoaded();
console.log("Error: Getting "+stock+" stat points from server failed: HTTP code " + status + ": " + data);
});
}
for (var i = 0; i < stocks.length; i++) {
loadLifepathsForStock(stocks[i]);
loadStartingStatPtsForStock(stocks[i]);
loadResourcesForStock(stocks[i]);
}
/* Load stocks from server */
this.whenStocksLoaded = fetch("/stocks")
.then((response) => response.json())
.then((data) => {
if(DEBUG) {
console.log("Loaded stock data:");
console.log(data);
}
myself.stocks = data;
for (var stock of Object.keys(data)) {
myself.startingStatPts[stock] = new StartingStatPoints(myself.stocks[stock].starting_stats);
}
})
.catch((error) => {
console.log("Error: Getting stocks from server failed: "+error);
});
/* Load skills from server */
$http.get("/skills", {'timeout': 3000} ).
success(function(data,status,headers,config){
this.whenSkillsLoaded = fetch("/skills")
.then((response) => response.json())
.then((data) => {
myself.skills = data;
myself.datasetLoaded();
console.log("Loaded skills. ");
}).
error(function(data,status,headers,config){
myself.datasetLoaded();
console.log("Error: Getting skills from server failed: HTTP code " + status + ": " + data);
if(DEBUG) {
console.log("Loaded skill data:");
console.log(data);
}
})
.catch((error) => {
console.log("Error: Getting skills from server failed: "+error);
});
/* Load traits from server */
$http.get("/traits", {'timeout': 3000} ).
success(function(data,status,headers,config){
this.whenTraitsLoaded = fetch("/traits")
.then((response) => response.json())
.then((data) => {
myself.traits = data;
myself.datasetLoaded();
console.log("Loaded traits. ");
}).
error(function(data,status,headers,config){
myself.datasetLoaded();
console.log("Error: Getting traits from server failed: HTTP code " + status + ": " + data);
if(DEBUG) {
console.log("Loaded trait data:");
console.log(data);
}
})
.catch((error) => {
console.log("Error: Getting traits from server failed: "+error);
});
/* Lifepaths and resources defer until their stock is selected */
this.whenLifePathsLoadedForStock = {};
/* Load lifepaths from server */
this.loadLifepathsForStock = function(stock){
return myself.whenLifePathsLoadedForStock[stock] = fetch("/lifepaths/" + stock)
.then((response) => response.json())
.then((data) => {
myself.lifepaths[stock] = data;
if(DEBUG) {
console.log("Loaded "+stock+" lifepaths:");
console.log(data);
}
})
.catch((error) => {
console.log("Error: Getting "+stock+" lifepaths from server failed: "+error);
});
};
/* Load resources from server */
this.whenResourcesLoadedForStock = {};
this.loadResourcesForStock = function(stock){
return myself.whenResourcesLoadedForStock[stock] = fetch("/resources/" + stock)
.then((response) => response.json())
.then((data) => {
myself.resources[stock] = data;
if(DEBUG) {
console.log("Loaded "+stock+" resources:");
console.log(data);
}
})
.catch((error) => {
console.log("Error: Getting "+stock+" resources from server failed: "+error);
});
};
}
/**** End BurningDataService ****/

@ -160,7 +160,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
};
// Setting names for use in the Add Lifepath section
$scope.settingNames = ["Loading..."]
$scope.settingNames = [];
$scope.currentSettingLifepathNames = [];
// The currently selected lifepath
$scope.currentSettingLifepath = "Loading...";
@ -206,12 +206,6 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
// Character name
$scope.name = "";
// Character stock. One of man, dwarf, orc, elf
if ( ! isValidStock(stock) ){
console.log("Invalid stock '"+stock+"' passed to BurningCtrl.initialize. Defaulting to man");
stock = "man";
}
$scope.stock = stock;
// Character id (server side id)
@ -302,7 +296,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
$scope.initialize("man");
$scope.initialize();
if ( characterStorage.currentCharacter ){
//console.log("Loading current character");
@ -355,7 +349,6 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
return result;
}
$scope.onGenderChange = function(){
if ($scope.name.length == 0) {
$scope.generateName();
@ -364,22 +357,43 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
$scope.onStockChange = function(){
var oldName = $scope.name;
// Make a blank character sheet
$scope.initialize($scope.stock);
if(!$scope.stock) return;
if ( oldName.length == 0 ){
$scope.generateName();
} else {
$scope.name = oldName;
if(!$scope.stockSelected) { // Removes 'select a stock' after the first selection
$scope.stocks.shift();
$scope.stockSelected = true;
}
calculateSettingNames($scope, burningData);
calculateCurrentSettingLifepathNames($scope, burningData);
calculateSpecialTraitsForDisplay($scope, burningData);
$scope.ensureStockLoaded($scope.stock).then(() => {
var oldName = $scope.name;
// Make a blank character sheet
$scope.initialize($scope.stock);
if ( oldName.length == 0 ){
$scope.generateName();
} else {
$scope.name = oldName;
}
calculateSettingNames($scope, burningData);
calculateCurrentSettingLifepathNames($scope, burningData);
calculateSpecialTraitsForDisplay($scope, burningData);
calculateGearSelectionLists($scope, burningData);
calculatePropertySelectionLists($scope, burningData);
$scope.$digest();
});
}
$scope.ensureStockLoaded = function(stock) {
let loadPromises = [];
if(!burningData.lifepaths[stock]) {
loadPromises.push(burningData.loadLifepathsForStock(stock));
}
if(!burningData.resources[stock]) {
loadPromises.push(burningData.loadResourcesForStock(stock));
}
return Promise.all(loadPromises);
};
$scope.onSettingChange = function(){
calculateCurrentSettingLifepathNames($scope, burningData);
@ -403,8 +417,10 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
calculateUnspentSkillPoints($scope);
}
burningData.registerOnAllDatasetsLoaded(function(){
onLifepathsLoad($scope, burningData);
burningData.whenStocksLoaded.then(() => {
$scope.stocks = [{ name: "Select a stock" }, ...Object.values(burningData.stocks)];
$scope.stockSelected = false;
$scope.$digest();
});
$scope.$on('$locationChangeStart', function(event, nextUrl, currentUrl) {
@ -742,13 +758,18 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
return;
$scope.attributeShade[attrName] = 'G';
if('Grief' == attrName) {
$scope.attributeShade['Spite'] = 'G';
}
}
else if (attr.shade == 'G'){
$scope.attributeShade[attrName] = 'B';
if('Spite' == attrName) {
$scope.attributeShade['Grief'] = 'B';
}
}
else
console.log("Error: changing shade of attribute failed: unknown shade " + stat.shade);
}
$scope.incrementSkill = function(skill){
@ -929,7 +950,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
for(var key in burningData.skills){
if ( !(key in $scope.lifepathSkills) && !(key in $scope.generalSkills) ){
var displaySkill = burningData.skills[key];
if ( !displaySkill.stock || restrictionStockToValidStock(displaySkill.stock) == $scope.stock ) {
if ( !displaySkill.stock || restrictionStockToValidStock(burningData.stocks, displaySkill.stock) == $scope.stock ) {
result.push(key);
}
}
@ -1024,20 +1045,9 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
return {"shade" : "", "exp" : 10 - $scope.statsByName["Will"].exp() + bonus};
}
else if ( "Stride" == name ){
var stride = 0;
if( $scope.stock == 'dwarf' )
stride = 6;
else if( $scope.stock == 'elf' )
stride = 8;
else if( $scope.stock == 'roden' )
stride = 8;
else if( $scope.stock == 'wolf' )
stride = 11;
else
stride = 7;
// This is a hack: if stock is unselected, use 0 for stride to not throw error; it shouldn't be displayed anyway
var stride = $scope.stock ? burningData.stocks[$scope.stock].stride : 0;
stride += bonus;
return {"shade" : "", "exp" : stride};
}
else if ( "Circles" == name ){
@ -1105,7 +1115,8 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
else if ( "Spite" == name ){
var spite = computeModifiers(name);
if($scope.attributeShade[name] == 'G'){
// If Grief is grey, the shadeshift cost has already been payed in the Grief exponent calculation
if($scope.attributeShade[name] == 'G' && $scope.attributeShade["Grief"] == 'B'){
spite -= 5;
}
spite += bonus;
@ -1189,30 +1200,6 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
return list;
}
/*
$scope.specialTraitsForDisplay = function(){
var list = [];
for(var traitName in burningData.traits) {
var trait = burningData.traits[traitName];
if ('restrict' in trait){
if ( trait.restrict.indexOf(validStockToRestrictionStock($scope.stock)) >= 0 &&
(trait.restrict.indexOf("special") >= 0 || trait.restrict.indexOf("character") >= 0) ){
list.push(new DisplayTrait(traitName, burningData.traits));
}
} else {
// No restriction! As long as cost > 0 (cost 0 is for traits with no cost; not purchaseable)
if ( trait.cost > 0 ) {
list.push(new DisplayTrait(traitName, burningData.traits));
}
}
}
return list;
}
*/
$scope.addLifepathTrait = function(traitName){
if ( $scope.unspentTraitPoints < 1 && $scope.enforcePointLimits )
@ -1950,63 +1937,31 @@ function calculateAge($scope){
$scope.age = age;
}
function isSubsetting(setting) { return !Object.values(setting).some((lp) => lp.born); }
function calculateSettingNames($scope, burningData){
var settingNames = null;
let stockSettings = burningData.lifepaths[$scope.stock];
$scope.settingNames = Object.keys(stockSettings);
var lastCurrentSetting = $scope.currentSetting;
if ( ! $scope.enforceLifepathReqts ) {
// Display all settings and subsettings
settingNames = [];
for(key in burningData.lifepaths[$scope.stock]){
settingNames.push(key);
}
}
else if ( $scope.selectedLifepaths.length == 0 ){
// All settings are allowed. Subsettings have no Born lifepath so don't include them.
settingNames = [];
for(key in burningData.lifepaths[$scope.stock]){
if( key.toLowerCase().indexOf("subsetting") < 0 ){
settingNames.push(key);
}
if ($scope.enforceLifepathReqts){
if ( $scope.selectedLifepaths.length == 0 ){
// All settings are allowed. Subsettings have no Born lifepath so don't include them.
$scope.settingNames = $scope.settingNames.filter(s => !isSubsetting(stockSettings[s]));
}
}
else {
// Only settings that are leads from the last lifepath are allowed
var lastLifepath = $scope.selectedLifepaths[$scope.selectedLifepaths.length-1];
settingNames = [];
var all = Object.keys(burningData.lifepaths[$scope.stock]);
for(var i = 0; i < all.length; i++){
//console.log("calculateSettingNames: checking if '"+all[i]+"' is allowed");
var setting = all[i];
if ( lastLifepath.setting == setting ){
settingNames.push(setting);
continue;
}
if ( lastLifepath.leads ){
for(var j = 0; j < lastLifepath.keyLeads.length; j++){
var lead = lastLifepath.keyLeads[j];
//console.log("calculateSettingNames: checking lead: '"+lead+"' is allowed");
else {
// Only settings that are leads from the last lifepath are allowed
var lastLifepath = $scope.selectedLifepaths[$scope.selectedLifepaths.length-1];
if( setting == lead ){
settingNames.push(setting);
}
}
}
// Doing this filtering instead of [lastLifepath.setting, ...lastLifepath.keyLeads] for two reasons:
// only presents settings present in this server and maintains relative order.
$scope.settingNames = $scope.settingNames.filter(s => s == lastLifepath.setting
|| (Array.isArray(lastLifepath.keyLeads) && lastLifepath.keyLeads.includes(s)));
}
}
$scope.settingNames = settingNames;
var currentSettingNeedsUpdate = true;
for(var i = 0; i < $scope.settingNames.length; i++){
if( $scope.settingNames[i] == lastCurrentSetting){
currentSettingNeedsUpdate = false;
break;
}
}
var currentSettingNeedsUpdate = !$scope.settingNames.includes(lastCurrentSetting);
if ( currentSettingNeedsUpdate && $scope.settingNames.length > 0 ){
$scope.currentSetting = $scope.settingNames[0];
@ -2019,13 +1974,6 @@ function calculatePTGS($scope) {
}
function isBornLifepath(lifepathName) {
return lifepathName.indexOf("Born") >= 0 ||
lifepathName == "Son Of A Gun" ||
lifepathName == "Gifted Child";
}
function calculateCurrentSettingLifepathNames($scope, burningData){
var currentSettingLifepathNames = null;
@ -2037,7 +1985,7 @@ function calculateCurrentSettingLifepathNames($scope, burningData){
if ( $scope.selectedLifepaths.length == 0 ){
// Only "Born" lifepaths are allowed
for(var i = 0; i < all.length; i++){
if ( isBornLifepath(all[i]) ){
if ( burningData.lifepaths[$scope.stock][$scope.currentSetting][all[i]].born ){
currentSettingLifepathNames.push(all[i]);
}
}
@ -2047,7 +1995,7 @@ function calculateCurrentSettingLifepathNames($scope, burningData){
for(var j = 0; j < lifepathNames.length; j++){
var lifepathName = lifepathNames[j];
if ( isBornLifepath(lifepathName) )
if ( burningData.lifepaths[$scope.stock][$scope.currentSetting][lifepathName].born )
continue;
var rexpr = burningData.lifepaths[$scope.stock][$scope.currentSetting][lifepathName].requires_expr
@ -2328,7 +2276,7 @@ function setCommonTraits($scope, burningData){
if( $scope.selectedLifepaths.length == 0 )
return;
var common = $scope.selectedLifepaths[0].commonTraits;
var common = burningData.stocks[$scope.stock].common_traits;
if(common.length > 0){
for(var j = 0; j < common.length; j++){
var name = common[j];
@ -2760,7 +2708,7 @@ function calculateSpecialTraitsForDisplay($scope, burningData){
var trait = burningData.traits[traitName];
if ('restrict' in trait){
if ( trait.restrict.indexOf(validStockToRestrictionStock($scope.stock)) >= 0 &&
if ( trait.restrict.indexOf(validStockToRestrictionStock(burningData.stocks, $scope.stock)) >= 0 &&
(trait.restrict.indexOf("special") >= 0 || trait.restrict.indexOf("character") >= 0) ){
list.push(new DisplayTrait(traitName, burningData.traits));
}
@ -2808,44 +2756,12 @@ function calculateUnspentResourcePoints($scope){
$scope.unspentResourcePoints = unspentResourcePoints;
}
function isValidStock(stock){
return stock == "man" || stock == "elf" || stock == "orc" || stock == "dwarf" || stock == "roden" || stock == "wolf" || stock =="troll";
}
function restrictionStockToValidStock(stock){
if ( stock == "mannish" )
return "man";
else if ( stock == "elven" )
return "elf";
else if ( stock == "orcish" )
return "orc";
else if ( stock == "dwarven" )
return "dwarf";
else if ( stock == "wolfish" )
return "wolf";
else if ( stock == "roden" )
return "roden";
else if ( stock == "trollish" )
return "troll";
function restrictionStockToValidStock(stocks, stockAdjective){
return Object.values(stocks).findLast(s => s.adjective == stockAdjective).key;
}
function validStockToRestrictionStock(stock){
if ( stock == "man" )
return "mannish";
else if ( stock == "elf" )
return "elven";
else if ( stock == "orc" )
return "orcish";
else if ( stock == "dwarf" )
return "dwarven";
else if ( stock == "roden" )
return "roden";
else if ( stock == "wolf" )
return "wolfish";
else if ( stock == "troll" )
return "trollish";
function validStockToRestrictionStock(stocks, stockName){
return stocks[stockName].adjective;
}
function attributeModifyingQuestions($scope, attribute)

@ -1,5 +1,5 @@
var serverSettings = {
'versionString' : '2.3.0',
'versionString' : '3.0.0',
'storageType' : 'client',
'displayAttrMath' : 'false'
}

@ -18,7 +18,7 @@
<title>Charred - The Burning Wheel Gold Character Burner</title>
</head>
<body>
<a href="https://github.com/modality/charred-black" class="github-corner" target="_blank" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<a href="https://git.obscuritus.ca:3000/danwizard208/charred-gold/" class="github-corner" target="_blank" aria-label="View source on GitTea"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<div class='container' ng-controller='BurningCtrl'>
<nav class='navbar navbar-default' role='navigation'>
<div class='navbar-header'>

@ -58,7 +58,7 @@
in the main view. At the end is a description of some tricks for specific stocks.
</p>
<p>
The source code for this version can be found on Github: <a href="https://github.com/modality/charred-black" target="_blank">Charred Black source</a>.
The source code for this version can be found on Gittea: <a href="https://git.obscuritus.ca:3000/danwizard208/charred-gold" target="_blank">Charred Gold source</a>.
</p>
<h2 id='tools'>Tools</h2>
<p>

@ -94,14 +94,7 @@
</strong>
</div>
<div class='col-md-2'>
<select class='form-control' ng-change='onStockChange()' ng-model='stock'>
<option value='man'>Man</option>
<option value='dwarf'>Dwarf</option>
<option value='elf'>Elf</option>
<option value='orc'>Orc</option>
<option value='roden'>Roden</option>
<option value='wolf'>Great Wolf</option>
<option value='troll'>Troll</option>
<select class='form-control' ng-change='onStockChange()' ng-model='stock' ng-options='s.key as s.name for s in stocks'>
</select>
</div>
<div class='col-md-1'>

@ -0,0 +1 @@
{"serialize_version":1,"name":"Algoric the Apologist","gender":"male","stock":"man","lifepaths":[["Peasant Setting","Born Peasant",0,null,null,null,[]],["College of Magic Setting","Supplicant",0,null,null,null,[]],["College of Magic Setting","Junior Student",0,null,null,null,[[1,"p"]]],["Outcast Subsetting","Rogue Wizard",0,null,null,null,[[1,"p"],[1,"m"]]],["Servitude And Captive Setting","Captive Of War",0,null,null,null,[]],["City Dweller Setting","Criminal",0,null,null,null,[[1,"pm"]]],["City Dweller Setting","Temple Acolyte",0,null,null,null,[[1,"m"]]],["Religious Subsetting","Priest",0,null,null,null,[[1,"m"]]]],"stats":[{"name":"Will","shade":"B","mentalPoints":5,"physicalPoints":0,"eitherPoints":1},{"name":"Perception","shade":"B","mentalPoints":5,"physicalPoints":0,"eitherPoints":0},{"name":"Power","shade":"B","mentalPoints":0,"physicalPoints":3,"eitherPoints":0},{"name":"Forte","shade":"B","mentalPoints":0,"physicalPoints":4,"eitherPoints":0},{"name":"Agility","shade":"B","mentalPoints":0,"physicalPoints":4,"eitherPoints":0},{"name":"Speed","shade":"B","mentalPoints":0,"physicalPoints":3,"eitherPoints":0}],"skills":{"lifepath":[{"name":"Animal Husbandry","lifepathPoints":1,"generalPoints":0},{"name":"Firebuilding","lifepathPoints":1,"generalPoints":0},{"name":"Read","lifepathPoints":1,"generalPoints":0},{"name":"Write","lifepathPoints":1,"generalPoints":0},{"name":"Ancient History","lifepathPoints":1,"generalPoints":0},{"name":"Circination","lifepathPoints":2,"generalPoints":0},{"name":"Illuminations","lifepathPoints":1,"generalPoints":0},{"name":"Astrology","lifepathPoints":2,"generalPoints":0},{"name":"Symbology","lifepathPoints":1,"generalPoints":0},{"name":"Sorcery","lifepathPoints":5,"generalPoints":0},{"name":"Inconspicuous","lifepathPoints":1,"generalPoints":0},{"name":"Graveyard-wise","lifepathPoints":1,"generalPoints":0},{"name":"Bloodletting","lifepathPoints":1,"generalPoints":0},{"name":"Ugly Truth","lifepathPoints":1,"generalPoints":0},{"name":"Apocalypse-wise","lifepathPoints":1,"generalPoints":0},{"name":"Enchanting","lifepathPoints":2,"generalPoints":0},{"name":"Alchemy","lifepathPoints":1,"generalPoints":0},{"name":"Cell-wise","lifepathPoints":1,"generalPoints":0},{"name":"Chain-wise","lifepathPoints":1,"generalPoints":0},{"name":"Streetwise","lifepathPoints":1,"generalPoints":0},{"name":"Intimidation","lifepathPoints":1,"generalPoints":0},{"name":"Knives","lifepathPoints":1,"generalPoints":0},{"name":"Climbing","lifepathPoints":1,"generalPoints":0},{"name":"Doctrine","lifepathPoints":1,"generalPoints":0},{"name":"Bureaucracy","lifepathPoints":1,"generalPoints":0},{"name":"Temple-wise","lifepathPoints":1,"generalPoints":0},{"name":"Oratory","lifepathPoints":1,"generalPoints":0},{"name":"Suasion","lifepathPoints":2,"generalPoints":0},{"name":"Ritual","lifepathPoints":1,"generalPoints":0},{"name":"Religious History","lifepathPoints":1,"generalPoints":0}],"general":[{"name":"Whip-wise","lifepathPoints":0,"generalPoints":1},{"name":"Herbalism","lifepathPoints":0,"generalPoints":2}]},"traits":[{"name":"Gifted"},{"name":"Second Sight"},{"name":"Fey Blood"},{"name":"Aura Of Fear"},{"name":"Obscure Aura"},{"name":"Poker Face"},{"name":"Faithful"}],"gear":[{"cost":1,"desc":"Clothes"},{"cost":1,"desc":"Traveling Gear"},{"cost":1,"desc":"Personal Effects"},{"cost":5,"desc":"Riding Mount Or Pack Animal"},{"cost":10,"desc":"Armor, Light Mail, Run Of The Mill Quality"},{"cost":14,"desc":"Spells"}],"property":[{"cost":10,"desc":"Property, A House"}],"relationships":[],"affiliations":[{"desc":"The Scurrilous Foes","importance":"small"}],"reputations":[{"desc":"An Escaped Prisoner","importance":"regional"}],"attr_mod_questions":{"Health":[{"question":"Was the character severely wounded in the past?","answer":true},{"question":"Is the character athletic and active?","answer":true}],"Steel":[{"question":"Has the character ever been severely wounded?","answer":true},{"question":"Has the character ever murdered or killed with his own hand more than once?","answer":true},{"question":"Has the character been raised in a competitive (but non-violent) culture - sports, debate, strategy games, courting?","answer":true}],"Faith":[{"question":"Is it only through God that you best serve your allies?","answer":false}]},"brutal_life_withdrawn":false,"approp_weapons":{}}

@ -0,0 +1 @@
{"name":"Algoric the Apologist","age":41,"stock":"man","lifepaths":["Born Peasant","Supplicant","Junior Student","Rogue Wizard","Captive Of War","Criminal","Temple Acolyte","Priest"],"stats":{"will":["B",6],"perception":["B",5],"power":["B",3],"forte":["B",4],"agility":["B",4],"speed":["B",3]},"attributes":{"mortal wound":["B",9],"reflexes":["B",4],"health":["B",5],"steel":["B",6],"hesitation":["",4],"stride":["",7],"circles":["B",3],"resources":["B",3],"faith":["B",3]},"skills":[["Animal Husbandry","B",3,false],["Firebuilding","B",2,false],["Read","B",2,false],["Write","B",2,false],["Ancient History","B",2,false],["Circination","B",2,false],["Illuminations","B",2,false],["Astrology","B",3,false],["Symbology","B",2,false],["Sorcery","B",5,false],["Inconspicuous","B",3,false],["Graveyard-wise","B",2,null],["Bloodletting","B",2,false],["Ugly Truth","B",2,false],["Apocalypse-wise","B",2,null],["Enchanting","B",2,false],["Alchemy","B",2,false],["Cell-wise","B",2,null],["Chain-wise","B",2,null],["Streetwise","B",2,false],["Intimidation","B",3,false],["Knives","B",2,false],["Climbing","B",1,false],["Doctrine","B",2,false],["Bureaucracy","B",3,false],["Temple-wise","B",2,null],["Oratory","B",3,false],["Suasion","B",4,false],["Ritual","B",2,false],["Religious History","B",2,false],["Whip-wise","B",2,false],["Herbalism","B",3,false]],"traits":[["Gifted","die"],["Second Sight","die"],["Fey Blood","die"],["Aura Of Fear","die"],["Obscure Aura","die"],["Poker Face","call_on"],["Faithful","die"],["Broken In","die"],["Hazed","die"],["Spooky","character"],["Claustrophobic","die"],["Cynical","character"],["Believer","die"],["Vested","die"]],"gear":["Clothes","Traveling Gear","Personal Effects","Riding Mount Or Pack Animal","Armor, Light Mail, Run Of The Mill Quality","Spells"],"property":["Property, A House"],"relationships":[],"reputations":["An Escaped Prisoner 2D"],"affiliations":["The Scurrilous Foes 1D"],"ptgs":{"su":3,"li":5,"mi":6,"se":7,"tr":8,"mo":9},"attr_mod_questions":{"Health":[{"question":"Does the character live in squalor and filth?","math_label":"(-1 Health)","modifier":-1},{"question":"Is the character frail or sickly?","math_label":"(-1 Health)","modifier":-1},{"question":"Was the character severely wounded in the past?","math_label":"(-1 Health)","modifier":-1,"answer":true},{"question":"Has the character been tortured and enslaved?","math_label":"(-1 Health)","modifier":-1},{"question":"Is the character athletic and active?","math_label":"(+1 Health)","modifier":1,"answer":true},{"question":"Does the character live in a really clean and happy place, like the hills in the Sound of Music?","math_label":"(+1 Health)","modifier":1}],"Steel":[{"question":"Has the character ever been severely wounded?","math_label":"(+1 Steel if combat lifepath taken/-1 Steel if not)","computeModifier":true,"answer":true},{"question":"Has the character ever murdered or killed with his own hand more than once?","math_label":"(+1 Steel)","modifier":1,"answer":true},{"question":"Has the character been tortured, enslaved or beaten terribly over time?","math_label":"(+1 Steel if Will is > 4, -1 Steel if Will < 4, +0 if Will is 4)","computeModifier":true},{"question":"Has the character lead a sheltered life, free of violence and pain?","math_label":"(-1 Steel)","modifier":-1},{"question":"Has the character been raised in a competitive (but non-violent) culture - sports, debate, strategy games, courting?","math_label":"(+1 Steel)","modifier":1,"answer":true},{"question":"Has the character given birth to a child?","math_label":"(+1 Steel)","modifier":1}],"Faith":[{"question":"Is God who you trust the most?","math_label":"(+1 Faith)","modifier":1},{"question":"When in danger, do you consult God for aid?","math_label":"(+1 Faith)","modifier":1},{"question":"Is it only through God that you best serve your allies?","math_label":"(+1 Faith)","modifier":1,"answer":false}]}}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
{"name":"Tyastanarphen","age":676,"stock":"elf","lifepaths":["Citadel Born","Wanderer","Song Singer","Bard","Loremaster","Griever","Liar","Deceiver","Recluse"],"stats":{"will":["B",8],"perception":["G",6],"power":["B",6],"forte":["B",5],"agility":["B",5],"speed":["B",5]},"attributes":{"mortal wound":["B",11],"reflexes":["B",6],"health":["B",5],"steel":["B",9],"hesitation":["",2],"stride":["",8],"circles":["B",4],"resources":["B",1],"grief":["G",4],"spite":["B",9]},"skills":[["Elven Script","G",4,false],["Sing","B",4,false],["Song Of Paths And Ways","G",3,false],["Air Of Gates","B",4,false],["Foraging","G",3,false],["Road-wise","G",3,false],["Song Of Songs","B",4,false],["Song Of Soothing","B",4,false],["Lament Of Stars","B",4,false],["Song Of Merriment","B",4,false],["Lament Of Mourning","B",4,false],["Tract Of Enmity","B",4,false],["Oratory","B",6,false],["Conspicuous","B",4,false],["Lyre","B",3,false],["Flute","B",3,false],["Ancient And Obscure History","G",3,false],["Research","G",3,false],["Ballad Of History","G",3,false],["Lyric Of Law","G",3,false],["Canticle Of Years","B",4,false],["Rhyme Of Tongues","B",4,false],["Sorrow Of Truth","B",4,false],["Dark Elf-wise","G",3,null],["Falsehood","B",4,false],["Soothing Platitudes","B",4,false],["Persuasion","B",6,false],["Twisted Tongue","B",4,false],["Sleight Of Hand","B",4,false],["Disguise","B",3,false],["Inconspicuous","B",4,false],["Rhyme Of The Unraveller","B",4,false],["Ancient History","G",3,false],["Dwarf-wise","G",3,false],["Elven Politics-wise","G",3,null],["Cut Of The Quickened Mind","B",4,false],["Antiphon Union Training","B",5,true],["Almanac","G",3,false]],"traits":[["Grim","character"],["Glib","call_on"],["Oikofugic","character"],["Voice In The Crowd","character"],["Spite","character"],["Compulsive Liar","character"],["Deceptive","call_on"],["Vengeful","die"],["Born Under The Silver Stars","character"],["Essence Of The Earth","die"],["Fair And Statuesque","character"],["First Born","die"],["Grief","die"],["Keen Sight","die"]],"gear":["Morlin Armor, Light Mail","Long Knife","Tome Of Lore","Cloak Of Darkness"],"property":["Remote Refuge, Safe House"],"relationships":[],"reputations":[],"affiliations":[],"ptgs":{"su":3,"li":6,"mi":8,"se":9,"tr":10,"mo":11},"attr_mod_questions":{"Health":[{"question":"Does the character live in squalor and filth?","math_label":"(-1 Health)","modifier":-1,"answer":true},{"question":"Is the character frail or sickly?","math_label":"(-1 Health)","modifier":-1},{"question":"Was the character severely wounded in the past?","math_label":"(-1 Health)","modifier":-1,"answer":true},{"question":"Has the character been tortured and enslaved?","math_label":"(-1 Health)","modifier":-1,"answer":true},{"question":"Is the character athletic and active?","math_label":"(+1 Health)","modifier":1,"answer":true},{"question":"Does the character live in a really clean and happy place, like the hills in the Sound of Music?","math_label":"(+1 Health)","modifier":1}],"Steel":[{"question":"Has the character ever been severely wounded?","math_label":"(+1 Steel if combat lifepath taken/-1 Steel if not)","computeModifier":true,"answer":true},{"question":"Has the character ever murdered or killed with his own hand more than once?","math_label":"(+1 Steel)","modifier":1,"answer":true},{"question":"Has the character been tortured, enslaved or beaten terribly over time?","math_label":"(+1 Steel if Will is > 4, -1 Steel if Will < 4, +0 if Will is 4)","computeModifier":true,"answer":true},{"question":"Has the character lead a sheltered life, free of violence and pain?","math_label":"(-1 Steel)","modifier":-1},{"question":"Has the character been raised in a competitive (but non-violent) culture - sports, debate, strategy games, courting?","math_label":"(+1 Steel)","modifier":1,"answer":true},{"question":"Has the character given birth to a child?","math_label":"(+1 Steel)","modifier":1,"answer":true}],"Grief":[{"question":"Does the character's history include tragedy?","math_label":"(+1 Grief)","modifier":1,"answer":true},{"question":"Has the character lived among non-Elven people?","math_label":"(+1 Grief)","modifier":1,"answer":true}],"Spite":[{"question":"Has the character been betrayed by their friends?","math_label":"(+1 Spite)","modifier":1,"answer":true},{"question":"Is the character lovesick or broken hearted?","math_label":"(+1 Spite)","modifier":1,"answer":true},{"question":"Has the character been abandoned by those they held dear?","math_label":"(+1 Spite)","modifier":1,"answer":true},{"question":"Has the character been abused or tortured?","math_label":"(+1 Spite)","modifier":1,"answer":true},{"question":"Does the character still respect or admire someone on the other side?","math_label":"(-1 Spite)","modifier":-1,"answer":true},{"question":"Does the character still love someone on the other side?","math_label":"(-2 Spite)","modifier":-2}]}}

@ -0,0 +1,133 @@
{
"stock": "test",
"settings": {
"Test Setting": {
"Born Test": {
"time": 7,
"res": 5,
"skills": [
[
1,
"General"
]
],
"traits": [
2
],
"leads": [
"Nowhere"
],
"key_leads": [
"Nowhere Setting"
]
},
"A thing": {
"time": 5,
"res": 2,
"stat": [
[
2,
"p"
]
],
"skills": [
[
4,
"Testing",
"Forest-wise",
"Stealthy"
]
],
"traits": [
1
],
"leads": [
"Nowhere"
],
"key_leads": [
"Nowhere Setting"
]
}
},
"Nowhere Setting": {
"Born Nothing": {
"time": 0,
"res": 0,
"skills": [
],
"traits": [
],
"leads": [
],
"key_leads": [
]
},
"Not A Thing": {
"time": 15,
"res": 1,
"stat": [
[
1,
"pm"
]
],
"skills": [
[
2,
"Nothinging",
"Voiding"
]
],
"traits": [
3
],
"leads": [
"Somewhere"
],
"key_leads": [
"Somewhere Subsetting"
]
}
},
"Somewhere Subsetting": {
"Something Special": {
"time": 30,
"res": 21,
"stat": [
[
1,
"m"
],[
1,
"p"
],[
1,
"pm"
]
],
"skills": [
[
7,
"Specializing",
"Soothing",
"History",
"Sorcery",
"Spirit Binding",
"Harming"
]
],
"traits": [
3,
"Stubborn",
"Shy"
],
"leads": [
"Nowhere"
],
"key_leads": [
"Nowhere Setting"
]
}
}
}
}

@ -0,0 +1,25 @@
{
"stock": "test",
"resources": [
{
"name": "Rags",
"type": "gear",
"rp": 1
},
{
"name": "Riches",
"type": "gear",
"rp": 50
},
{
"name": "A firey soul",
"type": "gear",
"rp": 3
},
{
"name": "Chest or Footlocker",
"type": "gear",
"rp": 3
}
]
}

@ -0,0 +1,39 @@
{
"Testing": {
"stock": "testish",
"roots": [
"Perception"
]
},
"Nothinging": {
"stock": "testish",
"roots": [
"Will",
"Agility"
]
},
"Voiding": {
"stock": "testish",
"roots": [
"Speed"
]
},
"Specializing": {
"stock": "testish",
"roots": [
"Forte"
]
},
"Soothing": {
"stock": "testish",
"roots": [
"Power"
]
},
"Harming": {
"stock": "testish",
"roots": [
"Will"
]
}
}

@ -0,0 +1,95 @@
{
"key": "test",
"name": "Test",
"stride": 9,
"adjective": "testish",
"common_traits": [
"Trait 1",
"testy",
"Trait #3",
"Night Eyed (Test)"
],
"starting_stats":
[
{
"range": [
1,
10
],
"m": 1,
"p": 2
},
{
"range": [
11,
20
],
"m": 2,
"p": 4
},
{
"range": [
21,
30
],
"m": 3,
"p": 6
},
{
"range": [
31,
40
],
"m": 4,
"p": 8
},
{
"range": [
41,
50
],
"m": 5,
"p": 10
},
{
"range": [
51,
60
],
"m": 6,
"p": 12
},
{
"range": [
61,
70
],
"m": 7,
"p": 14
},
{
"range": [
71,
80
],
"m": 8,
"p": 16
},
{
"range": [
81,
90
],
"m": 9,
"p": 18
},
{
"range": [
91,
100
],
"m": 10,
"p": 20
}
]
}

@ -0,0 +1,55 @@
{
"Trait 1": {
"cost": 0,
"type": "die",
"restrict": [
"testish",
"common"
],
"desc": ""
},
"testy": {
"cost": 0,
"type": "die",
"restrict": [
"testish",
"common"
],
"desc": ""
},
"Trait #3": {
"cost": 0,
"type": "die",
"restrict": [
"testish",
"common"
],
"desc": ""
},
"Night Eyed (Test)": {
"cost": 1,
"type": "die",
"restrict": [
"testish",
"common"
],
"desc": "The test version"
},
"Shy": {
"cost": 1,
"type": "character",
"restrict": [
"testish",
"lifepath"
]
},
"Special": {
"cost": 3,
"type": "die",
"restrict": [
"testish",
"special"
],
"desc": "Snowflake"
}
}
Loading…
Cancel
Save