gogo
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
**/*.sw*
|
||||||
|
**/__pycache__
|
||||||
BIN
design.d/assets.d/class_sheets.d/0.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/0.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/1.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/1.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/10.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/10.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/2.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/2.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/3.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/3.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/4.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/4.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/5.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/5.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/6.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/6.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/7.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/7.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/8.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/8.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/class_sheets.d/9.pdf
Normal file
BIN
design.d/assets.d/class_sheets.d/9.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/classes_with_icons.pdf
Normal file
BIN
design.d/assets.d/classes_with_icons.pdf
Normal file
Binary file not shown.
8
design.d/assets.d/dice_distribution.yaml
Normal file
8
design.d/assets.d/dice_distribution.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
- color: white
|
||||||
|
sides: [0, 0, 1, 1, 2, 2C]
|
||||||
|
- color: yellow
|
||||||
|
sides: [0, 0, 1, 2, 3, 3C]
|
||||||
|
- color: red
|
||||||
|
sides: [0, 0, 2, 3, 3, 4C]
|
||||||
|
- color: black
|
||||||
|
sides: [0, 0, 3, 3, 4, 5C]
|
||||||
105
design.d/assets.d/play_tldr.yaml
Normal file
105
design.d/assets.d/play_tldr.yaml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
- src: https://s3.amazonaws.com/geekdo-files.com/bgg338940?response-content-disposition=inline%3B%20filename%3D%22Oathsworn_player_aid_v2.pdf%22&response-content-type=application%2Fpdf&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJYFNCT7FKCE4O6TA%2F20230917%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230917T005449Z&X-Amz-SignedHeaders=host&X-Amz-Expires=120&X-Amz-Signature=c2daa6d7c83c99289b2d6698ea0ee102c84800942ebd439bd7ce948ade3595db
|
||||||
|
- stories: |
|
||||||
|
Story aid
|
||||||
|
Setup
|
||||||
|
Take permanent combat tokens. Full oathsworn health.
|
||||||
|
Use locations
|
||||||
|
Send runner - cost LVL coins, send to Banksmith or Apothecary.
|
||||||
|
Banksmith: buy LVL common cards, sell for half price (round up).
|
||||||
|
Price is card level.
|
||||||
|
Apothecary: Buy curatives (max 5) for LVL cost.
|
||||||
|
Trade coins or equip-items at any time between players and
|
||||||
|
company bag (bag limit 12 items)
|
||||||
|
Perform check/survival check: One Oathsworn. 1-10 white dice.
|
||||||
|
Tokens: Redraw (all checks), Empowered x3 (Might checks).
|
||||||
|
2 blanks is fail (do not regain tokens).
|
||||||
|
Dice value / difficulty = successes. FAIL: See story.
|
||||||
|
Round of Combat: Everyone. Might dice and 0-10 white dice.
|
||||||
|
Tokens: Redraw and Empowered 3x, no Ability Cards, Items Abilities,
|
||||||
|
or Special Abilities. 2 blanks is fail (do not regain tokens). Dice value /
|
||||||
|
defense = damage (round down). FAIL: -1 health.
|
||||||
|
- encounters: |
|
||||||
|
Encounter aid
|
||||||
|
Setup
|
||||||
|
If special rules box is checked, place it faceup. Otherwise revealed at
|
||||||
|
end of setup.
|
||||||
|
Pick 2 hands of weapons, 1 armor, 1 gear.
|
||||||
|
Set weapon might cubes, and armor/shield defense number token.
|
||||||
|
7 ability cards, choose from * to the current LVL, one with cooldown
|
||||||
|
(0), two (1), two (2), two (3).
|
||||||
|
Take max animus and place on left side, place regen tracker token if
|
||||||
|
necessary.
|
||||||
|
Pick first player.
|
||||||
|
1. Turn start
|
||||||
|
Regen aminus, pick up cards on cooldown 0. Next stage card is face
|
||||||
|
up.
|
||||||
|
2. Oathsworn take turns
|
||||||
|
Move: 1 animus per hex. All characters and terrain block movement.
|
||||||
|
Use ability card: pick card action, pay animus, resolve, place on
|
||||||
|
cooldown, battleflow.
|
||||||
|
Pass (does not end your round).
|
||||||
|
Oathsworn attack
|
||||||
|
Target closest location on large monsters.
|
||||||
|
Might value plus any number of white dice. May use combat tokens.
|
||||||
|
2+ blank is fail (don’t include critical).
|
||||||
|
SUCCESS: Damage = dice roll / defense (round down).
|
||||||
|
FAIL: Regain all used combat tokens + 1 of choice.
|
||||||
|
Monster attack
|
||||||
|
Hero may play one card to increase defense, no animus cost (then
|
||||||
|
battleflow).
|
||||||
|
Roll might, no critical or miss.
|
||||||
|
Damage = dice roll / defense (round down)
|
||||||
|
Oathsworn may spend defense tokens.
|
||||||
|
3. Encounter phase
|
||||||
|
(start here if ambushed)
|
||||||
|
3a. Activate large monster(s) following stage card.
|
||||||
|
Large movement destroys terrain, will bounce on edges, moves
|
||||||
|
through characters, ending on characters pushes them (no damage).
|
||||||
|
Change facing after move.
|
||||||
|
Attacks that display icons of broken locations draw 1 less of the best
|
||||||
|
Might cards.
|
||||||
|
Face towards attack target.
|
||||||
|
3b. Minion activation order: closest target in range and LOS (ignore
|
||||||
|
terrain effects) > Target with adjacent enemy with Mob keyword (if
|
||||||
|
attacker has Mob keyword only) > NW rule. Activate minion and
|
||||||
|
move,
|
||||||
|
3c. Minions attack, mob sum up might dice to one attack.
|
||||||
|
Targeting priority
|
||||||
|
Character who broke location (reaction only) > specific target on
|
||||||
|
Stage card if in range and LOS > closest Oathsworn in range and
|
||||||
|
LOS (ignore terrain effects) > Oathsworn with adjacent enemy with
|
||||||
|
Mob keyword (if Mob keyword) > NW rule. (Never targets ally/friendly
|
||||||
|
character, except reaction)
|
||||||
|
Keywords
|
||||||
|
Area Of Effect: may affect each character only once, gain +1
|
||||||
|
damage for each extra hex of a large figure, for melee AOEs LOS
|
||||||
|
to all targets needed, for ranged AOEs only the center hex needs
|
||||||
|
to be in LOS. One dice roll for all targets. Reactions do not cancel
|
||||||
|
hits on additional targets.
|
||||||
|
Battleflow: move all cards on one cooldown position to next. No
|
||||||
|
cascade.
|
||||||
|
Caged: can't do anything. See special rules. Each adjacent friendly
|
||||||
|
character gives +2 on survival check.
|
||||||
|
Chained attack: choose target in range and LOS, add additional
|
||||||
|
targets in chain range and LOS of the previous target. See AOE.
|
||||||
|
Remove lowest (not blank) dice result, once for each additional
|
||||||
|
target.
|
||||||
|
Charge Through X: Move X in straight line, attack all enemies moved
|
||||||
|
through, see AOE.
|
||||||
|
Consumed: Stuck in body part until broken or 6 damage delt. May
|
||||||
|
attack once per round for 3 animus. See special rules on start/end
|
||||||
|
round effects.
|
||||||
|
Crippled: No move or abilities with movement, until the end of the
|
||||||
|
next Oathsworn phase.
|
||||||
|
Empowered: Upgrade dice white>yellow>red>black.
|
||||||
|
Push: move straight away, or closest NW free hex.
|
||||||
|
Knockback: push that damages 1 on collision with terrain or
|
||||||
|
character (both take damage), no damage on board edge. Large is
|
||||||
|
pushed ½ distance (round up) and destroys terrain.
|
||||||
|
Line Of Sight: between closest corners. Or if straight tile row; center
|
||||||
|
to center. Line cannot touch any terrain. Ignore characters.
|
||||||
|
Thrown: place tracker in any adjacent hex to target, cannot pick up
|
||||||
|
this round.
|
||||||
|
Thrown weapon: unarmed, might is zero. Can still attack.
|
||||||
|
Thrown armor: no defense from items, no use of thrown item.
|
||||||
|
Wave attacks: 3 hex wide line of attack, nothing blocks it.
|
||||||
BIN
design.d/assets.d/v1_character_sheet.pdf
Normal file
BIN
design.d/assets.d/v1_character_sheet.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/v1_company_allies_etc.pdf
Normal file
BIN
design.d/assets.d/v1_company_allies_etc.pdf
Normal file
Binary file not shown.
BIN
design.d/assets.d/v1_free_company_sheet.pdf
Normal file
BIN
design.d/assets.d/v1_free_company_sheet.pdf
Normal file
Binary file not shown.
108
design.d/cdrt-experiment.d/cdrt.py
Normal file
108
design.d/cdrt-experiment.d/cdrt.py
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
from yaml import safe_load as yaml_load
|
||||||
|
from yaml import dump as yaml_dump
|
||||||
|
from sys import argv
|
||||||
|
|
||||||
|
def main():
|
||||||
|
path = "./testdata/hello_world.yaml"
|
||||||
|
if len(argv) > 1:
|
||||||
|
path = argv[1]
|
||||||
|
doc = Doc.from_file(path)
|
||||||
|
print(doc.render())
|
||||||
|
print(doc.to_dict())
|
||||||
|
|
||||||
|
# https://blog.kevinjahns.de/are-crdts-suitable-for-shared-editing/
|
||||||
|
class Doc():
|
||||||
|
def __init__(self):
|
||||||
|
self._nodes = []
|
||||||
|
|
||||||
|
def from_file(path):
|
||||||
|
doc = Doc()
|
||||||
|
with open(path, "r") as f:
|
||||||
|
d = yaml_load(f)
|
||||||
|
doc._nodes = [Node.from_dict(i) for i in d["nodes"]]
|
||||||
|
return doc
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return yaml_dump(slim_dict({
|
||||||
|
"nodes": [node.to_dict() for node in self._nodes],
|
||||||
|
}))
|
||||||
|
|
||||||
|
def render(self):
|
||||||
|
result = []
|
||||||
|
nodes = [node for node in self._nodes]
|
||||||
|
while nodes:
|
||||||
|
first = self._first_node(nodes)
|
||||||
|
result.append(first)
|
||||||
|
nodes = [node for node in nodes if node != first]
|
||||||
|
return "".join([i.content() for i in result])
|
||||||
|
|
||||||
|
def _first_node(self, nodes):
|
||||||
|
for potential_root_node in sorted([node for node in nodes if not node.from_id()], key=lambda x: x.id()):
|
||||||
|
return potential_root_node
|
||||||
|
node_ids = [node.id() for node in nodes]
|
||||||
|
for potential_rootest_node in sorted([node for node in nodes if not node.from_id() in node_ids], key=lambda x: x.id()):
|
||||||
|
return potential_rootest_node
|
||||||
|
raise Exception(nodes)
|
||||||
|
|
||||||
|
class Node():
|
||||||
|
def __init__(self, client_name, ts, content, is_delete, from_id, to_id):
|
||||||
|
self._ts = ts
|
||||||
|
self._client_name = client_name
|
||||||
|
self._content = content
|
||||||
|
self._is_delete = is_delete
|
||||||
|
self._from_id = from_id
|
||||||
|
self._to_id = to_id
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.to_dict())
|
||||||
|
|
||||||
|
def from_dict(d):
|
||||||
|
return Node(
|
||||||
|
d.get("client_name", ""),
|
||||||
|
d.get("ts", 0),
|
||||||
|
d.get("content", ""),
|
||||||
|
d.get("is_delete", False),
|
||||||
|
d.get("from", ""),
|
||||||
|
d.get("to", ""),
|
||||||
|
)
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return slim_dict({
|
||||||
|
"client_name": self._client_name,
|
||||||
|
"ts": self._ts,
|
||||||
|
"content": self._content,
|
||||||
|
"is_delete": self._is_delete,
|
||||||
|
"from": self._from_id,
|
||||||
|
"to": self._to_id,
|
||||||
|
})
|
||||||
|
|
||||||
|
def clone(self):
|
||||||
|
return Node(
|
||||||
|
self._ts,
|
||||||
|
self._client_name,
|
||||||
|
self._content,
|
||||||
|
self._is_delete,
|
||||||
|
self._from_id,
|
||||||
|
self._to_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
def id(self):
|
||||||
|
return f'{self._ts}/{self._client_name}'
|
||||||
|
|
||||||
|
def from_id(self):
|
||||||
|
return self._from_id
|
||||||
|
|
||||||
|
def to_id(self):
|
||||||
|
return self._to_id
|
||||||
|
|
||||||
|
def content(self):
|
||||||
|
if self._is_delete:
|
||||||
|
self._content = ""
|
||||||
|
return self._content
|
||||||
|
|
||||||
|
def slim_dict(d):
|
||||||
|
return {k:v for k,v in d.items() if v or (isinstance(v, int) and not isinstance(v, bool))}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
179
design.d/cdrt-experiment.d/cdrt1.py
Normal file
179
design.d/cdrt-experiment.d/cdrt1.py
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
from yaml import safe_load as yaml_load
|
||||||
|
from yaml import dump as yaml_dump
|
||||||
|
from sys import argv
|
||||||
|
|
||||||
|
def main():
|
||||||
|
path = "./testdata/hello_world.yaml"
|
||||||
|
if len(argv) > 1:
|
||||||
|
path = argv[1]
|
||||||
|
doc = Doc.from_file(path)
|
||||||
|
print(doc.render())
|
||||||
|
print(doc.to_dict())
|
||||||
|
|
||||||
|
# https://blog.kevinjahns.de/are-crdts-suitable-for-shared-editing/
|
||||||
|
class Doc():
|
||||||
|
def __init__(self):
|
||||||
|
self._nodes = []
|
||||||
|
self._edges = []
|
||||||
|
|
||||||
|
def from_file(path):
|
||||||
|
doc = Doc()
|
||||||
|
with open(path, "r") as f:
|
||||||
|
d = yaml_load(f)
|
||||||
|
doc._nodes = [Node.from_dict(i) for i in d["nodes"]]
|
||||||
|
doc._edges = [Edge.from_dict(i) for i in d["edges"]]
|
||||||
|
return doc
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return yaml_dump(slim_dict({
|
||||||
|
"nodes": [node.to_dict() for node in self._nodes],
|
||||||
|
"edges": [edge.to_dict() for edge in self._edges],
|
||||||
|
}))
|
||||||
|
|
||||||
|
def render(self):
|
||||||
|
result = []
|
||||||
|
sorted_edges = self.sorted_edges()
|
||||||
|
for edge in sorted_edges:
|
||||||
|
result.extend([i for i in self._nodes if i.id() == edge.from_id()])
|
||||||
|
if sorted_edges:
|
||||||
|
result.extend([i for i in self._nodes if i.id() == sorted_edges[-1].to_id()])
|
||||||
|
for node in sorted(self._nodes, key=lambda x: x.id()):
|
||||||
|
if not node in result:
|
||||||
|
if result:
|
||||||
|
self._edges.append(Edge.between(result[-1], node))
|
||||||
|
result.append(node)
|
||||||
|
return "".join([i.content() for i in result])
|
||||||
|
|
||||||
|
def sorted_edges(self):
|
||||||
|
result = []
|
||||||
|
edges = [edge for edge in self._edges]
|
||||||
|
while edges:
|
||||||
|
first = self._first_edge(edges)
|
||||||
|
edges = [i for i in edges if i != first]
|
||||||
|
result.append(first)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _first_edge(self, edges):
|
||||||
|
to_ids = [edge.to_id() for edge in edges]
|
||||||
|
from_ids = [edge.from_id() for edge in edges]
|
||||||
|
candidates = []
|
||||||
|
for from_id in from_ids:
|
||||||
|
if not from_id in to_ids:
|
||||||
|
candidates.append(from_id)
|
||||||
|
from_edges = [edge for edge in edges if edge.from_id() in candidates]
|
||||||
|
return sorted(from_edges, key=lambda x: x.from_id())[0]
|
||||||
|
|
||||||
|
class Edge():
|
||||||
|
def __init__(self, from_client_name, from_ts, to_client_name, to_ts):
|
||||||
|
self._from_client_name = from_client_name
|
||||||
|
self._from_ts = from_ts
|
||||||
|
self._to_client_name = to_client_name
|
||||||
|
self._to_ts = to_ts
|
||||||
|
|
||||||
|
def between(a, b):
|
||||||
|
return Edge(
|
||||||
|
a.client_name(),
|
||||||
|
a.ts(),
|
||||||
|
b.client_name(),
|
||||||
|
b.ts(),
|
||||||
|
)
|
||||||
|
|
||||||
|
def from_dict(d):
|
||||||
|
return Edge(
|
||||||
|
d.get("from", {}).get("client_name", ""),
|
||||||
|
d.get("from", {}).get("ts", 0),
|
||||||
|
d.get("to", {}).get("client_name", ""),
|
||||||
|
d.get("to", {}).get("ts", 0),
|
||||||
|
)
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return slim_dict({
|
||||||
|
"from": slim_dict({
|
||||||
|
"client_name": self._from_client_name,
|
||||||
|
"ts": self._from_ts,
|
||||||
|
}),
|
||||||
|
"to": slim_dict({
|
||||||
|
"client_name": self._to_client_name,
|
||||||
|
"ts": self._to_ts,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
def from_id(self):
|
||||||
|
return f'{self._from_ts}/{self._from_client_name}'
|
||||||
|
|
||||||
|
def to_id(self):
|
||||||
|
return f'{self._to_ts}/{self._to_client_name}'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self._from_ts}/{self._from_client_name}..{self._to_ts}/{self._to_client_name}'
|
||||||
|
|
||||||
|
class Node():
|
||||||
|
def __init__(self, client_name, ts, content, is_delete):
|
||||||
|
self._ts = ts
|
||||||
|
self._client_name = client_name
|
||||||
|
self._content = content
|
||||||
|
self._is_delete = is_delete
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.to_dict())
|
||||||
|
|
||||||
|
def from_dict(d):
|
||||||
|
return Node(
|
||||||
|
d.get("client_name", ""),
|
||||||
|
d.get("ts", 0),
|
||||||
|
d.get("content", ""),
|
||||||
|
d.get("is_delete", False),
|
||||||
|
)
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return slim_dict({
|
||||||
|
"client_name": self._client_name,
|
||||||
|
"ts": self._ts,
|
||||||
|
"content": self._content,
|
||||||
|
"is_delete": self._is_delete,
|
||||||
|
})
|
||||||
|
|
||||||
|
def clone(self):
|
||||||
|
return Node(
|
||||||
|
self._ts,
|
||||||
|
self._client_name,
|
||||||
|
self._content,
|
||||||
|
self._is_delete,
|
||||||
|
)
|
||||||
|
|
||||||
|
def id(self):
|
||||||
|
return f'{self._ts}/{self._client_name}'
|
||||||
|
|
||||||
|
def content(self):
|
||||||
|
if self.is_delete():
|
||||||
|
return ""
|
||||||
|
return self._content
|
||||||
|
|
||||||
|
def client_name(self):
|
||||||
|
return self._client_name
|
||||||
|
|
||||||
|
def ts(self):
|
||||||
|
return self._ts
|
||||||
|
|
||||||
|
def is_delete(self):
|
||||||
|
return self._is_delete
|
||||||
|
|
||||||
|
def split(self, idx):
|
||||||
|
up_to = self.clone()
|
||||||
|
up_to._content = up_to._content[:idx]
|
||||||
|
starting_at = self.clone()
|
||||||
|
starting_at._content = up_to._content[idx:]
|
||||||
|
return [up_to, starting_at]
|
||||||
|
|
||||||
|
def merge(self, other):
|
||||||
|
assert(self._client_name == other._client_name)
|
||||||
|
self._ts = max(self._ts, other._ts)
|
||||||
|
self._content += other._content
|
||||||
|
self._is_delete = self._is_delete or other._is_delete
|
||||||
|
return self
|
||||||
|
|
||||||
|
def slim_dict(d):
|
||||||
|
return {k:v for k,v in d.items() if v or (isinstance(v, int) and not isinstance(v, bool))}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
18
design.d/cdrt-experiment.d/test_cdrt.py
Normal file
18
design.d/cdrt-experiment.d/test_cdrt.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import unittest
|
||||||
|
import cdrt
|
||||||
|
|
||||||
|
class TestTestdata(unittest.TestCase):
|
||||||
|
def test(self):
|
||||||
|
from pathlib import Path
|
||||||
|
for path in Path('./testdata').rglob('*.yaml'):
|
||||||
|
doc = cdrt.Doc.from_file(path)
|
||||||
|
result = doc.render()
|
||||||
|
print(doc.to_dict())
|
||||||
|
with open(path, "r") as f:
|
||||||
|
d = cdrt.yaml_load(f)
|
||||||
|
if "expect" in d:
|
||||||
|
print(f'expect "{d["expect"]}", got "{result}"')
|
||||||
|
self.assertEqual(d["expect"], result)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
11
design.d/cdrt-experiment.d/testdata/append_dangling.yaml
vendored
Normal file
11
design.d/cdrt-experiment.d/testdata/append_dangling.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
expect: "hello world ohno"
|
||||||
|
nodes:
|
||||||
|
- ts: 0
|
||||||
|
content: hello
|
||||||
|
to: 1/
|
||||||
|
- ts: 1
|
||||||
|
content: " world"
|
||||||
|
from: 0/
|
||||||
|
- ts: 99
|
||||||
|
content: " ohno"
|
||||||
|
from: 0/
|
||||||
6
design.d/cdrt-experiment.d/testdata/conflict_resolution.yaml
vendored
Normal file
6
design.d/cdrt-experiment.d/testdata/conflict_resolution.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
expect: "maybeAmaybeB"
|
||||||
|
nodes:
|
||||||
|
- ts: 0
|
||||||
|
content: "maybeA"
|
||||||
|
- ts: 0
|
||||||
|
content: "maybeB"
|
||||||
10
design.d/cdrt-experiment.d/testdata/hello_world.yaml
vendored
Normal file
10
design.d/cdrt-experiment.d/testdata/hello_world.yaml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
expect: "hello world"
|
||||||
|
nodes:
|
||||||
|
- ts: 0
|
||||||
|
content: hello
|
||||||
|
client_name: x
|
||||||
|
to: 1/x
|
||||||
|
- ts: 1
|
||||||
|
content: " world"
|
||||||
|
client_name: x
|
||||||
|
from: 0/x
|
||||||
11
design.d/cdrt-experiment.d/testdata/is_delete.yaml
vendored
Normal file
11
design.d/cdrt-experiment.d/testdata/is_delete.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
expect: " world"
|
||||||
|
nodes:
|
||||||
|
- ts: 0
|
||||||
|
content: hello
|
||||||
|
client_name: x
|
||||||
|
to: 1/x
|
||||||
|
is_delete: true
|
||||||
|
- ts: 1
|
||||||
|
content: " world"
|
||||||
|
client_name: x
|
||||||
|
from: 0/x
|
||||||
16
design.d/cdrt-experiment.d/testdata/unordered.yaml
vendored
Normal file
16
design.d/cdrt-experiment.d/testdata/unordered.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
expect: "idx0idx1idx2idx3"
|
||||||
|
nodes:
|
||||||
|
- ts: 1
|
||||||
|
content: "idx0"
|
||||||
|
to: 0/
|
||||||
|
- ts: 0
|
||||||
|
content: "idx1"
|
||||||
|
from: 1/
|
||||||
|
to: 2/
|
||||||
|
- ts: 2
|
||||||
|
content: "idx2"
|
||||||
|
from: 0/
|
||||||
|
to: 3/
|
||||||
|
- ts: 3
|
||||||
|
content: "idx3"
|
||||||
|
from: 2/
|
||||||
42
design.d/data-model.yaml
Normal file
42
design.d/data-model.yaml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
id: xyz
|
||||||
|
last_modified: 2006-01-02T03:04:05Z
|
||||||
|
state:
|
||||||
|
players:
|
||||||
|
oathsworn:
|
||||||
|
xyz:
|
||||||
|
hp: 0
|
||||||
|
tokens:
|
||||||
|
- xyz # defense, 2animus, redraw, Nempower, battleflow
|
||||||
|
animus:
|
||||||
|
regen: 0 # 6+-
|
||||||
|
max: 0 # 6+-
|
||||||
|
companions:
|
||||||
|
xyz: {}
|
||||||
|
free_company:
|
||||||
|
name: xyz
|
||||||
|
chapters:
|
||||||
|
- number: 1 # [1,21]
|
||||||
|
progress:
|
||||||
|
story:
|
||||||
|
complete: false
|
||||||
|
ambushed: false
|
||||||
|
special_rules: false
|
||||||
|
unique_item: false
|
||||||
|
encounter: false
|
||||||
|
traits:
|
||||||
|
- name: xyz # [0,3] stacks per name
|
||||||
|
knockouts:
|
||||||
|
- chapter: x
|
||||||
|
name: xyz
|
||||||
|
city:
|
||||||
|
- number: [0, 0]
|
||||||
|
allies:
|
||||||
|
- number: 0
|
||||||
|
name: xyz
|
||||||
|
deceased: true
|
||||||
|
wood:
|
||||||
|
- number: [0, 0]
|
||||||
|
notes:
|
||||||
|
- xyz
|
||||||
|
keywords:
|
||||||
|
- xyz
|
||||||
Reference in New Issue
Block a user