Compare commits
2 commits
d28e1b855f
...
68d85ba833
Author | SHA1 | Date | |
---|---|---|---|
|
68d85ba833 | ||
|
6c30f0447b |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -16,3 +16,4 @@ generated/**
|
|||
!images/**
|
||||
|
||||
.ninja_log
|
||||
build.ninja
|
||||
|
|
1348
.ninja_log
1348
.ninja_log
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@
|
|||
|
||||
package iditacards
|
||||
|
||||
#AssetKind: "image" | "tex" | "template" | "cat"
|
||||
#AssetKind: "image" | "tex" | "texdoc" | "template" | "cat"
|
||||
|
||||
#Asset: {
|
||||
// passed to convert to create the "print" version (usually to add bleed)
|
||||
|
@ -37,6 +37,10 @@ package iditacards
|
|||
source: string
|
||||
size: #Dimensions
|
||||
}
|
||||
|
||||
if kind == "texdoc" {
|
||||
source: string
|
||||
}
|
||||
}
|
||||
|
||||
// Assets are what actually need to be printed/created/etc
|
||||
|
|
|
@ -13,3 +13,10 @@ assets:
|
|||
source: iditaboard.tex
|
||||
size: 4875x3075
|
||||
|
||||
instructions:
|
||||
kind: texdoc
|
||||
source: instructions.tex
|
||||
|
||||
instructions-anatomy:
|
||||
kind: texdoc
|
||||
source: instructions-anatomy.tex
|
||||
|
|
1020
build.ninja
1020
build.ninja
File diff suppressed because it is too large
Load diff
|
@ -40,7 +40,7 @@ assets: {
|
|||
for deckname, deck in decks
|
||||
for cardname, freq in deck
|
||||
let card = cards[cardname] {
|
||||
"\(deckname)-\(cardname)[\(freq.count)]": {
|
||||
"cards/\(deckname)-\(cardname)[\(freq.count)]": {
|
||||
size: "750x1050"
|
||||
print: "-set option:distort:viewport 825x1125-37-37 -virtual-pixel Edge -distort SRT 0 +repage"
|
||||
|
||||
|
@ -72,7 +72,7 @@ pseudoassets: {
|
|||
contents: [
|
||||
for cardname, freq in deck
|
||||
for idx in list.Range(0, freq.count, 1) {
|
||||
"\(deckname)-\(cardname)[\(freq.count)]"
|
||||
"cards/\(deckname)-\(cardname)[\(freq.count)]"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ pseudoassets: {
|
|||
for deckname, deck in decks
|
||||
for cardname, card in deck {
|
||||
for idx in list.Range(0, card.count, 1) {
|
||||
"\(deckname)-\(cardname)[\(card.count)]"
|
||||
"cards/\(deckname)-\(cardname)[\(card.count)]"
|
||||
}
|
||||
},
|
||||
]
|
||||
|
|
179
configure.jq
Normal file → Executable file
179
configure.jq
Normal file → Executable file
|
@ -1,68 +1,121 @@
|
|||
#!/usr/bin/env -S jq -r -f
|
||||
# Takes iditacards output json and produces the dynamic ninja build
|
||||
# Example usage: cue export -- *.cue *.yaml | ./configure.jq > output/build.ninja
|
||||
|
||||
def expandout:
|
||||
to_entries[] | .value + { name: .key };
|
||||
def ifblank(x): if . | length > 0 then . else x end;
|
||||
def cuesources: $ARGS.positional | join(" ");
|
||||
def header: "# Generated from configure.jq, do not edit this file!
|
||||
|
||||
def everything:
|
||||
(
|
||||
(.assets | map_values(. + { pseudo: false })),
|
||||
(.pseudoassets | map_values(. + { pseudo: true }))
|
||||
) | expandout;
|
||||
root = .
|
||||
|
||||
def cuesources:
|
||||
$ARGS.positional | join(" ");
|
||||
rule configure
|
||||
description = recreate build.ninja using configure.jq
|
||||
command = cue export -- *.cue *.yaml | ./configure.jq --args -- *.cue *.yaml > $out
|
||||
generator = 1
|
||||
|
||||
"# Generated from configure.jq, do not edit this file!",
|
||||
"",
|
||||
"root = .",
|
||||
"",
|
||||
"rule configure",
|
||||
" description = recreate build.ninja using configure.jq via configure.sh",
|
||||
" command = bash configure.sh > build.ninja",
|
||||
" generator = 1",
|
||||
" restat = 1",
|
||||
"",
|
||||
"build build.ninja: configure | configure.jq configure.sh \(cuesources)",
|
||||
"include rules.ninja",
|
||||
"",
|
||||
"build output/everything.json: cuegen \(cuesources)",
|
||||
" filter = .",
|
||||
"", (
|
||||
everything | (
|
||||
select(.kind == "template") |
|
||||
.w = (.size | split("x")[0]) |
|
||||
.h = (.size | split("x")[1]) |
|
||||
.rawsuffix = (if .print then "raw." else "" end) |
|
||||
"build output/\(.name).json: extract output/everything.json",
|
||||
" filter = --arg asset '\(.name)' '.assets[$$asset].data'",
|
||||
"build output/\(.name).tex: template2tex output/\(.name).json | templates/\(.template)",
|
||||
" template = templates/\(.template)",
|
||||
"build output/\(.name).pdf: tex2pdf output/\(.name).tex || output/\(.name).pdf.dd",
|
||||
" dyndep = output/\(.name).pdf.dd",
|
||||
"build output/\(.name).pdf.dd: scantex output/\(.name).tex",
|
||||
"build output/\(.name).\(.rawsuffix)png: pdf2png output/\(.name).pdf",
|
||||
" w = \(.w)",
|
||||
" h = \(.h)",
|
||||
(select(.print) | "build output/\(.name).png: convert output/\(.name).raw.png"),
|
||||
(select(.print) | " args = \(.print)")
|
||||
),(
|
||||
select(.kind == "image") |
|
||||
.rawsuffix = (if .print then "raw." else "" end) |
|
||||
"build output/\(.name).\(.rawsuffix)png: copy \(.source)",
|
||||
(select(.print) | "build output/\(.name).png: convert output/\(.name).raw.png"),
|
||||
(select(.print) | " args = \(.print)")
|
||||
),(
|
||||
select(.kind == "tex") |
|
||||
.w = (.size | split("x")[0]) |
|
||||
.h = (.size | split("x")[1]) |
|
||||
.rawsuffix = (if .print then "raw." else "" end) |
|
||||
"build output/\(.name).pdf: tex2pdf \(.source) || output/\(.name).pdf.dd",
|
||||
" dyndep = output/\(.name).pdf.dd",
|
||||
"build output/\(.name).pdf.dd: scantex \(.source)",
|
||||
"build output/\(.name).\(.rawsuffix)png: pdf2png output/\(.name).pdf",
|
||||
" w = \(.w)",
|
||||
" h = \(.h)",
|
||||
(select(.print) | "build output/\(.name).png: convert output/\(.name).raw.png"),
|
||||
(select(.print) | " args = \(.print)")
|
||||
)
|
||||
)
|
||||
build build.ninja: configure | configure.jq \(cuesources)
|
||||
|
||||
base = .
|
||||
include rules.ninja
|
||||
|
||||
build output/.everything.json: cuegen \(cuesources)
|
||||
filter = .
|
||||
";
|
||||
|
||||
def dirof: split("/")[0:-1] | join("/") | if . | length > 0 then . + "/" else "" end;
|
||||
def filof: . as $saved | split("/")[-1] | ifblank($saved);
|
||||
def rawof: filof as $saved | split(".")[0:-1] | join(".") | ifblank($saved);
|
||||
|
||||
def generate_pdf_builds($dir; $raw; $tex): "
|
||||
build output/\($dir)\($raw).pdf: tex2pdf \($tex) || output/\($dir).\($raw).pdf.dd
|
||||
dyndep = output/\($dir).\($raw).pdf.dd
|
||||
|
||||
build output/\($dir).\($raw).pdf.dd: scantex \($tex)
|
||||
target = output/\($dir)\($raw).pdf
|
||||
";
|
||||
|
||||
def generate_png_from_pdf_builds($dir; $raw; $pdf):
|
||||
(.size | split("x")[0]) as $w |
|
||||
(.size | split("x")[1]) as $h |
|
||||
(if .print then "raw." else "" end) as $ext | "
|
||||
build output/\($dir)\($raw).\($ext)png: pdf2png \($pdf)
|
||||
w = \($w)
|
||||
h = \($h)
|
||||
";
|
||||
|
||||
def generate_png_copy_builds($dir; $raw; $png):
|
||||
(if .print then "raw." else "" end) as $ext | "
|
||||
build output/\($dir)\($raw).\($ext)png: copy \($png)
|
||||
";
|
||||
|
||||
def generate_print_png_builds($dir; $raw; $rawpng):
|
||||
if .print then "
|
||||
build output/\($dir)\($raw).png: convert \($rawpng)
|
||||
args = \(.print)
|
||||
" else empty end;
|
||||
|
||||
def generate_template_builds:
|
||||
(.name | dirof) as $dir |
|
||||
(.name | rawof) as $raw | ("
|
||||
build output/\($dir).\($raw).update | output/\($dir).\($raw).json: extract output/.everything.json
|
||||
filter = --arg asset '\(.name)' '.assets[$$asset].data'
|
||||
target = output/\($dir).\($raw).json
|
||||
|
||||
build output/\($dir)/tex/\($raw).tex: template2tex output/\($dir).\($raw).json | templates/\(.template)
|
||||
template = templates/\(.template)
|
||||
",
|
||||
generate_pdf_builds($dir; $raw; "output/\($dir)/tex/\($raw).tex"),
|
||||
generate_png_from_pdf_builds($dir; $raw; "output/\($dir)\($raw).pdf"),
|
||||
generate_print_png_builds($dir; $raw; "output/\($dir)\($raw).raw.png")
|
||||
);
|
||||
|
||||
def generate_image_builds:
|
||||
(.name | dirof) as $dir |
|
||||
(.name | rawof) as $raw | (
|
||||
generate_png_copy_builds($dir; $raw; .source),
|
||||
generate_print_png_builds($dir; $raw; "output/\($dir)\($raw).raw.png")
|
||||
);
|
||||
|
||||
def generate_tex_builds:
|
||||
(.size | split("x")[0]) as $w |
|
||||
(.size | split("x")[1]) as $h |
|
||||
(.name | dirof) as $dir |
|
||||
(.name | rawof) as $raw | (
|
||||
generate_pdf_builds($dir; $raw; .source),
|
||||
generate_png_from_pdf_builds($dir; $raw; "output/\($dir)\($raw).pdf"),
|
||||
generate_print_png_builds($dir; $raw; "output/\($dir)\($raw).raw.png")
|
||||
);
|
||||
|
||||
def generate_texdoc_builds:
|
||||
(.name | dirof) as $dir |
|
||||
(.name | rawof) as $raw | "
|
||||
build output/\($dir)\($raw).pdf: tex2pdf2x \(.source) || output/\($dir).\($raw).pdf.dd
|
||||
dyndep = output/\($dir).\($raw).pdf.dd
|
||||
|
||||
build output/\($dir).\($raw).pdf.dd: scantex \(.source)
|
||||
target = output/\($dir)\($raw).pdf
|
||||
";
|
||||
|
||||
def generate_cat_builds:
|
||||
(.contents | map("output/" + . + ".pdf") | join(" ")) as $pdfcontents |
|
||||
(.contents | map("output/" + . + ".png") | join(" ")) as $pngcontents |
|
||||
(.contents | map("output/" + . + ".raw.png") | join(" ")) as $rawcontents |
|
||||
(.name | dirof) as $dir |
|
||||
(.name | rawof) as $raw | "
|
||||
build output/\($dir)\($raw).pdf: pdfunite \($pdfcontents)
|
||||
build output/\($dir)\($raw).png: pngunite \($pngcontents)
|
||||
build output/\($dir)\($raw).raw.png: pngunite \($rawcontents)
|
||||
";
|
||||
|
||||
def generate_builds:
|
||||
(select(.kind == "template") | generate_template_builds),
|
||||
(select(.kind == "image") | generate_image_builds),
|
||||
(select(.kind == "tex") | generate_tex_builds),
|
||||
(select(.kind == "texdoc") | generate_texdoc_builds),
|
||||
(select(.kind == "cat") | generate_cat_builds);
|
||||
|
||||
def expandout: to_entries[] | .value + { name: .key };
|
||||
def everything: (.assets, .pseudoassets) | expandout;
|
||||
|
||||
header,
|
||||
(everything | generate_builds)
|
||||
|
|
98
configure.py
Normal file
98
configure.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
""" Generates build.ninja for iditacards build in output/. """
|
||||
|
||||
import glob
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
|
||||
cue_sources = glob.glob(f'*.cue')
|
||||
yaml_sources = glob.glob(f'*.yaml')
|
||||
sources = cue_sources + yaml_sources
|
||||
|
||||
everything = json.loads(subprocess.run(['cue', 'export', '--'] + sources, stdout=subprocess.PIPE).stdout)
|
||||
|
||||
assets = everything['assets']
|
||||
pseudos = everything['pseudoassets']
|
||||
all_assets = { **assets, **pseudos }
|
||||
|
||||
print('# Generated from configure.sh, do not edit this file!\n')
|
||||
|
||||
with open(f'{script_dir}/rules.ninja', 'r') as f:
|
||||
print(f.read())
|
||||
|
||||
print(f'''
|
||||
base = .
|
||||
|
||||
rule configure
|
||||
description = recreate $out using $in
|
||||
command = $in > $out
|
||||
generator = 1
|
||||
restat = 1
|
||||
|
||||
build build.ninja: configure ./configure.py | {' '.join(sources)}
|
||||
|
||||
build output/.everything.json: cuegen {' '.join(sources)}
|
||||
filter = .
|
||||
''')
|
||||
|
||||
for name, asset in all_assets.items():
|
||||
assetdir = os.path
|
||||
if asset['kind'] == 'template':
|
||||
print(f'''
|
||||
build output/.{name}.update | .{name}.json: extract .everything.json
|
||||
filter = --arg asset '{name}' '.assets[$$asset].data'
|
||||
target = .{name}.json
|
||||
|
||||
build tex/{name}.tex: template2tex .{name}.json | ../templates/{asset["template"]}
|
||||
template = ../templates/{asset["template"]}
|
||||
|
||||
build {name}.pdf: tex2pdf tex/{name}.tex || .{name}.pdf.dd
|
||||
dyndep = .{name}.pdf.dd
|
||||
|
||||
build .{name}.pdf.dd: scantex tex/{name}.tex
|
||||
target = {name}.pdf
|
||||
|
||||
build {name}.{'raw.' if 'print' in asset else ''}png: pdf2png {name}.pdf
|
||||
w = {asset['size'].split('x')[0]}
|
||||
h = {asset['size'].split('x')[1]}
|
||||
''')
|
||||
|
||||
if asset['kind'] == 'image':
|
||||
print(f'''
|
||||
build {name}.{'raw.' if 'print' in asset else ''}png: copy ../{asset['source']}
|
||||
''')
|
||||
|
||||
if asset['kind'] == 'tex':
|
||||
print(f'''
|
||||
build {name}.pdf: tex2pdf ../{asset['source']} || .{name}.pdf.dd
|
||||
dyndep = .{name}.pdf.dd
|
||||
|
||||
build .{name}.pdf.dd: scantex ../{asset['source']}
|
||||
target = {name}.pdf
|
||||
|
||||
build {name}.{'raw.' if 'print' in asset else ''}png: pdf2png {name}.pdf
|
||||
w = {asset['size'].split('x')[0]}
|
||||
h = {asset['size'].split('x')[1]}
|
||||
''')
|
||||
|
||||
if asset['kind'] == 'texdoc':
|
||||
print(f'''
|
||||
build {name}.pdf: tex2pdf2x ../{asset['source']} || .{name}.pdf.dd
|
||||
dyndep = .{name}.pdf.dd
|
||||
|
||||
build .{name}.pdf.dd: scantex ../{asset['source']}
|
||||
target = {name}.pdf
|
||||
''')
|
||||
|
||||
if asset['kind'] == 'cat':
|
||||
print(f'''
|
||||
build {name}.pdf: pdfunite {' '.join(content + '.pdf' for content in asset['contents'])}
|
||||
''')
|
||||
|
||||
if 'print' in asset:
|
||||
print(f'''
|
||||
build {name}.png: convert {name}.raw.png
|
||||
args = {asset['print']}
|
||||
''')
|
141
configure.sh
141
configure.sh
|
@ -1,4 +1,141 @@
|
|||
#!/bin/bash
|
||||
|
||||
# The real configure script uses jq to parse cue output
|
||||
cue export -- *.cue *.yaml | jq -r -f configure.jq --args -- *.cue *.yaml
|
||||
# Outputs a build.ninja script for placing into $1 (or output/ if omitted)
|
||||
|
||||
scriptdir="$(dirname -- "${BASH_SOURCE[0]}")"
|
||||
builddir="${1-output}"
|
||||
|
||||
cue_sources=( "$scriptdir"/*.cue "$scriptdir"/*.yaml )
|
||||
everything="$(cue export -- "${cue_sources[@]}" | jq -c)"
|
||||
ASSET_TO_JSON="| to_entries[] | .value + { name: .key }"
|
||||
mapfile -t assets < <(jq -c ".assets $ASSET_TO_JSON" <<<"$everything")
|
||||
mapfile -t pseudos < <(jq -c ".pseudoassets $ASSET_TO_JSON" <<<"$everything")
|
||||
|
||||
# base is the directory that contains the script
|
||||
base="$(realpath -s --relative-to="$builddir" "$scriptdir")"
|
||||
|
||||
# root is the directory that the assets are generated into
|
||||
root=.
|
||||
|
||||
relative_cue_sources=( )
|
||||
for cue_source in "${cue_sources[@]}"; do
|
||||
relative_cue_sources+=( "$base/$cue_source" )
|
||||
done
|
||||
|
||||
cat <<EOF
|
||||
# Generated from configure.sh, do not edit this file!
|
||||
|
||||
base = $base
|
||||
|
||||
EOF
|
||||
|
||||
cat "$scriptdir/rules.ninja"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
rule configure
|
||||
description = recreate build.ninja using $base/configure.sh
|
||||
command = $base/configure.sh $root
|
||||
generator = 1
|
||||
restat = 1
|
||||
|
||||
build ./build.ninja: configure | $base/configure.sh ${relative_cue_sources[*]}
|
||||
|
||||
build $root/.everything.json: cuegen ${relative_cue_sources[*]}
|
||||
filter = .
|
||||
|
||||
EOF
|
||||
|
||||
for asset in "${assets[@]}" "${pseudos[@]}"; do
|
||||
# reset asset variables, also quiets shellcheck
|
||||
name=
|
||||
print=
|
||||
kind=
|
||||
source=
|
||||
template=
|
||||
size=
|
||||
data=
|
||||
contents=
|
||||
|
||||
eval "$(jq -r 'to_entries[] | "\(.key)=\(.value|@text|@sh)"' <<<"$asset")"
|
||||
rawsuffix="$(echo -n "$print" | sed 's/.*/raw./')"
|
||||
|
||||
case $kind in
|
||||
template)
|
||||
cat <<EOF
|
||||
build $root/.$name.updated | $root/.$name.json: extract $root/.everything.json
|
||||
filter = --arg asset '$name' '.assets[\$\$asset].data'
|
||||
target = $root/.$name.json
|
||||
|
||||
build $root/tex/$name.tex: template2tex $root/.$name.json | $base/templates/$template
|
||||
template = $base/templates/$template
|
||||
|
||||
build $root/$name.pdf: tex2pdf $root/tex/$name.tex || $root/.$name.pdf.dd
|
||||
dyndep = $root/.$name.pdf.dd
|
||||
|
||||
build $root/.$name.pdf.dd: scantex $root/tex/$name.tex
|
||||
target = $root/$name.pdf
|
||||
|
||||
build $root/$name.${rawsuffix}png: pdf2png $root/$name.pdf
|
||||
w = ${size%x*}
|
||||
h = ${size#*x}
|
||||
|
||||
EOF
|
||||
;;
|
||||
|
||||
image)
|
||||
cat <<EOF
|
||||
build $root/$name.${rawsuffix}png: copy $base/$source
|
||||
|
||||
EOF
|
||||
;;
|
||||
|
||||
tex)
|
||||
cat <<EOF
|
||||
build $root/$name.pdf: tex2pdf $base/$source || $root/.$name.pdf.dd
|
||||
dyndep = $root/.$name.pdf.dd
|
||||
|
||||
build $root/.$name.pdf.dd: scantex $base/$source
|
||||
target = $root/$name.pdf
|
||||
|
||||
build $root/$name.${rawsuffix}png: pdf2png $root/$name.pdf
|
||||
w = ${size%x*}
|
||||
h = ${size#*x}
|
||||
|
||||
EOF
|
||||
;;
|
||||
|
||||
texdoc)
|
||||
cat <<EOF
|
||||
build $root/$name.pdf: tex2pdf2x $base/$source || $root/.$name.pdf.dd
|
||||
dyndep = $root/.$name.pdf.dd
|
||||
|
||||
build $root/.$name.pdf.dd: scantex $base/$source
|
||||
target = $root/$name.pdf
|
||||
|
||||
EOF
|
||||
;;
|
||||
|
||||
cat)
|
||||
mapfile -t ins < <(jq -r ".[]" <<<"$contents")
|
||||
echo -n "build $root/$name.pdf: pdfunite"
|
||||
for i in "${ins[@]}"; do
|
||||
echo -n " $root/$i.pdf"
|
||||
done
|
||||
echo
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "ERROR! UNKNOWN ASSET TYPE $kind!" >&2
|
||||
;;
|
||||
esac
|
||||
|
||||
# always run convert if print is non-empty
|
||||
if [ -n "$print" ]; then
|
||||
cat <<EOF
|
||||
build $root/$name.png: convert $root/$name.raw.png
|
||||
args = $print
|
||||
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -79,7 +79,9 @@
|
|||
\clearpage
|
||||
|
||||
\section{Overview}
|
||||
% Your background story/recap on what situation the players are getting themselves into. It sets the scene (thematically, usually) for the entire game.
|
||||
% Your background story/recap on what situation the players are getting
|
||||
% themselves into. It sets the scene (thematically, usually) for the entire
|
||||
% game.
|
||||
|
||||
Iditacards is a game where you race your opponents in the last great race on
|
||||
earth - The Iditarod. You will face starvation, hypothermia, and inclement
|
||||
|
@ -89,7 +91,10 @@ form to come out ahead.
|
|||
The first player to cross the finish line wins!
|
||||
|
||||
\section{Components}
|
||||
% This isn’t so important for playtesters at this point, but is important for the final rulebook and print and plays (PnP). This way players (including yourself) know whether or not there are missing pieces, or in the case of PnP players, if they have everything they need in order to play.
|
||||
% This isn’t so important for playtesters at this point, but is important for
|
||||
% the final rulebook and print and plays (PnP). This way players (including
|
||||
% yourself) know whether or not there are missing pieces, or in the case of PnP
|
||||
% players, if they have everything they need in order to play.
|
||||
|
||||
This game contains many cards. They can be sorted based on the symbol in the
|
||||
bottom right corner:
|
||||
|
@ -118,7 +123,10 @@ The game also contains:
|
|||
\clearpage
|
||||
|
||||
\section{Objective}
|
||||
% What the players are trying to accomplish. It should also make it clear how players are competing (free-for-all, teams, cooperative, etc.). This is the more technical/mechanical explanation of the 'Overview'. For example: “To be the last player with multiple spaceships orbiting the black hole”.
|
||||
% What the players are trying to accomplish. It should also make it clear how
|
||||
% players are competing (free-for-all, teams, cooperative, etc.). This is the
|
||||
% more technical/mechanical explanation of the 'Overview'. For example: “To be
|
||||
% the last player with multiple spaceships orbiting the black hole”.
|
||||
|
||||
Every turn each player will move forward one space. The cards they play will
|
||||
increase this, while the places they encounter will work to decrease it. When
|
||||
|
@ -126,7 +134,11 @@ the first player reaches the finish line the game ends. The finish line is the
|
|||
square \emph{after} the last square on the board.
|
||||
|
||||
\section{Setup}
|
||||
% How to get the game ready for play. There shouldn’t be anything in here that mentions what components are used for or why they are important--save that for the 'Gameplay' section. Just make sure that in this section everything is laid out clearly--if diagrams are necessary (they almost always are) don’t be afraid to put those in!
|
||||
% How to get the game ready for play. There shouldn’t be anything in here that
|
||||
% mentions what components are used for or why they are important--save that for
|
||||
% the 'Gameplay' section. Just make sure that in this section everything is laid
|
||||
% out clearly--if diagrams are necessary (they almost always are) don’t be
|
||||
% afraid to put those in!
|
||||
|
||||
To start the game each player must pick a colour. They take the token of that
|
||||
colour and place it in the ``Start'' space.
|
||||
|
@ -145,7 +157,9 @@ Before starting the game everybody draws 6 cards. The first player to grab the
|
|||
weather die goes first. They roll it, then take their turn.
|
||||
|
||||
\section{Gameplay}
|
||||
% The main gameplay section tells you how the game is broken up (rounds, turns, phases, etc.) and summarizes what players do in each of those stages. This section should explain the flow of the game from start to completion.
|
||||
% The main gameplay section tells you how the game is broken up (rounds, turns,
|
||||
% phases, etc.) and summarizes what players do in each of those stages. This
|
||||
% section should explain the flow of the game from start to completion.
|
||||
|
||||
The game is broken into turns. Each turn you may either play a card, or take
|
||||
a new day. At the end of your turn you automatically move a distance equal to
|
||||
|
@ -160,7 +174,11 @@ limit on hand size, however if there aren't enough cards in your deck to fill
|
|||
your hand, then your hand will consist only of however many cards are available
|
||||
to be drawn.
|
||||
|
||||
% Once that’s done, you go into the gameplay specifics, which should be explained in the order in which they occur in game. This is where you explain exactly what happens during each turn, action, round, etc. You also should have sections dedicated to complicated subjects and their edge cases (for instance, our section on Collisions for “Pulled into Darkness”).
|
||||
% Once that’s done, you go into the gameplay specifics, which should be
|
||||
% explained in the order in which they occur in game. This is where you explain
|
||||
% exactly what happens during each turn, action, round, etc. You also should
|
||||
% have sections dedicated to complicated subjects and their edge cases (for
|
||||
% instance, our section on Collisions for “Pulled into Darkness”).
|
||||
\subsection{Movement}
|
||||
|
||||
As in any race, movement is important. Whenever you move you add your current
|
||||
|
@ -185,7 +203,7 @@ If you pass the checkerboard finish line you win the game.
|
|||
|
||||
\subsection{Card Anatomy}
|
||||
|
||||
\includegraphics{instructions-anatomy.pdf}
|
||||
\includegraphics{output/instructions-anatomy.pdf}
|
||||
|
||||
In this example card, the energy cost is \emph{X} the health cost is \emph{Y}
|
||||
and the risk cost is \emph{Z}.
|
||||
|
|
4
legs.cue
4
legs.cue
|
@ -19,7 +19,7 @@ legs: [string]: #Leg
|
|||
|
||||
assets: {
|
||||
for legname, leg in legs {
|
||||
"\(legname)[1]": {
|
||||
"legs/\(legname)[1]": {
|
||||
size: "750x1050"
|
||||
print: "-set option:distort:viewport 825x1125-37-37 -virtual-pixel Edge -distort SRT 0 +repage"
|
||||
|
||||
|
@ -40,7 +40,7 @@ pseudoassets: {
|
|||
"\(deckname)": {
|
||||
kind: "cat"
|
||||
contents: [
|
||||
for legname, one in legs {"\(legname)[1]"},
|
||||
for legname, one in legs {"legs/\(legname)[1]"},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
181
legs.yaml
181
legs.yaml
|
@ -1,6 +1,12 @@
|
|||
# The legs (TODO: export shorthands for each leg effect in iditacard.cls so that
|
||||
# the cue generation/gomplate instantiation can be simplified)
|
||||
#
|
||||
# TODO: consider returning to the old leg system, it allowed for more
|
||||
# flavour and less clutter, its main downside was that the game was too
|
||||
# "complicated" and that slowed it down, perhaps decrease the density of legs
|
||||
# while still using the old card-based system?
|
||||
legs:
|
||||
# First legs
|
||||
farm:
|
||||
name: 'Farm'
|
||||
level: firstleg
|
||||
|
@ -9,3 +15,178 @@ legs:
|
|||
3: hypo
|
||||
5: damage
|
||||
7: hypo
|
||||
|
||||
fishing_hole:
|
||||
name: 'Fishing Hole'
|
||||
level: firstleg
|
||||
effect: '\daydraw{3}'
|
||||
spaces:
|
||||
3: damage
|
||||
5: hypo
|
||||
7: damage
|
||||
|
||||
hospital:
|
||||
name: 'Hospital'
|
||||
level: firstleg
|
||||
effect: '\freecardtype{personal}'
|
||||
spaces:
|
||||
3: starve
|
||||
5: hypo
|
||||
7: starve
|
||||
|
||||
new_moon:
|
||||
name: 'New Moon'
|
||||
level: firstleg
|
||||
effect: '\freecardtype{dog}'
|
||||
spaces:
|
||||
3: hypo
|
||||
5: starve
|
||||
7: hypo
|
||||
|
||||
repair_shop:
|
||||
name: 'Repair Shop'
|
||||
level: firstleg
|
||||
effect: '\freecardtype{sled}'
|
||||
spaces:
|
||||
3: starve
|
||||
5: damage
|
||||
7: starve
|
||||
|
||||
volcano:
|
||||
name: 'Volcano'
|
||||
level: firstleg
|
||||
effect: '\allowednot{\includegraphics[width=1cm]{icons/hypo.png}}'
|
||||
spaces:
|
||||
3: damage
|
||||
5: starve
|
||||
7: damage
|
||||
|
||||
|
||||
# Second legs
|
||||
downhill:
|
||||
name: 'Downhill'
|
||||
level: secondleg
|
||||
effect: '\speed{3}'
|
||||
spaces:
|
||||
2: hypo
|
||||
4: damage
|
||||
6: damage
|
||||
8: hypo
|
||||
|
||||
junkyard:
|
||||
name: 'Junkyard'
|
||||
level: secondleg
|
||||
effect: '\healthcosts{-1}'
|
||||
spaces:
|
||||
2: damage
|
||||
4: hypo
|
||||
6: hypo
|
||||
8: damage
|
||||
|
||||
park:
|
||||
name: 'Park'
|
||||
level: secondleg
|
||||
effect: '\freecardtype{attachment}'
|
||||
spaces:
|
||||
2: starve
|
||||
4: damage
|
||||
6: damage
|
||||
8: starve
|
||||
|
||||
solar_farm:
|
||||
name: 'Solar Farm'
|
||||
level: secondleg
|
||||
effect: '\energycosts{-1}'
|
||||
spaces:
|
||||
2: damage
|
||||
4: starve
|
||||
6: starve
|
||||
8: damage
|
||||
|
||||
town:
|
||||
name: 'Town'
|
||||
level: secondleg
|
||||
effect: '\freecardtype{food}'
|
||||
spaces:
|
||||
2: hypo
|
||||
4: starve
|
||||
6: starve
|
||||
8: hypo
|
||||
|
||||
village:
|
||||
name: 'Village'
|
||||
level: secondleg
|
||||
effect: '\healthcosts{-1}'
|
||||
spaces:
|
||||
2: starve
|
||||
4: hypo
|
||||
6: hypo
|
||||
8: starve
|
||||
|
||||
# Third legs
|
||||
cliff:
|
||||
name: 'Cliff'
|
||||
level: thirdleg
|
||||
effect: '\allowednot{\cardtypetext{personal}{}}'
|
||||
spaces:
|
||||
1: starve
|
||||
3: hypo
|
||||
5: starve
|
||||
7: hypo
|
||||
9: starve
|
||||
|
||||
wasteland:
|
||||
name: 'Wasteland'
|
||||
level: thirdleg
|
||||
effect: '\allowednot{\cardtypetext{food}{}}'
|
||||
spaces:
|
||||
1: damage
|
||||
3: starve
|
||||
5: damage
|
||||
7: starve
|
||||
9: damage
|
||||
|
||||
exposed:
|
||||
name: 'Exposed'
|
||||
level: thirdleg
|
||||
effect: '\daydraw{-3}'
|
||||
spaces:
|
||||
1: hypo
|
||||
3: starve
|
||||
5: hypo
|
||||
7: starve
|
||||
9: hypo
|
||||
|
||||
mountainside:
|
||||
name: 'Mountainside'
|
||||
level: thirdleg
|
||||
effect: '\healthcosts{+1}'
|
||||
spaces:
|
||||
1: starve
|
||||
3: damage
|
||||
5: starve
|
||||
7: damage
|
||||
9: starve
|
||||
|
||||
river:
|
||||
name: 'River'
|
||||
level: thirdleg
|
||||
effect: '\energycosts{+1}'
|
||||
spaces:
|
||||
1: hypo
|
||||
3: damage
|
||||
5: hypo
|
||||
7: damage
|
||||
9: hypo
|
||||
|
||||
swamp:
|
||||
name: 'Swamp'
|
||||
level: thirdleg
|
||||
effect: '\speed{-3}'
|
||||
spaces:
|
||||
1: damage
|
||||
3: hypo
|
||||
5: damage
|
||||
7: hypo
|
||||
9: damage
|
||||
|
||||
|
|
46
rules.ninja
46
rules.ninja
|
@ -1,3 +1,13 @@
|
|||
# TeX compilation takes a lot of resources and can hang a system, only do about
|
||||
# 4 at a time
|
||||
pool tex_pool
|
||||
depth = 4
|
||||
|
||||
# uncomment restats when ninja stops segfaulting when you do so -.- (ninja; touch legs.yaml; ninja)
|
||||
|
||||
# TODO: clean up the output directory by messing with this and configure.jq
|
||||
# hide all json/tex/etc in hidden files?
|
||||
|
||||
rule template2tex
|
||||
description = convert $in to $out using $template as a template
|
||||
command = gomplate --left-delim '«' --right-delim '»' -c .=$in < $template > $out
|
||||
|
@ -7,24 +17,38 @@ rule cuegen
|
|||
command = cue export $in > $out
|
||||
|
||||
rule extract
|
||||
description = extract $out from $in via jq filter $filter
|
||||
command = jq $filter < $in | bash update.sh $out
|
||||
description = extract $target from $in via jq filter $filter
|
||||
command = touch $out && jq -c $filter < $in | bash $base/update.sh $target
|
||||
restat = 1
|
||||
|
||||
rule tex2pdf
|
||||
description = render tex from $in to $out
|
||||
command = $
|
||||
xelatex $
|
||||
-interaction=batchmode $
|
||||
-halt-on-error $
|
||||
--shell-escape $
|
||||
--output-directory=$$(dirname $out) $in >/dev/null
|
||||
pool = tex_pool
|
||||
|
||||
rule tex2pdf2x
|
||||
description = render tex from $in to $out twice (for toc)
|
||||
command = $
|
||||
xelatex $
|
||||
-interaction=batchmode $
|
||||
-halt-on-error $
|
||||
--shell-escape $
|
||||
--output-directory=$$(dirname $out) $in >/dev/null $
|
||||
&& [ $$(basename -s .tex $in) = $$(basename -s .pdf $out) ] $
|
||||
|| mv $$(dirname $out)/$$(basename -s .tex $in).pdf $out
|
||||
|| xelatex $
|
||||
-interaction=batchmode $
|
||||
-halt-on-error $
|
||||
--shell-escape $
|
||||
--output-directory=$$(dirname $out) $in >/dev/null
|
||||
pool = tex_pool
|
||||
|
||||
rule scantex
|
||||
description = scan tex $in for dependencies
|
||||
command = bash scantex.sh $in $out > $out
|
||||
command = bash $base/scantex.sh $in $target > $out
|
||||
|
||||
rule pdf2png
|
||||
description = convert pdf $in to png $out with size $w by $h
|
||||
|
@ -37,3 +61,15 @@ rule convert
|
|||
rule copy
|
||||
description = copy $in to $out
|
||||
command = cp $in $out
|
||||
|
||||
rule pdfunite
|
||||
description = unite pdfs to create $out
|
||||
command = $
|
||||
pdfunite $in $out $
|
||||
&& pdfjam --nup 3x3 $out $
|
||||
--no-landscape --delta '0.5cm 0.5cm' --scale 0.9 $
|
||||
-o $$(dirname $out)/$$(basename -s .pdf $out)-mini.pdf >/dev/null 2>&1
|
||||
|
||||
rule pngunite
|
||||
description = unite pngs to create a mosaic
|
||||
command = magick montage -mode concatenate $in $out
|
||||
|
|
11
scantex.sh
11
scantex.sh
|
@ -2,18 +2,21 @@
|
|||
|
||||
echo 'ninja_dyndep_version = 1'
|
||||
|
||||
scriptdir="$(dirname -- "${BASH_SOURCE[0]}")"
|
||||
src="$1"
|
||||
dst="$2"
|
||||
tgt="${dst%%.*}.pdf"
|
||||
tgt="${dst%.*}.pdf"
|
||||
|
||||
cd "$scriptdir" || exit 1
|
||||
|
||||
temp="$(mktemp -p .)"
|
||||
trap 'rm -rf ${temp} ${temp}.*' EXIT INT
|
||||
|
||||
cp "$src" "$temp.tex"
|
||||
xelatex -recorder "$temp.tex" >/dev/null
|
||||
xelatex -recorder --shell-escape "$temp.tex" >/dev/null
|
||||
|
||||
deps="$(awk -v ORS=' ' -v "temp=$temp" -v "repl=${src%%.*}" '/INPUT \./ {gsub(temp,repl,$2); print $2}' < "$temp.fls")"
|
||||
outs="$(awk -v ORS=' ' -v "temp=${temp#*/}" -v "repl=${dst%%.*}" '/OUTPUT / {gsub(temp,repl,$2); print $2}' < "$temp.fls")"
|
||||
deps="$(awk -v "temp=$temp" -v "repl=${src%%.*}" '/INPUT \./ {gsub(temp,repl,$2); print $2}' < "$temp.fls" | sort | uniq | tr '\n' ' ')"
|
||||
outs="$(awk -v "temp=${temp#*/}" -v "repl=${dst%.*}" '/OUTPUT / {gsub(temp,repl,$2); print $2}' < "$temp.fls" | sort | uniq | tr '\n' ' ')"
|
||||
|
||||
echo -n "build $tgt"
|
||||
[ -z "$outs" ] || echo -n " | $outs"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Counts the number of cards in the given deck.
|
||||
yq r -j cards.yaml | jq -r --arg deckname "$1" '.decks[] | select(.name | test($deckname; "i")) | .cards | length'
|
||||
yq r -j cards.yaml | jq -r --arg deckname "$1" '.decks[$deckname] | values | map(.count) | add'
|
||||
|
|
Loading…
Reference in a new issue