Skip to content

Latest commit

 

History

157 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

chalkwalk-jambot

Bots that play in a NINJAM room, and answer when you talk to them. JUCE-free, MIT.

A band for one player who wanted to jam and found nobody there. Not a composer, not a backing track. docs/PRINCIPLES.md is the twelve rules that follow from that, docs/NON-GOALS.md is what they refuse and what to reach for instead, and docs/BOT-CHAT.md is the long argument behind both -- read the short ones first.

They hold a key and a chord chart, render a part per interval on the beat grid the room is running, and read the room's chat well enough to be asked things: what key are we in, can we slow down, play something else, stop, start again.

PracticeBot.{h,cpp} one bot: renders its part, answers what it is asked
BotBand.{h,cpp} the ensemble -- which voice plays what, and the mix
BotVoice.h, BotDsp.h the instruments, and the primitives under them
BandPatch.{h,cpp} the tunable knobs, and the patch file format
BandPlayState.h Silent/Playing/Wrapping/Resolving: how a tune ends
IntervalPump.h the interval grid, driven. One thread, free-running
BotAddress.{h,cpp} who a message is for
BotLanguage.{h,cpp} what it asks
BotAnswer.{h,cpp} what it says back -- pure functions over room state
BotChat.{h,cpp} the join of the three: context + message -> what to say
BotNames.{h,cpp} the name pool, and picking a band that reads apart
BotClient.h the room as a bot needs it: 14 calls out, 6 back

The corpus is the specification

test/fixtures/bot-phrases.txt says what a message asks and bot-addressing.txt says who it is for. Add the phrasing first and watch it go red. Every fourth line of each section is held out from tuning, and the holdout rate is the only figure that says anything about phrasing nobody has thought of. Append to the end of a section so new lines keep feeding it.

src/BotDictionary.h is generated by scripts/make_wordlist.py and must not be hand-edited; regenerate it after any lexicon change. scripts/lexicon_gaps.py proposes entries from the corpus and never edits.

What a bot will not do

It will not set the key. The key travels as a tagged chat line, [key: D minor], and saying that line is setting it -- in every Antiphon client in the room. So no reply may contain the tag, and a bot asked to change the key answers with the line for a person to type instead. BotAnswerTests asserts that over every string this library can produce, because no corpus can catch it and the failure would be silent.

It will not start a vote, either. It will back one.

Use

add_subdirectory(libs/jambot)
target_link_libraries(your_target PRIVATE chalkwalk::jambot)

A host supplies the room through BotClient.h -- connect, chat, transmit, and a timer. Scheduling is asked for rather than taken, because the bots' own timers must fire wherever the host's messages are delivered; a scheduler thread of their own would turn heardOne into a silent race.

Build and test

git submodule update --init --recursive
cmake -B build && cmake --build build && ctest --test-dir build

Standalone with nothing else on the machine — that is the test of the boundary, not a convenience. A library that only builds inside its parent has not been extracted.

To try a change to one of the shared libraries without pushing it:

cmake -B build -DCHALKWALK_MUSIC_DIR=$HOME/Programming/chalkwalk-music

CHALKWALK_DSP_DIR and CHALKWALK_NINJAM_DIR likewise. Configure prints OVERRIDE when one is in use, because the submodule SHA then no longer describes what you built.

Provenance, and why this is MIT

This came out of Antiphon, which is GPLv3, with its history intact — git filter-repo, not a copy, so git log --follow still reaches the commit that first brought a band to the practice room. Same author throughout, so the relicensing is the copyright holder's to make; it is stated here rather than assumed, because relicensing is a decision and not a default.

Antiphon keeps what a practice room needs and a command-line bot does not: the loopback server, and the room that puts a server and a band together.

Not yet done

  • The namespaces are still BotBand, PracticeBot and the rest, not chalkwalk::jambot, and the headers sit in src/ rather than include/chalkwalk/jambot/. Both are deliberate and both are temporary: this repository's first job was to carry its history across intact, and renaming several hundred call sites in the same change would have made the move and the rename impossible to review separately.
  • There is no client yet. BotClient.h is the interface a host implements; Antiphon implements it, and nothing here does. A JUCE-free socket client is what stands between this library and jambot --connect host:port.
  • The suites run on a shim. test/JuceUnitShim.h gives juce::UnitTest's verbs and enough of juce::String on top of Catch2, so the assertions came across unedited. The count is the check that nothing was dropped, and it is exact: 25,705 either side, suite for suite.

Licence

MIT. See LICENSE.

Part of the chalkwalk ecosystem, alongside chalkwalk-music, chalkwalk-dsp and chalkwalk-ninjam, which it depends on.

About

Bots that play in a NINJAM room and answer when you talk to them: parts on the interval grid, a key and a chart they hold, and chat they actually read. JUCE-free, MIT.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages