asterism-games 0.20.0 → 0.22.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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/README.md +67 -9
  4. data/VERSION +1 -1
  5. data/lib/asterism_games/commentate/assets/SOUNDS_LICENSE.txt +63 -0
  6. data/lib/asterism_games/commentate/assets/commentate.css +9 -4
  7. data/lib/asterism_games/commentate/assets/commentate.js +298 -7
  8. data/lib/asterism_games/commentate/assets/index.html +5 -3
  9. data/lib/asterism_games/commentate/assets/sounds/after_the_rain.mp3 +0 -0
  10. data/lib/asterism_games/commentate/assets/sounds/chi.wav +0 -0
  11. data/lib/asterism_games/commentate/assets/sounds/discard.wav +0 -0
  12. data/lib/asterism_games/commentate/assets/sounds/discard_other.wav +0 -0
  13. data/lib/asterism_games/commentate/assets/sounds/draw.wav +0 -0
  14. data/lib/asterism_games/commentate/assets/sounds/encounter.mp3 +0 -0
  15. data/lib/asterism_games/commentate/assets/sounds/fanfare1.wav +0 -0
  16. data/lib/asterism_games/commentate/assets/sounds/fanfare2.wav +0 -0
  17. data/lib/asterism_games/commentate/assets/sounds/fanfare3.wav +0 -0
  18. data/lib/asterism_games/commentate/assets/sounds/fanfare4.wav +0 -0
  19. data/lib/asterism_games/commentate/assets/sounds/kan.wav +0 -0
  20. data/lib/asterism_games/commentate/assets/sounds/kyuushu.wav +0 -0
  21. data/lib/asterism_games/commentate/assets/sounds/points.wav +0 -0
  22. data/lib/asterism_games/commentate/assets/sounds/pon.wav +0 -0
  23. data/lib/asterism_games/commentate/assets/sounds/riichi.wav +0 -0
  24. data/lib/asterism_games/commentate/assets/sounds/ron.wav +0 -0
  25. data/lib/asterism_games/commentate/assets/sounds/round.wav +0 -0
  26. data/lib/asterism_games/commentate/assets/sounds/ryuukyoku.wav +0 -0
  27. data/lib/asterism_games/commentate/assets/sounds/sounds.json +335 -0
  28. data/lib/asterism_games/commentate/assets/sounds/spring_thing.mp3 +0 -0
  29. data/lib/asterism_games/commentate/assets/sounds/tsumo.wav +0 -0
  30. data/lib/asterism_games/commentate/assets/sounds/turn.wav +0 -0
  31. data/lib/asterism_games/commentate/assets/sounds/yaku.wav +0 -0
  32. data/lib/asterism_games/commentate/mahjong.rb +11 -4
  33. data/lib/asterism_games/commentate/mahjong_sounds.rb +118 -0
  34. data/lib/asterism_games/commentate/server.rb +14 -2
  35. data/lib/asterism_games/commentate.rb +8 -2
  36. data/lib/asterism_games/play/mahjong.rb +3 -1
  37. metadata +29 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a35db1346246e5d20505026e701fef357536cc75fa53f22bf47878398fb01c3
4
- data.tar.gz: 79c4c46763e2104c3e4d03ba521327e9ceb5fa77fc74521cec6041eb3ca48b89
3
+ metadata.gz: e6e27396e105e0e9ab5c096030c51cb529a437291460df76fc6b0510fc9dff6d
4
+ data.tar.gz: 237c4a6b962e98dc9c3a7e1288c646989a256c1773dd8244ddc9146d5873db55
5
5
  SHA512:
6
- metadata.gz: 2b31fdedf12d610dca0c8cbd4f1ae060b5b42eeab54dee46d62f0ced96d8895468b48e84db2eae2904489448329a19ef5888cf9cb2a514684c2610d4e0937d87
7
- data.tar.gz: 9908df82204210223cecd09b651da9d12e3a27ee832433d0e57b74d4d895a7a9753c83c20b75cadfeff88ef94eb91f6564290be193b1e501a37ce209124b67d3
6
+ metadata.gz: e428ec7e87cc08c9727743c322448eb8a4c39c2d2fa0d6005eb4855dea335d3884d82ceae0a3da66e35e8ca88a07c03518a7c7329cc0d4f6b0395ba702b3da4f
7
+ data.tar.gz: 1f61104e967413c4c5ee65a75a71ad9ca572007b8fdfa3dd0518257ea585be1e6798cc804dfa0752b6a8fa002bf41046efabe94b80df80fa7cb2766a9af19663
data/CHANGELOG.md CHANGED
@@ -3,6 +3,41 @@
3
3
  Versions before 0.11.1 are noted in the README where each feature is
4
4
  described ("games 0.10.0" and the like).
5
5
 
6
+ ## Unreleased
7
+
8
+ ## 0.22.0
9
+
10
+ - Needs CRuby 3.4 or newer (`required_ruby_version >= 3.4`; 3.2 is past its end of life). The image is built on `ruby:3.4.11-slim`.
11
+
12
+ ## 0.21.0
13
+
14
+ - **The commentary's sound** (README "The sound"): the page of
15
+ `commentate mahjong` plays Family mruby's mahjong app's BGM and effects,
16
+ the same sounds at the same moments as the app. The BGM follows the
17
+ app's scenes (the lobby, the game, the tense part, none at the end),
18
+ starts low (the app's levels: off, low, mid, high, **B** or the bar's
19
+ button) and goes down to half while the voice speaks. The effects (a
20
+ round's start, the jingles of the calls, riichi and the wins, the
21
+ winner's points, the draws, a discard, the fanfare at the end; as for
22
+ the app's spectator, no draw or turn sound) play beside the voice, sharing the APU's channels as in the
23
+ app; **E** turns them off and on; the page remembers both. Which sound
24
+ when is a pure function of two views (`commentate/mahjong_sounds.rb`);
25
+ each `state` event now carries `bgm` and `sounds`.
26
+ - The files are in the gem (`commentate/assets/sounds/`, 3.6 MB: WAVs for
27
+ the effects, MP3s for the three tunes, `sounds.json`), made with Family
28
+ mruby's own APU emulator by fmruby-core's `tools/mahjong_sounds.rb`.
29
+ The effects are MIT here; the BGM is shiru8bit's under CC BY 3.0,
30
+ unchanged (`SOUNDS_LICENSE.txt`), credited in the page's corner. The
31
+ web server serves `/sounds/` (those files only) and
32
+ `/SOUNDS_LICENSE.txt`.
33
+
34
+ ## 0.20.1
35
+
36
+ - `play mahjong`: an owner's command queued with `--commands` (`watch`,
37
+ `start`, `cpu` ...) while someone else holds the owner's role now says
38
+ so (「卓の主ではありません。卓の主の役が回ってくるのを待っています」)
39
+ instead of asking for a seat: since 0.20.0 an owner may be unseated.
40
+
6
41
  ## 0.20.0
7
42
 
8
43
  - **Watch games** (README "Watch games"): the owner of a mahjong table
data/README.md CHANGED
@@ -92,7 +92,7 @@ nothing else (othello, the drawing board), `bin/asterism-games` (with
92
92
  `play`, the terminal clients of othello and mahjong: a mahjong table needs
93
93
  riichi_engine, its client does not; and `commentate`, a mahjong table watched
94
94
  in the browser with commentary, with the tile sheets of Family mruby's
95
- mahjong app). It depends on
95
+ mahjong app and its sound: the effects and the BGM, "The sound"). It depends on
96
96
  the asterism gem only (0.7.1 or later in
97
97
  0.x; what came after 0.7.1, such as `@status` and `on_app_join`, is used
98
98
  when there). Not in it: mahjong (`app/`, it needs the riichi_engine fork
@@ -102,7 +102,7 @@ anthropic gem as well, which is not a dependency (`gem install anthropic`,
102
102
  "AI players").
103
103
 
104
104
  ```
105
- gem install asterism-games # CRuby 3.2 or newer and a C compiler (asterism-zenoh)
105
+ gem install asterism-games # CRuby 3.4 or newer and a C compiler (asterism-zenoh)
106
106
  ```
107
107
 
108
108
  A host of the sample games on a plain zenohd (`games.yml`):
@@ -144,7 +144,7 @@ docs/install.md (`deploy/vps`, which pulls it, or builds it with
144
144
 
145
145
  ## Running
146
146
 
147
- From this checkout (everything, mahjong too). CRuby 3.2 or newer and a C
147
+ From this checkout (everything, mahjong too). CRuby 3.4 or newer and a C
148
148
  compiler (asterism-zenoh compiles its extension). Bundler fetches the
149
149
  riichi_engine fork from GitHub (see "riichi_engine"). The `Gemfile` is for
150
150
  this checkout and the image (mahjong, the AI players); the gem's own needs
@@ -1568,7 +1568,8 @@ when it is taken), prints the address and opens it in the browser (macOS
1568
1568
  each, the newest at the bottom. Two seats to a row in a wide window, one
1569
1569
  in a narrow one (a phone). Keys: **Space** pauses (what comes meanwhile
1570
1570
  is held and shown when it goes on), **M** turns the voice off and on,
1571
- **H** hides the hands on that page (backs instead of the tiles, and the
1571
+ **B** steps the BGM (off, low, mid, high), **E** turns the effects off
1572
+ and on, **H** hides the hands on that page (backs instead of the tiles, and the
1572
1573
  lines that tell a hand left out). A table that several hosts put is
1573
1574
  chosen in the bar.
1574
1575
  - **The AI's one-liners.** Claude's short lines at the big moments,
@@ -1583,6 +1584,9 @@ when it is taken), prints the address and opens it in the browser (macOS
1583
1584
  Japanese voice when it has one (the bar says which voice, or that it has
1584
1585
  none). Browsers play sound only after the page has been clicked once:
1585
1586
  the page says so until then. "The voice" below.
1587
+ - **The sound.** The BGM and the effects of Family mruby's mahjong app,
1588
+ at the moments the app plays them, the BGM low by default and lower
1589
+ while the voice speaks. "The sound" below.
1586
1590
  - **The commentary.** Made by rules from the difference between one view
1587
1591
  and the one before (pure functions, `commentate/mahjong_events.rb` and
1588
1592
  `mahjong_phrases.rb`, so the host can take them over later), each event
@@ -1601,9 +1605,10 @@ when it is taken), prints the address and opens it in the browser (macOS
1601
1605
  game goes on as before. The delay of the table is the host's
1602
1606
  ("Spectators"); the page shows it and adds none.
1603
1607
  - **The web server.** HTTP by hand on the standard library's `socket`
1604
- (no gem): the page, its script and style, the two tile sheets and
1605
- `/events`, a stream of Server-Sent Events (`status`, `state`, `line`)
1606
- that pushes the table and the commentary. It listens on `127.0.0.1`
1608
+ (no gem): the page, its script and style, the two tile sheets, the
1609
+ sounds (`/sounds/`, the files of `assets/sounds/` only) and `/events`,
1610
+ a stream of Server-Sent Events (`status`, `state`, `line`) that pushes
1611
+ the table and the commentary. It listens on `127.0.0.1`
1607
1612
  only, answers GET (and HEAD) on those paths only, and refuses a request
1608
1613
  whose Host is not `127.0.0.1` or `localhost`. The page loads nothing from
1609
1614
  elsewhere.
@@ -1714,8 +1719,61 @@ your character before you publish anything; they can change):
1714
1719
  description too** (the page shows it in its corner).
1715
1720
  - Whoever you give generated voices to must follow the same terms, so
1716
1721
  they cannot be mixed into an MIT package. That is why this gem ships no
1717
- sound: each user makes the files with their own VOICEVOX, and they stay
1718
- on that machine.
1722
+ voice: each user makes the files with their own VOICEVOX, and they stay
1723
+ on that machine. (The sounds it does ship are the mahjong app's effects
1724
+ and BGM, "The sound".)
1725
+
1726
+ ### The sound
1727
+
1728
+ (games 0.21.0) The page plays the sound of Family mruby's mahjong app:
1729
+ its BGM for the scene and its effects and jingles for what happens, the
1730
+ same sounds at the same moments as the app. They are files in the gem
1731
+ (`lib/asterism_games/commentate/assets/sounds/`), made beforehand with
1732
+ Family mruby's own APU emulator from the app's notes and its NSF tunes
1733
+ (not played again by ear), and the page plays them with Web Audio after
1734
+ the first click (the browser's autoplay rule).
1735
+
1736
+ - **The BGM** follows the app's scenes: the lobby (a table waiting, or no
1737
+ table yet) "After The Rain", the game and its results "Spring Thing",
1738
+ the tense part (a riichi on the table, or 10 tiles or fewer left)
1739
+ "Encounter", nothing at the end of a game (the fanfare plays alone). A
1740
+ tune starts from its beginning and repeats its loop without a seam.
1741
+ **B** (or the bar's button) steps it off, low, mid, high: the app's
1742
+ levels (low is 30 % of the tune's full level, mid 55 %, high 100 %, the
1743
+ effects always at theirs), **low by default**.
1744
+ - **Ducking.** While the voice speaks (VOICEVOX or the browser's), the BGM
1745
+ goes down to half its level, and back up a moment after the voice stops
1746
+ (not between two lines). The effects are not lowered.
1747
+ - **The effects** come with each new view of the table, beside the voice
1748
+ (never waiting in its queue): a round's start, the jingles of a call
1749
+ (チー, ポン, カン), of a riichi, of a win (ロン, ツモ) followed by the
1750
+ winner's points, a draw of the round and the abortive draws, a discard
1751
+ (the app's sound for another player's discard, whoever made it), and
1752
+ the fanfare at the end of the game (the app's spectator's: the
1753
+ winner's). As for the app's spectator, a move sounds its discard only:
1754
+ the player's own sounds (a draw, the turn coming) are not played. They
1755
+ share the APU's four channels as in the app: a sound of a higher
1756
+ priority still sounding keeps its channels, otherwise the newest wins.
1757
+ A voice that would start on top of a jingle waits for most of it (at
1758
+ most 0.6 s). **E** turns the effects off and on. The page remembers
1759
+ both switches (the browser's local storage).
1760
+ - **Which sound, when** is a pure function of two views
1761
+ (`commentate/mahjong_sounds.rb`), and each `state` event carries the
1762
+ BGM's scene (`bgm`) and the effects (`sounds`, `[name, delay ms]`).
1763
+ - **The files.** The effects are WAVs (mono, 16-bit, the APU's 15720 Hz,
1764
+ under 40 KB each); the three tunes are MP3s (24 kHz mono, 64 kbit/s,
1765
+ about 1 MB each: the tune from its start through one pass of its loop,
1766
+ 115 to 154 s). `sounds.json` lists each with its SHA-256, the loop
1767
+ points, the app's levels and scenes. They are made by fmruby-core's
1768
+ `tools/mahjong_sounds.rb` (`ruby tools/mahjong_sounds.rb <dir>`;
1769
+ `--check <dir>` makes them again elsewhere and says whether any differs).
1770
+ - **Their licenses** (`assets/SOUNDS_LICENSE.txt`): the effects are the
1771
+ app's author's and are under the MIT License in this gem, by his
1772
+ decision (fmruby-core keeps them under GPL-3.0). **The BGM is not MIT**:
1773
+ the tunes are by shiru8bit under CC BY 3.0, unchanged (only played from
1774
+ their NSF files and saved as MP3). The page shows
1775
+ 「BGM: shiru8bit (CC BY 3.0)」 in its corner while the BGM is on, beside
1776
+ the voice's credit; put it in a stream's description too.
1719
1777
 
1720
1778
  ### The AI's one-liners
1721
1779
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.20.0
1
+ 0.22.0
@@ -0,0 +1,63 @@
1
+ The sounds in sounds/
2
+
3
+ These are the sound of Family mruby's mahjong app (fmruby-core,
4
+ flash/app/game/mahjong/mahjong_sound.rb), which the commentary page plays:
5
+ the effects and jingles, and the BGM of its scenes. They were not played
6
+ again by ear: fmruby-core's tools/mahjong_sounds.rb plays the app's notes
7
+ and tunes with Family mruby's own APU emulator (components/apu_emu) and
8
+ writes the files; sounds/sounds.json lists each file with its SHA-256 and
9
+ what it was made from.
10
+
11
+ 1. The effects and jingles (sounds/*.wav)
12
+
13
+ discard, discard_other, draw, turn, round, yaku, points, riichi, pon,
14
+ chi, kan, ron, tsumo, kyuushu, ryuukyoku, fanfare1, fanfare2, fanfare3,
15
+ fanfare4
16
+
17
+ Written by Katsuhiko Kageyama, the author of Family mruby and of this
18
+ gem, as notes for the APU. In this gem they are under the MIT License,
19
+ the license of the gem (LICENSE), by the author's decision. In
20
+ fmruby-core they stay under that repository's license (GPL-3.0).
21
+
22
+ MIT License
23
+
24
+ Copyright (c) 2026 Katsuhiko Kageyama
25
+
26
+ Permission is hereby granted, free of charge, to any person obtaining a copy
27
+ of this software and associated documentation files (the "Software"), to deal
28
+ in the Software without restriction, including without limitation the rights
29
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30
+ copies of the Software, and to permit persons to whom the Software is
31
+ furnished to do so, subject to the following conditions:
32
+
33
+ The above copyright notice and this permission notice shall be included in all
34
+ copies or substantial portions of the Software.
35
+
36
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
42
+ SOFTWARE.
43
+
44
+ 2. The BGM (sounds/*.mp3): music by shiru8bit, CC BY 3.0
45
+
46
+ NOT under the MIT License. These three tunes are by shiru8bit and are
47
+ licensed under the Creative Commons Attribution 3.0 Unported license
48
+ (CC BY 3.0, https://creativecommons.org/licenses/by/3.0/), as the NSF
49
+ files Family mruby ships (fmruby-core, flash/usr/share/sounds/nsf/).
50
+
51
+ after_the_rain.mp3 "8-bit Chiptune - After The Rain" by shiru8bit
52
+ https://opengameart.org/content/8-bit-chiptune-after-the-rain
53
+ spring_thing.mp3 "8-bit Chiptune - Spring Thing" by shiru8bit
54
+ https://opengameart.org/content/8-bit-chiptune-spring-thing
55
+ encounter.mp3 "8-bit Chiptune - Encounter" by shiru8bit
56
+ https://opengameart.org/node/100497
57
+
58
+ The music is not changed. Each file is the original NSF played by
59
+ Family mruby's APU emulator and saved as MP3: from the start of the tune
60
+ through one pass of its loop (and a second more); the page repeats the
61
+ loop as the NSF does. Whoever passes these files on, or plays them in a
62
+ stream or a recording, gives the same credit, for example
63
+ "BGM: shiru8bit (CC BY 3.0)" (the page shows it in its corner).
@@ -80,19 +80,24 @@ body.obs #captions { max-height: none; background: rgba(0, 0, 0, 0.55); }
80
80
  .cap.ai span { color: var(--ai); font-style: italic; }
81
81
  .cap.ai.old span { color: var(--dim); }
82
82
  #keys { padding: 0 12px 8px; color: var(--dim); font-size: 12px; }
83
- /* The voice's credit (VOICEVOX:<character>), in the corner, on a stream too. */
84
- #credit {
83
+ /* The credits (VOICEVOX:<character>, the BGM's), in the corner, on a stream too. */
84
+ #credits {
85
85
  position: fixed;
86
86
  right: 8px;
87
87
  bottom: 6px;
88
+ display: flex;
89
+ gap: 6px;
90
+ pointer-events: none;
91
+ }
92
+ #credits span {
88
93
  padding: 1px 6px;
89
94
  font-size: 12px;
90
95
  color: var(--dim);
91
96
  background: rgba(0, 0, 0, 0.45);
92
97
  border-radius: 3px;
93
- pointer-events: none;
94
98
  }
95
- #credit[hidden] { display: none; }
99
+ #credits span[hidden] { display: none; }
100
+ #bar .btn { cursor: pointer; user-select: none; }
96
101
  @media (max-width: 600px) {
97
102
  #captions { font-size: 16px; }
98
103
  .cap.p3 span { font-size: 18px; }