rgame 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +26 -0
  3. data/README.md +406 -0
  4. data/docs/api/README.md +167 -0
  5. data/docs/api/app.md +192 -0
  6. data/docs/api/assets.md +426 -0
  7. data/docs/api/audio.md +208 -0
  8. data/docs/api/components.md +321 -0
  9. data/docs/api/drawing.md +330 -0
  10. data/docs/api/game.md +99 -0
  11. data/docs/api/images.md +118 -0
  12. data/docs/api/input.md +179 -0
  13. data/docs/api/internals.md +110 -0
  14. data/docs/api/scene_graph.md +159 -0
  15. data/docs/api/signals.md +142 -0
  16. data/docs/api/systems.md +98 -0
  17. data/docs/api/text.md +116 -0
  18. data/docs/api/toolbox.md +240 -0
  19. data/docs/api/values.md +101 -0
  20. data/ext/README.md +225 -0
  21. data/ext/rgame_core/app/app.c +721 -0
  22. data/ext/rgame_core/app/app_gl.h +64 -0
  23. data/ext/rgame_core/app/frame_loop.c +42 -0
  24. data/ext/rgame_core/app/frame_loop.h +54 -0
  25. data/ext/rgame_core/audio/audio.c +466 -0
  26. data/ext/rgame_core/audio/audio_internal.h +45 -0
  27. data/ext/rgame_core/audio/vorbis_decoder.c +282 -0
  28. data/ext/rgame_core/audio/vorbis_decoder.h +45 -0
  29. data/ext/rgame_core/example.rb +188 -0
  30. data/ext/rgame_core/extconf.rb +167 -0
  31. data/ext/rgame_core/graphics/backend.c +52 -0
  32. data/ext/rgame_core/graphics/backend.h +64 -0
  33. data/ext/rgame_core/graphics/canvas.c +247 -0
  34. data/ext/rgame_core/graphics/canvas.h +143 -0
  35. data/ext/rgame_core/graphics/clip.c +87 -0
  36. data/ext/rgame_core/graphics/clip.h +89 -0
  37. data/ext/rgame_core/graphics/draw_queue.c +216 -0
  38. data/ext/rgame_core/graphics/draw_queue.h +174 -0
  39. data/ext/rgame_core/graphics/gl_backend.c +122 -0
  40. data/ext/rgame_core/graphics/gl_backend.h +43 -0
  41. data/ext/rgame_core/graphics/image.c +304 -0
  42. data/ext/rgame_core/graphics/image_internal.h +30 -0
  43. data/ext/rgame_core/graphics/primitives.c +189 -0
  44. data/ext/rgame_core/graphics/primitives.h +111 -0
  45. data/ext/rgame_core/graphics/recording.c +119 -0
  46. data/ext/rgame_core/graphics/recording.h +88 -0
  47. data/ext/rgame_core/graphics/texture.c +181 -0
  48. data/ext/rgame_core/graphics/texture.h +165 -0
  49. data/ext/rgame_core/graphics/transform.c +128 -0
  50. data/ext/rgame_core/graphics/transform.h +106 -0
  51. data/ext/rgame_core/include/rgame/core.h +577 -0
  52. data/ext/rgame_core/input/device_slots.c +103 -0
  53. data/ext/rgame_core/input/device_slots.h +93 -0
  54. data/ext/rgame_core/input/gamepad.c +145 -0
  55. data/ext/rgame_core/input/gamepad.h +63 -0
  56. data/ext/rgame_core/input/input.c +109 -0
  57. data/ext/rgame_core/input/input.h +99 -0
  58. data/ext/rgame_core/ruby/audio_ext.c +321 -0
  59. data/ext/rgame_core/ruby/core_ext.c +513 -0
  60. data/ext/rgame_core/ruby/core_ext.h +51 -0
  61. data/ext/rgame_core/ruby/font_ext.c +168 -0
  62. data/ext/rgame_core/ruby/image_ext.c +230 -0
  63. data/ext/rgame_core/ruby/recording_ext.c +186 -0
  64. data/ext/rgame_core/ruby/renderer_ext.c +376 -0
  65. data/ext/rgame_core/text/atlas.c +59 -0
  66. data/ext/rgame_core/text/atlas.h +85 -0
  67. data/ext/rgame_core/text/font.c +281 -0
  68. data/ext/rgame_core/text/font.h +139 -0
  69. data/ext/rgame_core/text/font_atlas.c +385 -0
  70. data/ext/rgame_core/text/font_internal.h +47 -0
  71. data/ext/rgame_core/text/glyph_cache.c +142 -0
  72. data/ext/rgame_core/text/glyph_cache.h +89 -0
  73. data/ext/rgame_core/vendor/README.md +159 -0
  74. data/ext/rgame_core/vendor/miniaudio.h +95864 -0
  75. data/ext/rgame_core/vendor/miniaudio_impl.c +62 -0
  76. data/ext/rgame_core/vendor/stb_image.h +7988 -0
  77. data/ext/rgame_core/vendor/stb_image_impl.c +31 -0
  78. data/ext/rgame_core/vendor/stb_truetype.h +5079 -0
  79. data/ext/rgame_core/vendor/stb_truetype_impl.c +23 -0
  80. data/ext/rgame_core/vendor/stb_vorbis.c +5584 -0
  81. data/ext/rgame_core/vendor/stb_vorbis_impl.c +29 -0
  82. data/ext/rgame_util/color.c +19 -0
  83. data/ext/rgame_util/color.h +60 -0
  84. data/ext/rgame_util/color_ext.c +156 -0
  85. data/ext/rgame_util/extconf.rb +27 -0
  86. data/ext/rgame_util/tensor.c +186 -0
  87. data/ext/rgame_util/util_ext.c +27 -0
  88. data/ext/rgame_util/util_ext.h +16 -0
  89. data/lib/rgame/boot.rb +13 -0
  90. data/lib/rgame/core/app.rb +82 -0
  91. data/lib/rgame/core/asset_manager.rb +224 -0
  92. data/lib/rgame/core/audio.rb +124 -0
  93. data/lib/rgame/core/font.rb +49 -0
  94. data/lib/rgame/core/gamepad.rb +55 -0
  95. data/lib/rgame/core/image.rb +55 -0
  96. data/lib/rgame/core/input.rb +77 -0
  97. data/lib/rgame/core/nine_slice.rb +163 -0
  98. data/lib/rgame/core/recording.rb +52 -0
  99. data/lib/rgame/core/renderer.rb +363 -0
  100. data/lib/rgame/core/sprite_sheet.rb +108 -0
  101. data/lib/rgame/core/tile_map_renderer.rb +160 -0
  102. data/lib/rgame/core/ui_atlas.rb +86 -0
  103. data/lib/rgame/core.rb +24 -0
  104. data/lib/rgame/engine/actor.rb +53 -0
  105. data/lib/rgame/engine/animation_set.rb +49 -0
  106. data/lib/rgame/engine/animator.rb +44 -0
  107. data/lib/rgame/engine/audio_bus.rb +24 -0
  108. data/lib/rgame/engine/audio_director.rb +29 -0
  109. data/lib/rgame/engine/body.rb +49 -0
  110. data/lib/rgame/engine/cached_label.rb +33 -0
  111. data/lib/rgame/engine/camera.rb +33 -0
  112. data/lib/rgame/engine/camera_view.rb +28 -0
  113. data/lib/rgame/engine/circle_collider.rb +32 -0
  114. data/lib/rgame/engine/collision_box.rb +34 -0
  115. data/lib/rgame/engine/collision_system.rb +44 -0
  116. data/lib/rgame/engine/component.rb +30 -0
  117. data/lib/rgame/engine/components/action_trigger.rb +41 -0
  118. data/lib/rgame/engine/components/animated_sprite.rb +63 -0
  119. data/lib/rgame/engine/components/character_body.rb +70 -0
  120. data/lib/rgame/engine/components/circle_collider.rb +44 -0
  121. data/lib/rgame/engine/components/collision_world.rb +103 -0
  122. data/lib/rgame/engine/components/despawn_offscreen.rb +26 -0
  123. data/lib/rgame/engine/components/path_follow.rb +84 -0
  124. data/lib/rgame/engine/components/player_controller.rb +24 -0
  125. data/lib/rgame/engine/components/pool.rb +53 -0
  126. data/lib/rgame/engine/components/screen_wrap.rb +27 -0
  127. data/lib/rgame/engine/components/sprite.rb +31 -0
  128. data/lib/rgame/engine/components/targeting.rb +54 -0
  129. data/lib/rgame/engine/components/thrust_controller.rb +65 -0
  130. data/lib/rgame/engine/components/tile_world.rb +68 -0
  131. data/lib/rgame/engine/components/timer.rb +75 -0
  132. data/lib/rgame/engine/components/velocity.rb +27 -0
  133. data/lib/rgame/engine/components/wander_controller.rb +60 -0
  134. data/lib/rgame/engine/debug_overlay.rb +106 -0
  135. data/lib/rgame/engine/i18n.rb +97 -0
  136. data/lib/rgame/engine/input/action_mapper.rb +46 -0
  137. data/lib/rgame/engine/input/actions.rb +41 -0
  138. data/lib/rgame/engine/input/player_controller.rb +14 -0
  139. data/lib/rgame/engine/matrix.rb +32 -0
  140. data/lib/rgame/engine/node2d.rb +271 -0
  141. data/lib/rgame/engine/path.rb +78 -0
  142. data/lib/rgame/engine/pool.rb +51 -0
  143. data/lib/rgame/engine/resettable.rb +67 -0
  144. data/lib/rgame/engine/scene/scene_stack.rb +65 -0
  145. data/lib/rgame/engine/signal.rb +75 -0
  146. data/lib/rgame/engine/spatial_hash.rb +71 -0
  147. data/lib/rgame/engine/tile_collision.rb +78 -0
  148. data/lib/rgame/engine/tile_map.rb +149 -0
  149. data/lib/rgame/engine/tileset.rb +101 -0
  150. data/lib/rgame/engine/timer.rb +51 -0
  151. data/lib/rgame/engine.rb +68 -0
  152. data/lib/rgame/fonts/LiberationSans-Regular.ttf +0 -0
  153. data/lib/rgame/fonts/OFL.txt +102 -0
  154. data/lib/rgame/game.rb +129 -0
  155. data/lib/rgame/util/color.rb +27 -0
  156. data/lib/rgame/util/controls.rb +107 -0
  157. data/lib/rgame/util/tensor.rb +12 -0
  158. data/lib/rgame/util.rb +8 -0
  159. data/lib/rgame/version.rb +12 -0
  160. data/lib/rgame.rb +20 -0
  161. metadata +215 -0
@@ -0,0 +1,159 @@
1
+ # Vendored third-party code
2
+
3
+ Third-party sources that are **compiled into the engine** live here. Note what
4
+ is *not* here: the default font, which is data read at runtime and therefore
5
+ lives where a gem installs data — see "The default font" at the bottom.
6
+
7
+ ## `stb_image.h` — v2.30
8
+
9
+ Single-header image decoder by Sean Barrett, <http://nothings.org/stb>.
10
+ Dual-licensed **MIT or public domain (Unlicense)** — the full text is at the
11
+ bottom of the header itself. Nothing needs to be done to comply with either;
12
+ it is recorded here so the choice is visible without reading 8000 lines.
13
+
14
+ **Why vendored rather than a system package.** It is not packaged on any
15
+ mainstream distro, and the alternative is a `libpng` (plus `zlib`) build
16
+ dependency that every `gem install rgame` would then have to satisfy. A
17
+ public-domain header in the repo is the smaller obligation, and it is the only
18
+ dependency the gem does not have to ask for.
19
+
20
+ Only PNG decoding is enabled (`STBI_ONLY_PNG`); the other formats are compiled
21
+ out, which keeps the object small and shrinks the parsing surface exposed to
22
+ whatever files a game happens to load.
23
+
24
+ ## `stb_truetype.h` — v1.26
25
+
26
+ Single-header TrueType rasteriser from the same author and under the same
27
+ dual licence. It turns the shipped `.ttf` into the coverage bitmaps that fill
28
+ the glyph atlas.
29
+
30
+ Same reasoning as above, with more force: the alternative is FreeType, which is
31
+ a real system dependency, and Gosu — which this engine replaces — vendors this
32
+ very header for this very job.
33
+
34
+ No feature macros are set. The defaults are what a glyph atlas wants, and
35
+ `STBTT_STATIC` is deliberately *not* defined so that `font.c` can call into it
36
+ from another translation unit.
37
+
38
+ ## `miniaudio.h` — v0.11.25
39
+
40
+ Single-header audio playback library by David Reid,
41
+ <https://miniaud.io>. Dual-licensed **public domain or MIT-0**, stated at the
42
+ bottom of the header.
43
+
44
+ It provides the device, the mixer and voice management. On Linux it finds ALSA
45
+ or PulseAudio **at runtime** with `dlopen`, so nothing has to be linked or
46
+ installed; on Windows and macOS it needs nothing at all. That is the property
47
+ that makes audio cost this project no new system dependency, and it is the whole
48
+ reason it is here instead of SDL_mixer — which would need `libsdl2-mixer-dev` to
49
+ build and pulls ~8 MB on Debian, six of them a MIDI soundfont.
50
+
51
+ That choice was made by looking at what comparable engines do rather than by
52
+ preference. raylib vendors this same header; SFML 3 bundles it; DragonRuby and
53
+ Gosu vendor MojoAL. Nobody in the small-C-engine category depends on SDL_mixer.
54
+ The one close peer that does is ruby2d, and the price shows in its `extconf.rb`:
55
+ a hand-maintained package-name table for five package managers, plus around
56
+ twenty prebuilt static archives shipped in the gem because system libraries are
57
+ hopeless on macOS and Windows. That is the real cost of the SDL satellite
58
+ libraries — either your users fight their package manager, or you become a
59
+ distributor of binaries.
60
+
61
+ MojoAL was the other finalist and both were prototyped against the full feature
62
+ set: load an ogg, overlapping one-shots, streaming music, `playing?`, stop,
63
+ volume. MojoAL is ten times smaller and compiles ten times faster. miniaudio won
64
+ on the two things OpenAL hands back to the caller — streaming and voice
65
+ management — because a stream needs a pump, and a pump driven from the frame
66
+ loop turns a slow frame into an audio dropout.
67
+
68
+ It is ~4 MB of source, an order of magnitude more than everything else here.
69
+ That is known and accepted; if it ever stops being worth it, MojoAL is the
70
+ fallback and is a tenth the size.
71
+
72
+ Which formats and backends are compiled in is decided in
73
+ [`miniaudio_impl.c`](miniaudio_impl.c) rather than in build flags, so the
74
+ standalone binary and the gem cannot end up supporting different things.
75
+
76
+ ## `stb_vorbis.c` — v1.22
77
+
78
+ Ogg Vorbis decoder, same author and licence as the other stb files. miniaudio
79
+ **cannot read Ogg Vorbis** — it does wav, mp3 and flac — and its own reference
80
+ vorbis backend uses *system* libvorbis, which would hand back the dependency all
81
+ of the above avoids. `../audio/vorbis_decoder.c` is a miniaudio decoding backend over
82
+ this instead.
83
+
84
+ Note it ships as a `.c`, not a `.h`: it is always an implementation, with no
85
+ declarations-only mode.
86
+
87
+ ## How they are built
88
+
89
+ Each library becomes code in exactly one file, `<name>_impl.c`, which sits here
90
+ beside the library it instantiates and contains the implementation macro and the
91
+ feature choices, and nothing else. **The `_impl.c` suffix is reserved for
92
+ vendored code** — it is what selects the warning carve-out below.
93
+
94
+ **Those files are the only ones in the project compiled without `-Wall
95
+ -Wextra`.** Third-party code rarely survives them, and everything we wrote is
96
+ meant to stay warning-clean. Both build systems carve out the same set from one
97
+ list rather than one rule per library — `VENDOR_OBJS` and the `%_impl.o`
98
+ pattern rule in the root `Makefile`, and `VENDORED` in `extconf.rb`, which
99
+ appends an explicit rule per entry (mkmf Makefiles have to work with whatever
100
+ `make` the platform has, and pattern rules are a GNU extension).
101
+
102
+ Adding another library is therefore: drop the source here, add `<name>_impl.c`,
103
+ and add the name to those two lists.
104
+
105
+ ### Updating them
106
+
107
+ ```
108
+ V=ext/rgame_core/vendor
109
+ curl -sSL -o $V/stb_image.h https://raw.githubusercontent.com/nothings/stb/master/stb_image.h
110
+ curl -sSL -o $V/stb_truetype.h https://raw.githubusercontent.com/nothings/stb/master/stb_truetype.h
111
+ curl -sSL -o $V/stb_vorbis.c https://raw.githubusercontent.com/nothings/stb/master/stb_vorbis.c
112
+ curl -sSL -o $V/miniaudio.h https://raw.githubusercontent.com/mackron/miniaudio/master/miniaudio.h
113
+ ```
114
+
115
+ Then run `make test` and `rake spec:core`. Those suites decode a real PNG and
116
+ check its pixels, measure and render real glyphs, and decode a real `.ogg` — so
117
+ a regression in any of the four shows up as a failure rather than as something
118
+ noticed months later. Bump the versions in the headings above.
119
+
120
+ ### The audio test fixture
121
+
122
+ `spec_core/fixtures/tone.ogg` is generated by
123
+ [`tools/make_ogg_fixture.c`](../../../tools/make_ogg_fixture.c) and committed.
124
+ The other suites build their own fixtures — PNGs from Ruby's zlib, glyphs from
125
+ the shipped font — but there is no Ogg Vorbis encoder in Ruby's standard library
126
+ and stb_vorbis only decodes, so this one is made once with `libvorbisenc` and
127
+ checked in. That library is needed to *regenerate* the fixture and by nothing
128
+ else; the engine links no vorbis library at all.
129
+
130
+ ## The default font
131
+
132
+ `lib/rgame/fonts/LiberationSans-Regular.ttf` — **Liberation Sans 2.1.5**, from
133
+ the upstream release at <https://github.com/liberationfonts/liberation-fonts>,
134
+ licensed **SIL Open Font License 1.1** (`lib/rgame/fonts/OFL.txt`).
135
+
136
+ It is not in this directory because it is not compiled — it is a data file the
137
+ engine reads at runtime, so it belongs where the gem installs data. `Font.new`
138
+ without a path uses it.
139
+
140
+ **Take 2.x, not 1.x.** Liberation 1.x is GPL-2-with-a-font-exception rather than
141
+ OFL, and lacks capital `ẞ`. The 2.x file is 410 KB and covers 2327 codepoints:
142
+ Latin-1 Supplement and Latin Extended-A complete (so English, German, French,
143
+ Italian, Spanish, Portuguese, Nordic and Polish in full, plus `« »`, curly
144
+ quotes and `€`), and Greek and Cyrillic besides. Not CJK, Arabic, Hebrew or
145
+ Devanagari — a game needing those passes its own font path.
146
+
147
+ **Why ship a font at all, rather than asking the system for one?** Because the
148
+ lookup is not one lookup. Doing it the way a font-database library does means a
149
+ backend per platform — fontconfig on Linux, CoreText on macOS, GDI on Windows —
150
+ which is a system dependency this project otherwise does not have, and a
151
+ per-glyph *fallback chain* on top: a name, then a series of substitutes, then
152
+ whatever the database offers, then a hardcoded path. The engine this one
153
+ replaces ended its Linux chain at a literal Debian path.
154
+
155
+ Vendoring buys the thing the lookup structurally cannot: **text renders
156
+ identically on every machine.** A UI laid out against one font on the
157
+ developer's box and a substituted one on a player's is a layout bug nobody can
158
+ reproduce. 410 KB is a fair price, and it is smaller than the PNG decoder
159
+ already sitting in this directory.