Recommend
11 
 Thumb up
 Hide
9 Posts

Piecepack» Forums » General

Subject: An introduction to piecepackr rss

Your Tags: Add tags
Popular Tags: [View All]
Trevor Davis
msg tools
An introduction to piecepackr

piecepackr provides an API for making configurable board game graphics using the programming language R, a popular open-source programming language famed for its graphical (and data analysis) capabilities. By default piecepackr is configured to make piecepack game diagrams, animations, and "Print & Play" layouts but can be configured to make graphics for other board game systems as well. Furthermore when used with dynamic report generators like knitr it can be used to make customizable rulesets and rulebooks. An earlier "bleeding edge" version of piecepackr won a "Special Achievement" award in the eighth community piecepack game design contest Where No One Has Gamed Before. A stable version of piecepackr suitable for public use was published to the Comprehensive R Archive Network (CRAN) on 2019-06-28.



TABLE OF CONTENTS


* Intro to piecepackr's API
+ Drawing components with 'grid.piece' and 'pmap_piece'
+ Saving individual images of all components with 'save_piece_images'
+ Making customized Print & Play layouts with 'save_print_and_play'
+ Animations
+ Other game systems like the Hexpack and Tak
* Customizing rulesets and rulebooks
+ Writing rulsets and rulebooks with dynamic report generators
+ Customizing piecepack designs to illustrate a game
+ Customizing rulesets and rulebooks to better fit a piecepack
+ Prototype rulesets and rulebook in 'ppgames' R package



Intro to piecepackr's API

Creating arbitrary piecepack graphics with 'grid.piece' and 'pmap_piece'

grid.piece is the core function used to draw board game components. It uses R's grid graphics system and uses similar semantics as other grid functions like grid.circle, grid.text, grid.segments, grid.polygon, etc. By default piecepackr draws piecepack components with a "top-down orthogonal" view using a printer and color-blind friendly piecepack design that doesn't require most users to install extra fonts onto their system (this last requirement unfortunately eliminates the traditional piecepack suits):


library("piecepackr")
g.p <- function(...) { grid.piece(..., default.units="in") }
g.p("tile_back", x=0.5+c(3,1,3,1), y=0.5+c(3,3,1,1))
g.p("tile_back", x=0.5+3, y=0.5+1)
g.p("tile_back", x=0.5+3, y=0.5+1)
g.p("die_face", suit=3, rank=5, x=1, y=1)
g.p("pawn_face", x=1, y=4, angle=90)
g.p("coin_back", x=3, y=4, angle=180)
g.p("coin_back", suit=4, x=3, y=4, angle=180)
g.p("coin_back", suit=2, x=3, y=1, angle=90)




Example diagram with default configuration


However one can use a high-level "cascading" configuration list system to stylize the appearance of the game components drawn by grid.piece (piecepackr also allows users complete low-level control of their game components appearance by letting them write and use their own custom grob functions which could include inserting images):


dark_colorscheme <- list(suit_color="darkred,black,darkgreen,darkblue,black",
invert_colors.suited=TRUE, border_color="black", border_lex=2)
piecepack_suits <- list(suit_text="\U0001f31e,\U0001f31c,\U0001f451,\u269c,\uaa5c", # 🌞,🌜,👑,⚜,꩜
suit_fontfamily="Noto Emoji,Noto Sans Symbols2,Noto Emoji,Noto Sans Symbols,Noto Sans Cham",
suit_cex="0.6,0.7,0.75,0.9,0.9")
traditional_ranks <- list(use_suit_as_ace=TRUE, rank_text=",a,2,3,4,5")
cfg <- c(piecepack_suits, dark_colorscheme, traditional_ranks)
g.p <- function(...) { grid.piece(..., default.units="in", cfg=pp_cfg(cfg)) }
g.p("tile_back", x=0.5+c(3,1,3,1), y=0.5+c(3,3,1,1))
g.p("tile_back", x=0.5+3, y=0.5+1)
g.p("tile_back", x=0.5+3, y=0.5+1)
g.p("die_face", suit=3, rank=5, x=1, y=1)
g.p("pawn_face", x=1, y=4, angle=90)
g.p("coin_back", x=3, y=4, angle=180)
g.p("coin_back", suit=4, x=3, y=4, angle=180)
g.p("coin_back", suit=2, x=3, y=1, angle=90)




Example diagram with custom configuration


grid.piece has some support for drawing components with an oblique projection:


cfg3d <- list(width.pawn=0.75, height.pawn=0.75, depth.pawn=1,
dm_text.pawn="", shape.pawn="convex6", invert_colors.pawn=TRUE,
edge_color.coin="tan", edge_color.tile="tan")
cfg <- pp_cfg(c(cfg, cfg3d))
g.p <- function(...) {
grid.piece(..., op_scale=0.5, op_angle=45, cfg=cfg, default.units="in")
}
g.p("tile_back", x=0.5+c(3,1,3,1), y=0.5+c(3,3,1,1))
g.p("tile_back", x=0.5+3, y=0.5+1, z=1/4+1/8)
g.p("tile_back", x=0.5+3, y=0.5+1, z=2/4+1/8)
g.p("die_face", suit=3, rank=5, x=1, y=1, z=1/4+1/4)
g.p("pawn_face", x=1, y=4, z=1/4+1/2, angle=90)
g.p("coin_back", x=3, y=4, z=1/4+1/16, angle=180)
g.p("coin_back", suit=4, x=3, y=4, z=1/4+1/8+1/16, angle=180)
g.p("coin_back", suit=2, x=3, y=1, z=3/4+1/8, angle=90)




Example diagram with an oblique projection


Although one can straightforwardly draw components one at a time with grid.piece most of its arguments are "vectorized" so one can also concisely draw several components at a time:


png("san_andreas.png", width=11, height=17, units="in", res=72)
x <- 0.5+c(rep(c(1,3,5), 3), 2,4,6, 3,5,7, 4,6,8, 5,7,9, 7,9)
y <- 0.5+c(rep(c(15,13,11,9,7,5,3), each=3), 1, 1)
grid.piece("tile_back", x=x, y=y, default.units="in", cfg=cfg)
dev.off()




Saving a 'png' of the starting diagram for San Andreas with a couple lines of code


If you are familiar with R's data frames then pmap_piece provides a convenient wrapper to grid.piece


library("tibble")
df_tiles <- tibble(piece_side="tile_back", x=0.5+c(3,1,3,1), y=0.5+c(3,3,1,1))
df_coins <- tibble(piece_side="coin_back", x=rep(4:1, 4), y=rep(4:1, each=4),
suit=1:16%%2+rep(c(1,3), each=8),
angle=rep(c(180,0), each=8), z=1/4+1/16)
df <- dplyr::bind_rows(df_tiles, df_coins)
pmap_piece(df, cfg=cfg, op_scale=0.5, default.units="in")




One can use 'pmap_piece' to process R data frame input


Saving individual images of all components with 'save_piece_images'

If you would prefer to make piecepack game diagrams (or print-and-play layout) with a graphics editor but would like to use piecepackr's advanced configuration system to (perhaps initially) style your piecepack components you can use save_piece_images to save individual images of all components in various formats and rotations:


save_piece_images(cfg, directory=getwd(), format=c("svg", "png"),
angle=c(0,90,180,270))


Making customized Print & Play layouts with 'save_print_and_play'

The function save_print_and_play generates a customizable Print & Play layout. It can generate a layout supporting a standard piecepack, piecepack pyramids, piecepack matchsticks, and/or a piecepack "subpack" (aka a half-sized "travel" piecepack) in either letter, A4, or A5 paper sizes in either a "single-sided" or "double-sided" configuration. Here is an example of creating a Chinese-zodiac themed piecepack Print & Play layout (letter-sized, "single-sided", piecepack+pyramids+matchsticks).


library("piecepackr")
zodiac_cn1 <- list(rank_text = "🐀,🐉,🐒,🐂,🐍,🐓",
suit_text = "🌲,🔥,⛰️,🏆,🌊,",
rank_fontfamily = "Noto Emoji",
suit_fontfamily = "Noto Emoji,Noto Emoji,Noto Emoji,Noto Sans Symbols2,Noto Emoji",
rank_cex = 0.6, suit_cex = "0.6,0.5,0.6,0.6,0.5",
suit_color = "darkgreen,red3,chocolate4,black,darkblue,grey")
noto_credit <- c("\u25cf This piecepack uses characters from Google Noto Fonts. OFL 1.1.",
"\thttps://www.google.com/get/noto/")
zodiac_cn1$credit <- noto_credit
zodiac_cn1$description <- c('This piecepack uses ranks and suits from the Chinese Zodiac')
zodiac_cn1$title <- "Chinese Zodiac (Trines 1+2)"
zodiac_cn1 <- pp_cfg(zodiac_cn1)
save_print_and_play(zodiac_cn1, "zodiac_cn1_letter.pdf", size="letter")


piecepackr's companion website has over a dozen pre-generated demo Print & Play layouts as well as the source code to generate them.

Animations

R has several packages which support creating animations so it is straightforward to create piecepack animations.



Animation of a tic-tac-toe game


Other game systems like the Hexpack and Tak

piecepackr's configuration list system is flexible enough that it can be used to make graphics for other game systems like the Hexpack or Tak.



Example Hexpack diagram


Example Tak diagram


3 
 Thumb up
5.00
 tip
 Hide
  • [+] Dice rolls
Trevor Davis
msg tools
Customizing rulesets and rulebooks
Writing rulesets and rulebooks with dynamic report generators
Although one can certainly just write some R code to export some game diagrams and then manually insert those images into your document a flexible approach is to use a dynamic report generator aka "literate programming" and directly put the R code into your ruleset document (which will be processed to insert images, tables, text, etc.). There are several tools that support processing R code in several document formats but the most popular one by far is knitr which supports several document formats including:

1. Markdown (the most popular one)
2. reStructuredText (what the piecepackr companion website is written in)
3. LaTeX (what the prototype piecepack book in 'ppgames' is written in)

All three of those markup languages can be converted by pandoc (and other tools) to several output formats including PDF, EPUB, HTML, DokuWiki markup (as presumably used by piecepack.net), etc. (to convert to the Creole markup as used by the piecepack wiki you'll need to use an extra converter like HTML::WikiConverter::Oddmuse).

Customizing piecepack designs to illustrate a game

Since it is easy to customize piecepack designs in piecepackr it can make pedagogical sense to tweak your piecepack designs when writing a ruleset to make it easier to understand that particular game. For example some games involve dividing the suits between two players (i.e. Suns+Moons versus Crowns+Arms or Suns+Crowns versus Moons+Arms or even Suns+Arms versus Moons+Crowns) and it can make it easier to understand that game if the combined suits are more visually similar. Here is a Backgammon example where we make the Suns and Moons share a similar color scheme (and ditto for Crowns and Arms) to make it easy to understand which pieces are owned by each player:



Backgammon diagram with piecepack configured to link pairs of suits together


Or sometimes in games like Tablut or Reversi you'll want to use "suits" versus (unsuited) "ranks" so in order to make it easier to understand which pieces are owned by which sides you can make the "suited" pieces and the "unsuited" pieces have a distinct color scheme (such as "inverted" colors versus "uninverted" colors):



Tablut diagram with piecepack configured to have distinct "suited" and "unsuited" color schemes


Customizing rulesets and rulebooks to better fit a piecepack

Besides building an on-the-fly cache of graphics the pp_cfg object allows ruleset writers the ability to query information about the configured piecepack including the physical size of the pieces, the number of suits and ranks in the piecepack, what would be a good color to add annotations to diagrams in, and whether or not they should assume the user has accessories like piecepack matchsticks, piecepack pyramids, or piecepack saucers:


> cfg <- pp_cfg()
> cfg$n_suits
[1] 4
> cfg$n_ranks
[1] 6
> cfg$get_width("matchstick_face", suit=3, rank=2)
[1] 0.1875
> cfg$get_height("tile_back")
[1] 2
> cfg$get_depth("coin_back")
[1] 0.125
> cfg$annotation_color
[1] "black"
> cfg$has_matchsticks
[1] FALSE
> cfg$has_saucers
[1] FALSE
> cfg$has_pyramids
[1] FALSE


These values can be used to customize the ruleset diagrams (as well as ruleset text). For example in my configurable Tablut ruleset diagram I check the size of the dice and if they are 0.5" I'll use all four dice to build the "castle" in the middle of the board but if they are larger than 0.5" then I'll only use one die to build the "castle". Also in my Nine (and Twelve) Men's Morris rulesets I check for the presence of piecepack matchsticks and if they are present I'll add them to the diagrams (since matchsticks improve the ergonomics of those games but aren't strictly necessary).

Prototype rulesets and rulebook in 'ppgames' R package

Warning: unlike piecepackr itself the API in ppgames should be considered "unstable" for now. Furthermore, the prototype rulesets and rulebook contained in it are very much a "work in progress".

I have an experimental spin-off R package ppgames which contains the code for creating several piecepack game diagrams as well as some knitr-enhanced LaTeX files that use that code to create configurable rulesets and one work-in-progress configurable rulebook whose working title is The Historical Piecepacker. The way I have it set up if you have a piecepack configuration you like then generating rulesets and the rulebook for it is quite easy. Here is the code to generate a pdf of some crib notes on how to play Nine Men's Morris with diagrams that assume you don't have piecepack matchsticks:


library("ppgames")
cfg <- pp_cfg() # replace with your favoured configuration
gk <- game_kit(cfgs=list(cfg=cfg))
save_ruleset("nine-mens-morris", gk=gk)


To generate a pdf for "Nine Men's Morris" with diagrams that assumes you have piecepack matchsticks simply set cfg$has_matchsticks to TRUE:


cfg <- pp_cfg() # replace with your favoured configuration
cfg$has_matchsticks <- TRUE
gk <- game_kit(cfgs=list(cfg=cfg))
save_ruleset("nine-mens-morris", gk=gk)


Saving a pdf of the prototype rulebook The Historical Piecepacker is equally simple (here I'll make it using a traditional piecepack configuration downloaded from the piecepackr companion website):


download.file("https://trevorldavis.com/piecepackr/share/demo_cfgs.RData", "demo_cfgs.RData")
cfgs <- new.env()
load("demo_cfgs.RData", envir=cfgs)
gk <- game_kit(cfgs=list(cfg=cfgs$orthodox1))
save_rulebook("the-historical-piecepacker", gk=gk)


One reason why the API in ppgames should be considered "unstable" is I'm still trying to figure out the best way to conveniently represent a "game kit" of game systems. A goal for the (distant) future would be to amass a collection of piecepackr aware rulesets and write a general function where a user could state what games systems they have (say a piecepack, a (dual) piecepack expansion, a rainbow stash of looney pyramids, a double-six deck of dominoes, and a (french bourgeois Tarot) deck of playing cards) and what kind of games they would be interested in (say 2-player games, rated at least ten times on BoardGameGeek with an average rating of at least 6.0, that has a playing time of an hour or less) and it would build them a rulebook pdf (or epub/html/etc.) of just those games (making sure to suggest just one way to play for games like Tingle/Tink/Ting or Alien City which can be played lots of different ways depending on which game systems you have).

The ppgames package also has a cool function df_rect_board_tiles (as well as a wrapper grid.board_rect_tiles) which given a number of desired rows and columns and maximum number of tile backs to use can build a wide variety of rectangular boards using tile backs. If possible it will try to build a rectangular board using using the "cells" of tile backs but if that isn't possible it will build it instead using the "points" while inserting "Xiangqi-style" rivers as necessary. For example here is the code in ppgames of all the information needed to make a starting diagram for Alice chess with a single piecepack (to be drawn with pmap_piece re-using a df_fide_chess_pieces function also used in other chess variants). If you have just a normal 4-suited (6-ranked) piecepack it will make two 8x8 boards using the points of boards each made with just 9 tiles but if you have a Sixpack it will make two 8x8 boards using the cells of boards each made with 16 tiles:


df_alice_chess <- function(cfg1=pp_cfg()) {
max_tiles <- floor(cfg1$n_suits * cfg1$n_ranks / 2)
df_t1 <- df_rect_board_tiles(8, 8, max_tiles=max_tiles)
df_t2 <- df_rect_board_tiles(8, 8, max_tiles=max_tiles, x0=11)
df_p <- df_fide_chess_pieces(cfg1)
bind_rows(df_t1, df_t2, df_p)
}

3 
 Thumb up
 tip
 Hide
  • [+] Dice rolls
Jessica Eccles
New Zealand
flag msg tools
designer
badge
Alarm! Alarm!
Avatar
mbmbmbmbmb
This is great! I need to check it out more in depth with my resident R enthusiast.
1 
 Thumb up
 tip
 Hide
  • [+] Dice rolls
Derek H
South Africa
Johannesburg
Gauteng
flag msg tools
badge
Avatar
mbmbmbmbmb
Fantastic! Unfortunately I am a Python developer, not an R programmer so I don't see myself using this tool.
 
 Thumb up
 tip
 Hide
  • [+] Dice rolls
Trevor Davis
msg tools
gamesbook wrote:
Fantastic! Unfortunately I am a Python developer, not an R programmer so I don't see myself using this tool.

I love Python too and I chose to (mainly) write the Energy Market Game in it. However I regularly use half a dozen programming languages (i.e. Python, R, Bash, Javascript, Ruby, LaTeX etc.) and try to pick whichever one is easiest for me to complete the job at hand and in this case picked R instead of Python. I have thought about writing a Python wrapper to piecepackr using one of the several Python/R interfaces like rpy2 but it seems that it may be hard for any developers to debug any issues that arise unless the developer groks both Python and R in which case maybe the extra complexity of a Python wrapper is not worth it (since if they also grok R they could just use that instead). Plus in my experience you don't need to understand a language very deeply to use a tool written in it if you have a bunch of examples you can tweak (which I have tried to provide).
 
 Thumb up
 tip
 Hide
  • [+] Dice rolls
Michael Van Biesbrouck
Canada
St Catharines
Ontario
flag msg tools
designer
badge
Avatar
mbmbmbmbmb
Someone who prefers a language other than R might want to use piecepackr as a rendering backend to their language of choice. piecepackr instructions look unfriendly but should be easy to generate.

The 2D figures are functional (good when you need lots of small diagrams) and the 3D ones are quite nice. The one thing that I don't like is the weight of the grid lines on the tiles; the tiles are flush so the eye is confused about the physical components. Dashed or grey lines might work better.

I'll be thinking about uses for this. The more general rulebook-making community should be informed.
1 
 Thumb up
 tip
 Hide
  • [+] Dice rolls
Trevor Davis
msg tools
mlvanbie wrote:
The one thing that I don't like is the weight of the grid lines on the tiles; the tiles are flush so the eye is confused about the physical components. Dashed or grey lines might work better.

You can customize the lines to whatever colors and thicknesses as you wish. Here is an example where I modify the color and thickness of the border (thicker) and grid lines (thinner) as well as add a "mat":


cfg <- pp_cfg(list(border_color.tile="grey20",
border_lex.tile=3,
gridline_color.tile_back="grey50",
gridline_lex.tile_back=0.5,
mat_color.tile_back="grey80",
mat_width.tile_back=0.05))
grid.piece("tile_back", x=0.5+c(1,3,1,3),
y=0.5+c(1,1,3,3),
cfg=cfg, default.units="in")




The high-level configuration list system currently doesn't allow specifying dashed lines but it would be easy to write a custom grob function that uses dashed lines for the border lines and/or the gridlines (i.e. gpar(lty="dashed")).

Quote:
I'll be thinking about uses for this. The more general rulebook-making community should be informed.

What would be the best ways to inform them? I was thinking of (slowly) building example diagrams for other game systems then post a picture and link to the code on those game's BoardGameGeek pages.
 
 Thumb up
 tip
 Hide
  • [+] Dice rolls
Michael Van Biesbrouck
Canada
St Catharines
Ontario
flag msg tools
designer
badge
Avatar
mbmbmbmbmb
Thanks for the style example; I like that much more than your default. Both of the real grids are clear and you won't get sucked into an imaginary grid offset from the tiles.

trevorld wrote:


Quote:
I'll be thinking about uses for this. The more general rulebook-making community should be informed.

What would be the best ways to inform them? I was thinking of (slowly) building example diagrams for other game systems then post a picture and link to the code on those game's BoardGameGeek pages.

That is definitely a good approach for games such as Tak. There are a lot of abstract games created with standard components (square or hex boards, checkers, etc.). Once you have a few then you can post to the appropriate forum an perhaps get suggestions for desirable common components: https://www.boardgamegeek.com/boardgamesubdomain/4666/abstra...

The most logical forum seems to be overrun with people hoping to get work as graphic designers: https://www.boardgamegeek.com/forum/974655/boardgamegeek/boa...
1 
 Thumb up
 tip
 Hide
  • [+] Dice rolls
Derek H
South Africa
Johannesburg
Gauteng
flag msg tools
badge
Avatar
mbmbmbmbmb
trevorld wrote:
gamesbook wrote:
Fantastic! Unfortunately I am a Python developer, not an R programmer so I don't see myself using this tool.

I love Python too and I chose to (mainly) write the Energy Market Game in it. However I regularly use half a dozen programming languages (i.e. Python, R, Bash, Javascript, Ruby, LaTeX etc.) and try to pick whichever one is easiest for me to complete the job at hand
Wow,; I admire anyone who can be an advanced user of more than 2 languages! With all the complexities and new features added to Python 3, along with the dozens of ancillary libraries and frameworks that I need to use, that is more than enough for me to keep up with. shake

I dabble in bash on the side; but when I have looked at R and Ruby before I realized that many of their approaches and concepts are so different that its not worth the effort to try and keep all of them in my head at the same time (let alone master them to the point of complete and natural fluency). There's a good reason I have moved on from Java, XSLT, Pascal and (once in the dim-and-distant past) VB!
 
 Thumb up
 tip
 Hide
  • [+] Dice rolls