Browse Source

initial commit

Getty Ritter 3 years ago
commit
c70390ee0d
4 changed files with 201 additions and 0 deletions
  1. 13 0
      assets.rkt
  2. 10 0
      citysworn.rkt
  3. 76 0
      core.rkt
  4. 102 0
      oracles.rkt

+ 13 - 0
assets.rkt

@@ -0,0 +1,13 @@
+#lang racket
+
+(require "core.rkt")
+
+(define-asset-path "Animal-Kin"
+  (basic "When you make a move to pacify, calm, control, aid, or fend off an animal"
+         "(or an animal or beast companion), add +1 and take +1 momentum on a hit.")
+  (advance "You may add or upgrade an animal or beast companion asset for 1 fewer"
+           "experience. Once you mark all their abilities, you may [Forge a Bond]"
+           "with them and take an automatic strong hit. When you do, mark a bond twice"
+           "and take 1 experience.")
+  (advance "Once per fight, when you leverage your animal or beast companion to make a"
+           "move, reroll any dice. On a hit, take +1 momentum."))

+ 10 - 0
citysworn.rkt

@@ -0,0 +1,10 @@
+#lang racket
+
+(require "core.rkt")
+(require "assets.rkt")
+(require "oracles.rkt")
+
+
+;; our stats differ from Ironsworn only in substituting Grit for Iron
+(struct stats [edge heart grit shadow wits])
+(struct character [name experience])

+ 76 - 0
core.rkt

@@ -0,0 +1,76 @@
+#lang racket
+
+;; start with some basic utilities
+(define (d n)
+  (random 1 (+ n 1)))
+
+;; the logic for judging the 'outcome' of an Ironsworn roll or progress track
+(define (judge-outcome attempt challenge-1 challenge-2)
+  (let [(outcome
+         (cond [(and (> attempt challenge-1) (> attempt challenge-2))
+                'success]
+               [(or (> attempt challenge-1) (> attempt challenge-2))
+                'partial]
+               [else 'failure]))]
+    `(,outcome ,attempt (,challenge-1 ,challenge-2))))
+  
+
+;; a typical Ironsworn roll:
+(define (roll-plus-mod m)
+  (let [
+         ;; roll two challenge dice
+         (challenge-1 (d 10))
+         (challenge-2 (d 10))
+         ;; roll an attempt die
+         (attempt (+ (d 6) m))]
+    ;; judge the outome
+    (judge-outcome attempt challenge-1 challenge-2)))
+
+
+;; this just keeps us honest that this is playable with dice
+(define *allowed-table-sizes* '(2 4 6 8 10 12 20 36 50 100))
+
+(define (oracle table)
+  (cond [(andmap valid-oracle-result? table)
+         (if (member (length table) *allowed-table-sizes*)
+             (lambda () (car (shuffle table)))
+             (error 'oracle "Length ~a is not a die-size-compatible length" (length table)))]
+        [(andmap valid-table-member? table)
+         (let [(max (max-table-size table))]
+           (lambda () (table-index (d max) table)))]
+        [else (error 'oracle "Unexpected argument: ~a" table)]))
+
+(define (max-table-size table)
+  (let [(final (last table))]
+    (if (= (length final) 3) (cadr final) (car final))))
+
+(define (valid-oracle-result? thing)
+  (or (symbol? thing) (string? thing)))
+
+(define (valid-table-member? member)
+  (and (list? member)
+       (or (and (= (length member) 3)
+                (number? (car member))
+                (number? (cadr member))
+                (valid-oracle-result? (caddr member)))
+           (and (= (length member) 2)
+                (number? (car member))
+                (valid-oracle-result? (cadr member))))))
+
+(define (table-index idx table)
+  (if (null? table)
+      (error 'table-index "Unexpected empty table")
+      (let [(head (car table))]
+        (cond [(and (= (length head) 3)
+                    (>= idx (car head))
+                    (<= idx (cadr head)))
+               (caddr head)]
+              [(and (= (length head) 2)
+                    (= idx (car head)))
+               (cadr head)]
+              [else (table-index idx (cdr table))]))))
+
+(define-syntax-rule [define-oracle name . table]
+  (define name (oracle (quote table))))
+
+(provide judge-outcome roll-plus-mod oracle define-oracle)

+ 102 - 0
oracles.rkt

@@ -0,0 +1,102 @@
+#lang racket
+
+(require "core.rkt")
+
+(define-oracle oracle/action
+  scheme clash weaken initiate create swear avenge guard defeat control
+  break risk surrender inspect raid evade assault deflect threaten attack
+  leave preserve manipulate remove eliminate withdraw abandon investigate hold focus
+  uncover breach aid uphold falter suppress hunt share destroy avoid
+  reject demand explore bolster seize mourn reveal gather defy transform
+  persevere serve begin move coordinate resist await impress take oppose
+  capture overwhelm challenge acquire protect finish strengthen restore advance command
+  refuse find deliver hide fortify betray secure arrive affect change
+  defend debate support follow construct locate endure release lose reduce
+  escalate distract journey escore learn communicate depart search charge summon)
+
+
+(define-oracle oracle/theme
+  risk ability price ally battle safety survival weapon wound shelter
+  leader fear time duty secret innocence renown direction death honor
+  labor solution tool balance love barrier creation decay trade bond
+  hope superstition peace deception history world vow protection nature opinion
+  burden vengeance opportunity faction danger corruption freedom debt hate possession
+  stranger passage land creature disease advantage blood language rumor weakness
+  greed family resource structure dream community war portent prize destiny
+  momentum power memory ruin mysticism rival problem idea revenge health
+  fellowship enemy religion spirit fame desolation strength knowledge truth quest
+  pride loss law path warning relationship wealth home strategy supply)
+
+;; TODO: figure out city regions
+(define-oracle oracle/region
+  (1 12 "Barrier Islands")
+  (13 24 "Ragged Coast")
+  (25 34 "Deep Wilds")
+  (35 46 "Flooded Lands")
+  (47 60 "Havens")
+  (61 72 "Hinterlands")
+  (73 84 "Tempest Hills")
+  (85 94 "Veiled Mountains")
+  (95 99 "Shattered Wastes")
+  (100 "Elsewhere"))
+
+;; TODO: figure out city locations
+(define-oracle oracle/location
+  (1 Hideout)
+  (2 Ruin)
+  (3 Mine)
+  (4 Waste)
+  (5 "Mystical Site")
+  (6 Path)
+  (7 Outpost)
+  (8 Wall)
+  (9 Battlefield)
+  (10 Hovel)
+  (11 Spring)
+  (12 Lair)
+  (13 Fort)
+  (14 Bridge)
+  (15 Camp)
+  (16 Cairn/Grave)
+  (17 18 Caravan)
+  (19 20 Waterfall)
+  (21 22 Cave)
+  (23 24 Swamp)
+  (25 26 Fen)
+  (27 28 Ravine)
+  (29 30 Road)
+  (31 32 Tree)
+  (33 34 Pond)
+  (35 36 Fields)
+  (37 38 Marsh)
+  (39 40 Steading)
+  (41 42 Rapids)
+  (43 44 Pass)
+  (45 46 Trail)
+  (47 48 Glade)
+  (49 50 Plain)
+  (51 52 Ridge)
+  (53 54 Cliff)
+  (55 56 Grove)
+  (57 58 Village)
+  (59 60 Moor)
+  (61 62 Thicket)
+  (63 64 "River Ford")
+  (65 66 Valley)
+  (67 68 Bay/Fjord)
+  (69 70 Foothills)
+  (71 72 Lake)
+  (73 75 River)
+  (76 79 Forest)
+  (80 83 Coast)
+  (84 88 Hill)
+  (89 93 Mountain)
+  (94 99 Woods)
+  (100 Anomaly))
+
+(define-oracle oracle/challenge-rank
+  ( 1  20 troublesome)
+  (21  55 dangerous)
+  (56  80 formidable)
+  (81  93 extreme)
+  (94 100 epic))