squib 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +5 -3
  4. data/CHANGELOG.md +24 -2
  5. data/README.md +2 -4
  6. data/RELEASE TODO.md +1 -0
  7. data/Rakefile +1 -1
  8. data/docs/arrays.rst +5 -2
  9. data/docs/build_groups.rst +15 -17
  10. data/docs/colors.rst +29 -3
  11. data/docs/conf.py +3 -3
  12. data/docs/config.rst +14 -1
  13. data/docs/data.rst +8 -4
  14. data/docs/dsl/configure.rst +18 -0
  15. data/docs/dsl/csv.rst +19 -0
  16. data/docs/dsl/data_frame.rst +85 -0
  17. data/docs/dsl/disable_build.rst +1 -4
  18. data/docs/dsl/disable_build_globally.rst +46 -0
  19. data/docs/dsl/enable_build.rst +1 -1
  20. data/docs/dsl/enable_build_globally.rst +44 -0
  21. data/docs/dsl/save_pdf.rst +44 -3
  22. data/docs/dsl/showcase.rst +11 -0
  23. data/docs/dsl/text.rst +3 -5
  24. data/docs/dsl/xlsx.rst +6 -0
  25. data/docs/guides/game_icons.rst +124 -4
  26. data/docs/guides/getting-started/part_1_zero_to_game.rst +4 -3
  27. data/docs/guides/getting-started/part_2_iconography.rst +92 -16
  28. data/docs/guides/getting-started/part_3_workflows.rst +43 -1
  29. data/docs/guides/getting-started/part_4_ruby_power.rst +18 -0
  30. data/docs/guides/git.rst +2 -1
  31. data/docs/guides/guard.rst +84 -0
  32. data/docs/guides/hello_world.rst +63 -4
  33. data/docs/guides/projects.rst +35 -0
  34. data/docs/install.rst +3 -1
  35. data/docs/layouts.rst +3 -3
  36. data/docs/learning.rst +3 -1
  37. data/docs/parameters.rst +14 -6
  38. data/docs/text_feature.rst +42 -13
  39. data/docs/units.rst +9 -1
  40. data/lib/squib/api/data.rb +6 -5
  41. data/lib/squib/api/groups.rb +14 -7
  42. data/lib/squib/api/save.rb +2 -1
  43. data/lib/squib/args/sheet.rb +57 -2
  44. data/lib/squib/card.rb +8 -0
  45. data/lib/squib/conf.rb +9 -1
  46. data/lib/squib/deck.rb +2 -1
  47. data/lib/squib/graphics/save_doc.rb +0 -45
  48. data/lib/squib/graphics/save_pdf.rb +85 -0
  49. data/lib/squib/graphics/showcase.rb +1 -1
  50. data/lib/squib/import/data_frame.rb +108 -0
  51. data/lib/squib/version.rb +1 -1
  52. data/samples/autoscale_font/.gitignore +2 -0
  53. data/samples/autoscale_font/card_00_expected.png +0 -0
  54. data/samples/backend/.gitignore +1 -0
  55. data/samples/backend/_backend-config.yml +5 -0
  56. data/samples/backend/_backend.rb +2 -9
  57. data/samples/backend/backend_00_expected.png +0 -0
  58. data/samples/backend/backend_01_expected.png +0 -0
  59. data/samples/backend/backend_vectorized_expected.pdf +0 -0
  60. data/samples/backend/backend_vectors_00_expected.svg +84 -0
  61. data/samples/backend/backend_vectors_01_expected.svg +84 -0
  62. data/samples/backend/shiny-purse.png +0 -0
  63. data/samples/backend/showcase_expected.png +0 -0
  64. data/samples/backend/spanner.svg +91 -0
  65. data/samples/build_groups/.gitignore +1 -0
  66. data/samples/build_groups/Rakefile +25 -0
  67. data/samples/colors/.gitignore +1 -0
  68. data/samples/colors/color_constants_00_expected.png +0 -0
  69. data/samples/colors/colors_00_expected.png +0 -0
  70. data/samples/colors/gradient_00_expected.png +0 -0
  71. data/samples/data/.gitignore +1 -0
  72. data/samples/data/explode_quantities.xlsx +0 -0
  73. data/samples/data/quantity_explosion.csv +3 -0
  74. data/samples/data/sample.csv +3 -0
  75. data/samples/data/sample.xlsx +0 -0
  76. data/samples/data/sample_csv_00_expected.png +0 -0
  77. data/samples/data/sample_csv_01_expected.png +0 -0
  78. data/samples/data/sample_csv_qty_00_expected.png +0 -0
  79. data/samples/data/sample_excel_00_expected.png +0 -0
  80. data/samples/data/sample_excel_01_expected.png +0 -0
  81. data/samples/data/sample_excel_02_expected.png +0 -0
  82. data/samples/data/sample_excel_resources_00_expected.png +0 -0
  83. data/samples/data/sample_excel_resources_01_expected.png +0 -0
  84. data/samples/data/sample_xlsx_qty_00_expected.png +0 -0
  85. data/samples/images/.gitignore +8 -0
  86. data/samples/images/_images_00_expected.png +0 -0
  87. data/samples/images/angler-fish.png +0 -0
  88. data/samples/images/ball.png +0 -0
  89. data/samples/images/glass-heart.svg +52 -0
  90. data/samples/images/grit.png +0 -0
  91. data/samples/images/offset.svg +85 -0
  92. data/samples/images/robot-golem.svg +1 -0
  93. data/samples/images/shiny-purse.png +0 -0
  94. data/samples/images/spanner.svg +91 -0
  95. data/samples/images/sprites.png +0 -0
  96. data/samples/images/with-alpha.png +0 -0
  97. data/samples/intro/.gitignore +2 -0
  98. data/samples/intro/auto-repair.svg +1 -0
  99. data/samples/intro/crawling.svg +1 -0
  100. data/samples/intro/data.xlsx +0 -0
  101. data/samples/intro/humans.svg +1 -0
  102. data/samples/intro/ninja-mask.svg +1 -0
  103. data/samples/intro/part1_00_expected.png +0 -0
  104. data/samples/intro/part2_00_expected.png +0 -0
  105. data/samples/intro/part3_00_expected.png +0 -0
  106. data/samples/intro/part3_layout.yml +34 -0
  107. data/samples/intro/part4_00_expected.png +0 -0
  108. data/samples/intro/part4_01_expected.png +0 -0
  109. data/samples/intro/part5_00_expected.png +0 -0
  110. data/samples/intro/part5_01_expected.png +0 -0
  111. data/samples/intro/part5_02_expected.png +0 -0
  112. data/samples/intro/part5_03_expected.png +0 -0
  113. data/samples/intro/part5_hand_expected.png +0 -0
  114. data/samples/intro/part5_showcase_expected.png +0 -0
  115. data/samples/intro/pirate-skull.svg +1 -0
  116. data/samples/intro/robot-golem.svg +1 -0
  117. data/samples/project/Gemfile +6 -0
  118. data/samples/project/Guardfile +18 -0
  119. data/samples/project/Rakefile +25 -0
  120. data/samples/project/bw/robot-golem.svg +53 -0
  121. data/samples/project/color/robot-golem.svg +1 -0
  122. data/samples/project/config.yml +2 -0
  123. data/samples/project/layouts/characters.yml +3 -0
  124. data/samples/project/layouts/skills.yml +3 -0
  125. data/samples/project/src/characters.rb +8 -0
  126. data/samples/project/src/skills.rb +7 -0
  127. data/samples/{ranges.rb → ranges/_ranges.rb} +0 -0
  128. data/samples/ranges/glass-heart.svg +52 -0
  129. data/samples/ranges/ranges_00_expected.png +0 -0
  130. data/samples/saves/.gitignore +1 -0
  131. data/samples/saves/_save_pdf.rb +18 -0
  132. data/samples/saves/hand_expected.png +0 -0
  133. data/samples/saves/hand_pretty_expected.png +0 -0
  134. data/samples/saves/save-pdf-small_expected.pdf +0 -0
  135. data/samples/saves/save-pdf_expected.pdf +0 -0
  136. data/samples/saves/save_png_00_expected.png +0 -0
  137. data/samples/saves/save_png_trimmed_00_expected.png +0 -0
  138. data/samples/saves/save_sheet_00_expected.png +0 -0
  139. data/samples/saves/save_sheet_01_expected.png +0 -0
  140. data/samples/saves/save_sheet_range_00_expected.png +0 -0
  141. data/samples/saves/save_sheet_range_01_expected.png +0 -0
  142. data/samples/saves/save_single_sheet_00_expected.png +0 -0
  143. data/samples/saves/saves_notrim_01_expected.png +0 -0
  144. data/samples/saves/showcase2_expected.png +0 -0
  145. data/samples/saves/showcase_expected.png +0 -0
  146. data/samples/saves/showcase_individual_00_expected.png +0 -0
  147. data/samples/saves/showcase_individual_01_expected.png +0 -0
  148. data/samples/saves/showcase_individual_02_expected.png +0 -0
  149. data/samples/saves/showcase_individual_03_expected.png +0 -0
  150. data/samples/saves/spanner.svg +91 -0
  151. data/samples/shapes/.gitignore +1 -0
  152. data/samples/shapes/shape_00_expected.png +0 -0
  153. data/samples/text/.gitignore +2 -0
  154. data/samples/text/README.md +1 -0
  155. data/samples/text/_text_00_expected.png +0 -0
  156. data/samples/text/config.yml +2 -0
  157. data/samples/units/_units.rb +32 -0
  158. data/samples/units/units_00_expected.png +0 -0
  159. data/samples/units/using_units.yml +10 -0
  160. data/spec/api/api_data_spec.rb +18 -18
  161. data/spec/api/api_groups_spec.rb +49 -0
  162. data/spec/args/sheet_spec.rb +24 -2
  163. data/spec/conf_spec.rb +8 -0
  164. data/spec/data/conf/basic.yml +1 -0
  165. data/spec/data/samples/autoscale_font/_autoscale_font.rb.txt +3 -0
  166. data/spec/data/samples/basic.rb.txt +3 -0
  167. data/spec/data/samples/cairo_access.rb.txt +2 -0
  168. data/spec/data/samples/colors/_gradients.rb.txt +1 -0
  169. data/spec/data/samples/config_text_markup.rb.txt +2 -0
  170. data/spec/data/samples/custom_config.rb.txt +1 -0
  171. data/spec/data/samples/data/_csv.rb.txt +6 -0
  172. data/spec/data/samples/data/_excel.rb.txt +13 -0
  173. data/spec/data/samples/embed_text.rb.txt +4 -0
  174. data/spec/data/samples/hello_world.rb.txt +2 -0
  175. data/spec/data/samples/images/_more_load_images.rb.txt +1 -0
  176. data/spec/data/samples/{ranges.rb.txt → ranges/_ranges.rb.txt} +3 -0
  177. data/spec/data/samples/saves/_hand.rb.txt +8 -0
  178. data/spec/data/samples/saves/_portrait_landscape.rb.txt +2 -0
  179. data/spec/data/samples/saves/_save_pdf.rb.txt +1505 -449
  180. data/spec/data/samples/saves/_saves.rb.txt +16 -0
  181. data/spec/data/samples/saves/_showcase.rb.txt +4 -0
  182. data/spec/data/samples/shapes/_draw_shapes.rb.txt +1 -0
  183. data/spec/data/samples/text_options.rb.txt +3 -0
  184. data/spec/data/samples/tgc_proofs.rb.txt +1 -0
  185. data/spec/data/samples/{units.rb.txt → units/_units.rb.txt} +20 -15
  186. data/spec/deck_spec.rb +7 -0
  187. data/spec/graphics/graphics_save_doc_spec.rb +2 -1
  188. data/spec/import/data_frame_spec.rb +251 -0
  189. data/spec/samples/run_samples_spec.rb +1 -1
  190. data/spec/samples/samples_regression_spec.rb +3 -2
  191. data/squib.gemspec +6 -6
  192. metadata +144 -24
  193. data/.gitmodules +0 -36
  194. data/samples/units.rb +0 -28
@@ -0,0 +1,46 @@
1
+ disable_build_globally
2
+ ======================
3
+
4
+ Disable the given build group for all future ``Squib::Deck`` runs.
5
+
6
+ Essentially a convenience method for setting the ``SQUIB_BUILD`` environment variable. See :doc:`/build_groups` for ways to use this effectively.
7
+
8
+ This is a member of the ``Squib`` module, so you must run it like this::
9
+
10
+ Squib.disable_build_globally :pdf
11
+
12
+ The intended purpose of this method is to be able to alter the environment from other build scripts, such as a Rakefile.
13
+
14
+ Required Arguments
15
+ ------------------
16
+
17
+ build_group_name
18
+
19
+ the name of the build group to disable. Convention is to use a Ruby symbol.
20
+
21
+
22
+ Examples
23
+ --------
24
+
25
+ Can be used to disable a group, overriding setting the environment variable at the command line::
26
+
27
+ Squib.enable_build_globally :pdf
28
+ Squib.disable_build_globally :pdf
29
+
30
+ Squib::Deck.new do
31
+ build :pdf do
32
+ save_pdf #does not get run regardless of incoming environment
33
+ end
34
+ end
35
+
36
+ But gets overridden by an individual ``Squib::Deck`` programmatically enabling a build via :doc:`/dsl/enable_build`::
37
+
38
+ Squib.enable_build_globally :pdf
39
+ Squib.disable_build_globally :pdf
40
+
41
+ Squib::Deck.new do
42
+ enable_build :pdf
43
+ build :pdf do
44
+ save_pdf # this will be run no matter what
45
+ end
46
+ end
@@ -1,7 +1,7 @@
1
1
  enable_build
2
2
  ============
3
3
 
4
- Enable the given build group for the rest of the build. Thus, code within the corresponding :doc:`/dsl/group` block will be executed. See :doc:`/build_groups` for ways to use this effectively.
4
+ Enable the given build group for the rest of the build. Thus, code within the corresponding :doc:`/dsl/build` block will be executed. See :doc:`/build_groups` for ways to use this effectively.
5
5
 
6
6
 
7
7
  Required Arguments
@@ -0,0 +1,44 @@
1
+ disable_build_globally
2
+ ======================
3
+
4
+ Enagle the given build group for all future ``Squib::Deck`` runs.
5
+
6
+ Essentially a convenience method for setting the ``SQUIB_BUILD`` environment variable. See :doc:`/build_groups` for ways to use this effectively.
7
+
8
+ This is a member of the ``Squib`` module, so you must run it like this::
9
+
10
+ Squib.enable_build_globally :pdf
11
+
12
+ The intended purpose of this method is to be able to alter the environment from other build scripts, such as a Rakefile.
13
+
14
+ Required Arguments
15
+ ------------------
16
+
17
+ build_group_name
18
+
19
+ the name of the build group to enable. Convention is to use a Ruby symbol.
20
+
21
+
22
+ Examples
23
+ --------
24
+
25
+ Can be used to enable a group, overriding setting the environment variable at the command line::
26
+
27
+ Squib.enable_build_globally :pdf
28
+
29
+ Squib::Deck.new do
30
+ build :pdf do
31
+ save_pdf # this runs regardless of incoming environment
32
+ end
33
+ end
34
+
35
+ But gets overridden by an individual ``Squib::Deck`` programmatically enabling a build via :doc:`/dsl/enable_build`::
36
+
37
+ Squib.enable_build_globally :pdf
38
+
39
+ Squib::Deck.new do
40
+ disable_build :pdf
41
+ build :pdf do
42
+ save_pdf # this will NOT be run no matter what
43
+ end
44
+ end
@@ -1,13 +1,11 @@
1
1
  save_pdf
2
2
  ========
3
3
 
4
- Lays out the cards in range on a sheet and renders a PDF
4
+ Lays out the cards in a gride and renders a PDF.
5
5
 
6
6
  Options
7
7
  -------
8
8
 
9
-
10
-
11
9
  file
12
10
  default: ``'output.pdf'``
13
11
 
@@ -43,6 +41,49 @@ trim
43
41
 
44
42
  the space around the edge of each card to trim (e.g. to cut off the bleed margin for print-and-play). Supports :doc:`/units`.
45
43
 
44
+ crop_marks
45
+ default: ``false``
46
+
47
+ When ``true``, draws lines in the margins as guides for cutting. Crop marks factor in the ``trim`` (if non-zero), and can also be customized via ``crop_margin_*`` options (see below). Has no effect if ``margin`` is 0.
48
+
49
+ .. warning::
50
+
51
+ Enabling this feature will draw lines to the edge of the page. Most PDF Readers, by default, will recognize this and scale down the entire PDF to fit in those crop marks - throwing off your overall scale. To disable this, you will need to set Print Scaling "Use original" or "None" when you go to print (this looks different for different PDF readers). Be sure to test this out before you do your big print job!!
52
+
53
+ crop_margin_bottom
54
+ default: 0
55
+
56
+ The space between the bottom edge of the (potentially trimmed) card, and the crop mark. Supports :doc:`/units`. Has no effect if ``crop_marks`` is ``false``.
57
+
58
+ crop_margin_left
59
+ default: 0
60
+
61
+ The space between the left edge of the (potentially trimmed) card, and the crop mark. Supports :doc:`/units`. Has no effect if ``crop_marks`` is ``false``.
62
+
63
+ crop_margin_right
64
+ default: ``0``
65
+
66
+ The space between the right edge of the (potentially trimmed) card, and the crop mark. Supports :doc:`/units`. Has no effect if ``crop_marks`` is ``false``.
67
+
68
+ crop_margin_top
69
+ default: ``0``
70
+
71
+ The space between the top edge of the (potentially trimmed) card, and the crop mark. Supports :doc:`/units`. Has no effect if ``crop_marks`` is ``false``.
72
+
73
+ crop_stroke_color
74
+ default: ``:black``
75
+
76
+ The color of the crop mark lines. Has no effect if ``crop_marks`` is ``false``.
77
+
78
+ crop_stroke_dash
79
+ default: ``''``
80
+
81
+ Define a dash pattern for the crop marks. This is a special string with space-separated numbers that define the pattern of on-and-off alternating strokes, measured in pixels or units. For example, ``'0.02in 0.02in'`` will be an equal on-and-off dash pattern. Supports :doc:`/units`. Has no effect if ``crop_marks`` is ``false``.
82
+
83
+ crop_stroke_width
84
+ default: ``1.5``
85
+
86
+ Width of the crop mark lines. Has no effect if ``crop_marks`` is ``false``.
46
87
 
47
88
  Examples
48
89
  --------
@@ -63,3 +63,14 @@ file
63
63
 
64
64
  Examples
65
65
  --------
66
+
67
+ This sample `lives here <https://github.com/andymeneely/squib/tree/master/samples/saves>`_.
68
+
69
+ .. literalinclude:: ../../samples/saves/_showcase.rb
70
+ :language: ruby
71
+ :linenos:
72
+
73
+ .. raw:: html
74
+
75
+ <img src="../saves/showcase_expected.png" class="figure">
76
+ <img src="../saves/showcase2_expected.png" class="figure">
@@ -18,7 +18,7 @@ str
18
18
  font
19
19
  default: ``'Arial 36'``
20
20
 
21
- the Font description string, including family, styles, and size. (e.g. ``'Arial bold italic 12'``). For the official documentation, see the `Pango docs <http://ruby-gnome2.sourceforge.jp/hiki.cgi?Pango%3A%3AFontDescription#style>)`_. This `description <http://www.pygtk.org/pygtk2reference/class-pangofontdescription.html>`_ is also quite good.
21
+ the Font description string, including family, styles, and size. (e.g. ``'Arial bold italic 12'``). For the official documentation, see the `Pango font string docs <http://ruby-gnome2.sourceforge.jp/hiki.cgi?Pango%3A%3AFontDescription#style>`_. This `description <http://www.pygtk.org/pygtk2reference/class-pangofontdescription.html>`_ is also quite good.
22
22
 
23
23
  font_size
24
24
  default: ``nil``
@@ -116,7 +116,7 @@ Markup
116
116
 
117
117
  If you want to do specialized formatting within a given string, Squib has lots of options. By setting ``markup: true``, you enable tons of text processing. This includes:
118
118
 
119
- * Pango Markup. This is an HTML-like formatting language that specifies formatting inside your string. Pango Markup essentially supports any formatting option, but on a letter-by-letter basis. Such as: font options, letter spacing, gravity, color, etc. See the `Pango docs <https://developer.gnome.org/pango/stable/PangoMarkupFormat.html>`_ for details.
119
+ * Pango Markup. This is an HTML-like formatting language that specifies formatting inside your string. Pango Markup essentially supports any formatting option, but on a letter-by-letter basis. Such as: font options, letter spacing, gravity, color, etc. See the `Pango markup docs <https://developer.gnome.org/pango/stable/PangoMarkupFormat.html>`_ for details.
120
120
  * Quotes are converted to their curly counterparts where appropriate.
121
121
  * Apostraphes are converted to curly as well.
122
122
  * LaTeX-style quotes are explicitly converted (````like this''``)
@@ -289,6 +289,4 @@ angle
289
289
  Examples
290
290
  --------
291
291
 
292
- .. raw:: html
293
-
294
- <script src="https://gist.github.com/andymeneely/52d7b8e332194946bc69.js"></script>
292
+ See :doc:`/text_feature`.
@@ -48,3 +48,9 @@ The ``xlsx`` method also takes in a block that will be executed for each cell in
48
48
 
49
49
  Examples
50
50
  --------
51
+
52
+ To get the sample Excel files, go to `its source <https://github.com/andymeneely/squib/tree/dev/samples/data>`_
53
+
54
+ .. literalinclude:: ../../samples/data/_excel.rb
55
+ :language: ruby
56
+ :linenos:
@@ -1,6 +1,126 @@
1
- Using GameIcons.net
2
- ===================
1
+ Squib + Game-Icons.net
2
+ ======================
3
3
 
4
- .. note::
4
+ I believe that, in prototyping, you want to focus on getting your idea to the table as fast as possible. Artwork is the kind of thing that can wait for later iterations once you know your game is a good one.
5
5
 
6
- To be written
6
+ But! Playtesting with just text is a real drag.
7
+
8
+ Fortunately, there's this amazing project going on over at http://game-icons.net. They are in the process of building a massive library of gaming-related icons.
9
+
10
+ As a sister project to Squib, I've made a Ruby gem that interfaces with the Game Icons library. With this gem, you can access Game Icons files, and even manipulate them as they go into your game.
11
+
12
+ Here are some instructions for working with the Game Icons gem into Squib.
13
+
14
+ Install the Gem
15
+ ---------------
16
+
17
+ To get the gem, do:
18
+
19
+ $ gem install game_icons
20
+
21
+ The library update frequently, so it's a good idea to upgrade whenever you can.
22
+
23
+ $ gem up game_icons
24
+
25
+ If you are using Bundler, go ahead and put this in your Gemfile::
26
+
27
+ gem 'game_icons'
28
+
29
+ And then run ``bundle install`` to install it from there.
30
+
31
+ The ``game_icons`` gem has no required dependencies. However, if you want to manipulate the SVG
32
+
33
+ To begin using the gem, just require it::
34
+
35
+ require 'game_icons'
36
+
37
+ Find Your Icon
38
+ --------------
39
+
40
+ Game-Icons.net has a search engine with some great tagging. Find the icon that you need. The gem will need the "name" of your icon. You can get this easily from the URL. For example:
41
+
42
+ http://game-icons.net/lorc/originals/meat.html
43
+
44
+ could be called::
45
+
46
+ 'meat'
47
+ :meat
48
+
49
+ Symbols are okay too (really, anything that responds to ``to_s`` will suffice). Spaces are replaced with a dash::
50
+
51
+ 'police-badge'
52
+ :police_badge
53
+
54
+ However, some icons have the same name but different authors. To differentiate these, you put the author name before a slash. Like this::
55
+
56
+ 'lorc/meat'
57
+ 'andymeneely/police-badge'
58
+
59
+ To get the Icon, you use ``GameIcons#get``::
60
+
61
+ GameIcons.get(:meat)
62
+ GameIcons.get('lorc/meat')
63
+ GameIcons.get(:police_badge)
64
+ GameIcons.get('police-badge')
65
+ GameIcons.get('andymeneely/police-badge')
66
+
67
+ If you want to know all the icon names, you can always use::
68
+
69
+ GameIcons.names # returns the list of icon names
70
+
71
+ If you end up misspelling one, the gem will suggest one:
72
+
73
+ .. code-block:: shell
74
+
75
+ irb(main):005:0> GameIcons.get(:police_badg)
76
+ RuntimeError: game_icons: could not find icon 'police_badg'. Did you mean any of these? police-badge
77
+
78
+ Use the SVG File
79
+ ----------------
80
+
81
+ If you just want to use the icon in your game, you can just use the ``file`` method::
82
+
83
+ svg file: GameIcons.get(:police-badge).file
84
+
85
+ Recolor the SVG file
86
+ --------------------
87
+
88
+ The gem will also allow you to recolor the icon as you wish, setting foreground and background::
89
+
90
+ # recolor foreground and background to different shades of gray
91
+ svg data: GameIcons.get('glass-heart').
92
+ recolor(fg: '333', bg: 'ccc').
93
+ string
94
+
95
+ # recolor with opacity
96
+ svg data: GameIcons.get('glass-heart').
97
+ recolor(fg: '333', bg: 'ccc',
98
+ fg_opacity: 0.25, bg_opacity: 0.75).
99
+ string
100
+
101
+ Use the SVG XML Data
102
+ --------------------
103
+
104
+ SVGs are just XML files, and can be manipulated in their own clever ways. GameIcons is super-consistent in the way they format their SVGs - the entire icon is flattened into one path. So you can manipulate how the icon looks in your own way. Here's an example of using straight string substitution::
105
+
106
+ svg data: GameIcons.get(:meat).string.gsub('fill="#fff"', 'fill="#abc"')
107
+
108
+ Here's a fun one. It replaces all non-white colors in your SVG with black through the SVG::
109
+
110
+ svg data: GameIcons.get(:meat).string.gsub(':#ffffff', 'snarfblat').
111
+ gsub(/:#[0-9a-f]{6}/, ':#000000').
112
+ gsub('snarfblat', ':#ffffff')
113
+
114
+ XML can also be manipulated via CSS or XPATH queries via the ``nokogiri`` library, which Squib has as a dependency anyway. Like this::
115
+
116
+ doc = Nokogiri::XML(GameIcons.get(:meat).string)
117
+ doc.css('path')[1]['fill'] = #f00 # set foreground color to red
118
+ svg data: doc.to_xml
119
+
120
+
121
+ Path Weirdness
122
+ --------------
123
+
124
+ Inkscape and Squib's libRSVG renderer can lead to unexpected results for some icons. This has to do with a discrepancy in how path data is interpreted according to the specification. (Specifically, negative numbers need to have a space before them in the path data.) The fix for this is quick and easy, and the gem can do this for you::
125
+
126
+ GameIcons.get(:sheep).correct_pathdata.string # corrects path data
@@ -1,9 +1,11 @@
1
1
  The Squib Way pt 1: Zero to Game
2
2
  =================================
3
3
 
4
- .. warning::
4
+ I've always felt that the Ruby community and the tabletop game design community had a lot in common, and a lot to learn from each other. Both are all about testing. All about iterative development. Both communities are collegial, creative, and fun.
5
5
 
6
- Conversion from markdown not finished yet
6
+ But the Ruby community, and the software development community generally, has a lot to teach us game designers about how to develop something. `Ruby has a "way" of doing things <http://therubyway.io/>`_ that is unique and helpful to game designers.
7
+
8
+ In this series of guides, I'll introduce you to Squib's key features and I'll walk you through a basic prototype. We'll also take a more circuitous route than normal so that I can touch upon some key design principles and good software development habits so that you can make your Squib scripts maintainable, understandable, flexible, and changeable.
7
9
 
8
10
  Prototyping with Squib
9
11
  ----------------------
@@ -14,7 +16,6 @@ The key to prototyping tabletop games is *playtesting*. At the table. With human
14
16
 
15
17
  But! We also want to get the *second* (and third and fourth and fifth...) version of our game back to the playtesting table quickly, too. If we work with Squib from day one, our ability to react to feedback will be much smoother once we've laid the groundwork.
16
18
 
17
- In this series of guides, we'll introduce you to Squib's key features by also walking you through a basic prototype. We'll take a more circuitous route than normal so we can pick apart what Squib is actually doing so that we can leverage its features.
18
19
 
19
20
  Get Installed and Set Up
20
21
  -----------------------------
@@ -1,10 +1,6 @@
1
1
  The Squib Way pt 2: Iconography
2
2
  ===================================
3
3
 
4
- .. warning::
5
-
6
- This chapter is still being written
7
-
8
4
  In the previous guide, we walked you through the basics of going from ideas in your head to a very simple set of cards ready for playtesting at the table. In this guide we take the next step: creating a visual language.
9
5
 
10
6
  Art: Graphic Design vs. Illustration
@@ -30,7 +26,7 @@ The majority of the cards in RFTG have no description text on them, and yet the
30
26
 
31
27
  But once you know the structure of the game and what various bonuses mean, you can understand new cards very easily. Icons are combined in creative ways to show new bonuses. Text is used only when a bonus is much more complicated than what can be expressed with icons. Icons are primarily arranged along left side of the card so you can hold them in your hand and compare bonuses across cards quickly. All of these design decisions match the gameplay nicely because the game consists of a lot of scrolling through cards in your hand and evaluating which ones you want to play.
32
28
 
33
- Go check out images of Race for the Galaxy `on BoardGameGeek.com <https://boardgamegeek.com/boardgame/28143/race-galaxy>`_.
29
+ Go check out `images of Race for the Galaxy on BoardGameGeek.com <https://boardgamegeek.com/boardgame/28143/race-galaxy>`_.
34
30
 
35
31
  Dominion
36
32
  ^^^^^^^^
@@ -50,16 +46,17 @@ Squib is good for supporting any kind of layout you can think of, but it's also
50
46
  * :doc:`/dsl/png` method, and all of its features like blending operators, alpha transparency, and masking
51
47
  * Layout files allow multiple icons for one data column (see :doc:`/layouts`)
52
48
  * Layout files also have the ``extends`` feature that allows icons to inherit details from each other
53
- * The ``range`` option on :doc:`/dsl/text`, :doc:`/dsl/svg`, and :doc:`/dsl/png` allows you to specify text and icons for any subset of your files
49
+ * The ``range`` option on :doc:`/dsl/text`, :doc:`/dsl/svg`, and :doc:`/dsl/png` allows you to specify text and icons for any subset of your cards
54
50
  * The :doc:`/dsl/text` method allows for embedded icons.
55
- * Ruby provides neat ways of aggregating data with ``inject``, ``map``, and ``zip`` that supports iconography
51
+ * The :doc:`/dsl/text` method allows for Unicode characters (if the font supports it).
52
+ * Ruby provides neat ways of aggregating data with ``inject``, ``map``, and ``zip`` that gives you ultimate flexibility for specifying different icons for different cards.
56
53
 
57
54
  Back to the Example: Drones vs. Humans
58
55
  --------------------------------------
59
56
 
60
57
  Ok, let's go back to our running example, project ``arctic-lemming`` from Part 1. We created cards for playtesting, but we never put down the faction for each card. That's a good candidate for an icon.
61
58
 
62
- Let's get some stock icons for this exercise. For this example, I went to http://game-icons.net. I set my foreground color to black, and background to white. I then downloaded "auto-repair.svg" and "backup.svg". I'm choosing not to rename the files so that I can find them again on the website if I need to. (If you want to know how to do this process DIRECTLY from Ruby, and not going to the website, check out my *other* Ruby gem called `game_icons <https://github.com/andymeneely/game_icons>`_ - it's tailor-made for Squib!)
59
+ Let's get some stock icons for this exercise. For this example, I went to http://game-icons.net. I set my foreground color to black, and background to white. I then downloaded "auto-repair.svg" and "backup.svg". I'm choosing not to rename the files so that I can find them again on the website if I need to. (If you want to know how to do this process DIRECTLY from Ruby, and not going to the website, check out my *other* Ruby gem called `game_icons <https://github.com/andymeneely/game_icons>`_ - it's tailor-made for Squib! We've got some documentation in :doc:`/guides/game_icons`
63
60
 
64
61
  When we were brainstorming our game, we placed one category of icons in a single column ("faction"). Presumably, one would want the faction icon to be in the same place on every card, but a different icon depending on the card's faction. There are a couple of ways of accomplishing this in Squib. First, here some less-than-clean ways of doing it::
65
62
 
@@ -115,7 +112,7 @@ At this point, we've got a very scalable design for our future iterations. Let's
115
112
  Why Ruby+YAML+Spreadsheets Works
116
113
  --------------------------------
117
114
 
118
- In software design, a "good" design is one where the problem is broken down into a set of easier duties that each make sense on their own, where the interaction between duties is easy, and where to place new responsbilities is obvious.
115
+ In software design, a "good" design is one where the problem is broken down into a set of easier duties that each make sense on their own, where the interaction between duties is easy, and where to place new responsibilities is obvious.
119
116
 
120
117
  In Squib, we're using automation to assist the prototyping process. This means that we're going to have a bunch of decisions and responsibilities, such as:
121
118
 
@@ -137,16 +134,95 @@ The best way to preserve this design is to try to keep the Ruby code clean. As w
137
134
 
138
135
  Ok, let's get back to this prototype.
139
136
 
140
- Icons for Some, But Not All, Cards
141
- ----------------------------------
137
+ Illustration: One per Card
138
+ --------------------------
139
+
140
+ The cards are starting to come together, but we have another thing to do now. When playtesting, you need a way of visually identifying the card immediately. Reading text takes an extra moment to identify the card - wouldn't it be nice if we had some sort of artwork, individualized to the card?
141
+
142
+ Of course, we're not going to commission an artist or do our own oil paintings just yet. Let's get some placeholder art in there. Back to GameIcons, we're going to use "ninja-mask.svg", "pirate-skull.svg", "shambling-zombie.svg", and "robot-golem.svg".
143
+
144
+ Method 1: Put the file name in data
145
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
146
+
147
+ The difference between our Faction icon and our Illustration icon is that the Illustration needs to be different for every card. We already have a convenient way to do something different on every card - our CSV file!
148
+
149
+ Here's how the CSV would look:
150
+
151
+ .. raw:: html
152
+
153
+ <code data-gist-id="d2bb2eb028b27cf1dace"
154
+ data-gist-file="data_pt2_03.csv"></code>
155
+
156
+ In our layout file we can center it in the middle of the card, nice and big. And then the Ruby & YAML would look like this:
157
+
158
+ .. raw:: html
159
+
160
+ <code data-gist-id="d2bb2eb028b27cf1dace"
161
+ data-gist-file="_part2_03_illustrations.yml"
162
+ data-gist-highlight-line="12-16"></code>
163
+ <code data-gist-id="d2bb2eb028b27cf1dace"
164
+ data-gist-file="_part2_03_illustrations_m1.rb"
165
+ data-gist-highlight-line="14"></code>
166
+
167
+ And our output will look like this:
168
+
169
+ .. raw:: html
170
+
171
+ <code data-gist-id="d2bb2eb028b27cf1dace"
172
+ data-gist-file="_part2_03_illustrations_00.png"></code>
142
173
 
143
- .. note::
144
174
 
145
- to be written
175
+ Method 2: Map title to file name
176
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
146
177
 
147
- One Column per Icon
148
- -------------------
178
+ There are some drawbacks to Method 1. First, you're putting artwork graphics info inside your game data. This can be weird and unexpected for someone new to your code (i.e. that person being you when you put your project down for a few months). Second, when you're working on artwork you'll have to look up what the name of every file is in your CSV. (Even writing this tutorial, I forgot that "zombie" is called "shambling-zombie.svg" and had to look it up, distracting me from focusing on writing.)
179
+
180
+ There's another way of doing this, and it's more Ruby-like because it follows the `Convention over Configuration <https://en.wikipedia.org/wiki/Convention_over_configuration>`_ philosophy. The idea is to be super consistent with your naming so that you don't have to *configure* that, say, "pirate" has an illustration "pirate-skull". The illustration should be literally the title of the card - converted to lowercase because that's the convention for files. That means it should just be called "pirate.svg", and Squib should know to "just put an SVG that is named after the title". Months later, when you want to edit the illustration for pirate, you will probably just open "pirate.svg".
181
+
182
+ To do this, you'll need to convert an array of Title strings from your CSV (``data['title']`` to an array of file names. Ruby's ``map`` was born for this.
149
183
 
150
184
  .. note::
151
185
 
152
- to be written
186
+ If you're new to Ruby, here's a quick primer. The ``map`` method gets run on every element of an array, and it lets you specify a *block* (either between curly braces for one line or between ``do`` and ``end`` for multiple lines). It then returns another Array of the same size, but with every value mapped using your block. So::
187
+
188
+ [1, 2, 3].map { |x| 2 * x } # returns [2, 4, 6]
189
+ [1, 2, 3].map { |x| "$#{x}" } # returns ["$1", "$2", "$3"]
190
+ ['NARF', 'ZORT'].map { |x| x.downcase } # returns ['narf', 'zort']
191
+
192
+
193
+
194
+ Thus, if we rename our illustration files from "pirate-skull.svg" to "pirate.svg", we can have CSV data that's JUST game data:
195
+
196
+ .. raw:: html
197
+
198
+ <code data-gist-id="d2bb2eb028b27cf1dace"
199
+ data-gist-file="data.csv"
200
+ data-gist-highlight-line="14"></code>
201
+
202
+ And our Ruby code will figure out the file name:
203
+
204
+ .. raw:: html
205
+
206
+ <code data-gist-id="d2bb2eb028b27cf1dace"
207
+ data-gist-file="_part2_03_illustrations_m2.rb"
208
+ data-gist-highlight-line="3,14-15"></code>
209
+
210
+ And our output images look identical to Method 1.
211
+
212
+ Learn by Example
213
+ ----------------
214
+
215
+ In my game, Your Last Heist, I use some similar methods as above:
216
+
217
+ * `Use a different background depending <https://github.com/andymeneely/project-timber-wolf/blob/156a5d417dd8021e3f391a67c08b8e9f06f58c2b/src/characters.rb#L14-L16>`_ on if the character is level 1 or 2. Makes use of `Ruby's ternary operator <https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Control_Structures#short-if_expression_.28aka_ternary_operator.29>`_.
218
+ * `Only put an image if the data is non-nil <https://github.com/andymeneely/project-timber-wolf/blob/156a5d417dd8021e3f391a67c08b8e9f06f58c2b/src/characters.rb#L19-L21>`_. Some characters have a third skill, others do not. Only load a third skill image if they have a third skill. This line leverages the fact that when you do ``svg file: nil``, the ``svg`` simply does nothing.
219
+ * `Method 2 from above, but into its own directory <https://github.com/andymeneely/project-timber-wolf/blob/156a5d417dd8021e3f391a67c08b8e9f06f58c2b/src/characters.rb#L23>`_.
220
+ * `Use different-sized backdrops depending on the number of letters in the text <https://github.com/andymeneely/project-timber-wolf/blob/156a5d417dd8021e3f391a67c08b8e9f06f58c2b/src/characters.rb#L24-L31>`_. This one is cool because I can rewrite the description of a card, and it will automatically figure out which backdrop to use based on how many letters the text has. This makes use of `Ruby's case-when expression <https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Control_Structures#case_expression>`_.
221
+ * After saving the regular cards, we end our script by `creating some annotated figures <https://github.com/andymeneely/project-timber-wolf/blob/156a5d417dd8021e3f391a67c08b8e9f06f58c2b/src/characters.rb#L68-L76>`_ for the rulebook by drawing some text on top of it and saving it using ``showcase``.
222
+
223
+ Are We Done?
224
+ ------------
225
+
226
+ At this stage, you've got most of what you need to build a game from prototype through completion. Between images and text, you can do pretty much anything. Squib does much more, of course, but these are the basic building blocks.
227
+
228
+ But, prototyping is all about speed and agility. The faster you can get what you need, the sooner you can playtest, and the sooner you can make it better. Up next, we'll be looking at workflow: ways to help you get what you need quickly and reliably.