Added rapbattles courtesy of Bloitzhole

This commit is contained in:
barelyprofessional
2026-07-08 22:02:10 -05:00
parent 3bd5fc5d96
commit 3074443c34
7 changed files with 1177 additions and 1 deletions
@@ -0,0 +1,32 @@
# Keno Kasino rap battle challenge flourishes
#
# When someone is challenged, the bot picks ONE of these lines at random and appends it to the
# challenge announcement, right after "...for <bet> a head." For example, picking "GET ON STAGE!"
# produces: "...you've been challenged to a RAP BATTLE by @X for 500 KKK a head. GET ON STAGE! Reply ..."
#
# One flourish per line. Blank lines and lines starting with '#' are ignored.
# {challenger} and {opponent} are replaced with the respective usernames (already @-prefixed).
#
# Edit this file freely - it's reloaded on every challenge, no restart required.
# The avelloon has, allegedly, been seen slipping a few of its own taunts in here.
GET ON STAGE!
Bars or be felted.
Step up or step off.
The avelloon is watching. Don't choke.
Time to find out who's really got bars.
Lace up, this one's for the culture.
No pen, no paper, no mercy.
The mic is hot and the crowd is mean.
Defend your honor or forfeit your juice.
{opponent}, the whole Kasino can hear the silence already.
Crack your knuckles, {opponent}.
Last one to spit is a Ratdad.
The booth is open. The judges are nefarious.
Don't bring bars to a felting.
Warm up that throat, {opponent}.
Either drop heat or drop out.
Cmon Cmon Cmon, prove you're not all talk.
The avelloon already wrote your eulogy. Prove it wrong.
Money's up. Egos higher. Let's go.
This is your moment, {opponent}. Don't fumble it.
@@ -0,0 +1,60 @@
# Keno Kasino rap battle feedback pool
#
# The Kasino "mediator" reads one of these lines at random to justify the winner of a
# rap battle. The result is PURE CHANCE - the actual verses are never read by anyone.
# These lines exist purely to preserve the illusion that the bars mattered.
#
# One reason per line. Blank lines and lines starting with '#' are ignored.
# {winner} and {loser} are replaced with the respective usernames (already @-prefixed).
# {verse} is replaced with a short, sanitised snippet of the WINNER's submitted verse,
# so you can write lines that "quote" the bars - e.g. the lines near the bottom of this file.
#
# Edit this file freely - it's reloaded every battle, no restart required.
# An avelloon was last seen tampering with these lines. Audit accordingly.
{winner}'s flow was tighter than {loser}'s budget after a night at the Kasino.
The judges felt {winner}'s bars in their soul, while {loser} mostly mumbled into the mic.
{winner} stayed on beat; {loser} was rapping to a metronome only they could hear.
{winner}'s punchlines actually landed. {loser} threw haymakers at the air.
{winner} had the crowd bouncing. {loser} had the crowd checking their phones.
{winner}'s wordplay was surgical. {loser} brought a spork to a knife fight.
{winner} controlled the cypher from bar one. {loser} got lost looking for it.
{winner}'s delivery was ice cold. {loser} sweated through every syllable.
{winner} painted pictures with every line. {loser} drew stick figures.
{winner}'s rhyme scheme was a labyrinth. {loser}'s rhymed 'cat' with 'cat'.
{winner} switched flows three times mid-verse. {loser} forgot the one flow they had.
{winner}'s breath control was elite. {loser} tapped out halfway through the first bar.
{winner} weaponized the silence between bars. {loser} just filled it with 'uhh'.
{winner}'s metaphors hit like a felted plane. {loser}'s landed like a wet rizla.
{winner} freestyled circles around {loser}'s pre-written notes-app verse.
{winner} had bars for days. {loser} had a payment plan.
{winner}'s cadence was hypnotic. {loser}'s put the front row to sleep.
{winner} dropped a triple entendre. {loser} dropped the mic on their own foot.
{winner}'s diss was personal and devastating. {loser} apologized mid-verse.
The Kasino's certified-fair applause-o-meter clocked {winner} at double {loser}'s volume.
{winner} brought the heat; {loser} brought a participation trophy.
{winner} rhymed in pocket. {loser} rhymed in another area code.
{winner}'s closer left the room speechless. {loser}'s closer left the room.
{winner} simply wanted it more, and the algorithm respects hunger.
{winner} spit fire. {loser} spit, then forgot the rest.
# Lines that quote the winner's verse with {verse}:
The Kasino found the line "{verse}" very moving. You win, {winner}.
"{verse}" — the judges replayed that bar three times. {winner} takes it over {loser}.
When {winner} dropped "{verse}", {loser} knew it was over.
"{verse}". Chills. That's a {winner} victory, no debate.
The mediator is still quoting "{verse}" in the back office. {winner} wins.
{loser} never recovered after {winner} hit them with "{verse}".
That "{verse}" line had the whole room gasping. Crown goes to {winner}.
# Lines where the avelloon - a nefarious, cat-shaped balloon that rigs casinos - presides as judge:
The avelloon, a cat-shaped balloon of pure malice, bobbed toward {winner} and declared the battle rigged in their favor.
The judge tonight is the avelloon. It rigged the scoreboard, doxxed {loser}'s rhyme notes, and crowned {winner} anyway.
The avelloon floated over the booth, hissed at {loser}, and pawed the win to {winner}. Probably fair.
A nefarious balloon shaped like a cat — the avelloon — inflated with glee and awarded the bag to {winner}.
The avelloon doesn't read bars, it reads leaked data. It found dirt on {loser} and handed {winner} the W.
By decree of the avelloon, the rigging cat balloon that owns this Kasino: {winner} wins. Appeals go in the trash.
The avelloon batted the verdict between its paws, then let it drift to {winner}. {loser} was felted by helium and spite.
The avelloon judged "{verse}" the realest bar of the night. {winner} takes it; {loser} got rigged, as is tradition.
The avelloon squeaked once, ominously, and the scoreboard flipped to {winner}. Nobody questions the balloon.
The avelloon rigged it, the avelloon owns it, the avelloon says {winner}. {loser}, file a complaint with the cat.
File diff suppressed because it is too large Load Diff
+9
View File
@@ -51,6 +51,15 @@
<Content Include="NLog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Remove="rapbattle_feedback.txt" />
<!-- PreserveNewest so admins can edit the feedback pool in the output dir without rebuilds clobbering it -->
<None Remove="rapbattle_challenges.txt" />
<Content Update="Assets\rapbattle_challenges.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\rapbattle_feedback.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
@@ -311,7 +311,9 @@ public enum WagerGame
[Description("Roulette but live")]
Roulette,
Krash,
Cecil
Cecil,
[Description("Rap Battle")]
RapBattle
}
public enum GamblerState
+23
View File
@@ -47,6 +47,7 @@ public class BotServices
private Task? _websocketWatchdog;
private Task? _howlggGetUserTimer;
private Task? _rapBattleTimeoutSweeper;
private string? _bmjTwitchUsername;
private bool _twitchDisabled;
@@ -114,6 +115,28 @@ public class BotServices
_logger.Info("Starting websocket watchdog and Howl.gg user stats timer");
_websocketWatchdog = WebsocketWatchdog();
_howlggGetUserTimer = HowlggGetUserTimer();
_rapBattleTimeoutSweeper = RapBattleTimeoutSweeperTask();
}
// Durable replacement for the rap battle's old in-memory timeout timers: rap battle state lives in
// Redis, and this periodically refunds any battle whose deadline has passed - so timeouts still fire
// after a restart. No-ops cheaply when Redis isn't configured.
private async Task RapBattleTimeoutSweeperTask()
{
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(5));
while (await timer.WaitForNextTickAsync(_cancellationToken))
{
if (_chatBot.InitialStartCooldown) continue;
try
{
await Commands.Kasino.RapBattleCommand.SweepExpiredBattlesAsync(_chatBot);
}
catch (Exception e)
{
_logger.Error("Rap battle timeout sweep failed");
_logger.Error(e);
}
}
}
private async Task BuildKasinoKrash()
+24
View File
@@ -597,6 +597,30 @@ public static class BuiltIn
public static string KasinoPlinkoSize = "Kasino.Plinko.Size";
[BuiltInSetting("Whether Cecil is enabled", SettingValueType.Boolean, "true", BooleanRegex)]
public static string KasinoCecilEnabled = "Kasino.Cecil.Enabled";
[BuiltInSetting("Whether the rap battle game is enabled", SettingValueType.Boolean, "true", BooleanRegex)]
public static string KasinoRapBattleEnabled = "Kasino.RapBattle.Enabled";
[BuiltInSetting("How many seconds players have to accept a rap battle, and (once accepted) to submit their verses", SettingValueType.Text, "90", WholeNumberRegex)]
public static string KasinoRapBattleTimeout = "Kasino.RapBattle.Timeout";
[BuiltInSetting("Percentage of the pot the Kasino keeps as mediator when a rap battle is decided", SettingValueType.Text, "10")]
public static string KasinoRapBattleCasinoCutPercent = "Kasino.RapBattle.CasinoCutPercent";
[BuiltInSetting("Percentage fee the Kasino keeps when a rap battle is declined or times out and buy-ins are refunded", SettingValueType.Text, "5")]
public static string KasinoRapBattleRefundFeePercent = "Kasino.RapBattle.RefundFeePercent";
[BuiltInSetting("Minimum bet for a rap battle", SettingValueType.Text, "1", WholeNumberRegex)]
public static string KasinoRapBattleMinimumBet = "Kasino.RapBattle.MinimumBet";
[BuiltInSetting("Minimum length (in characters) of a rap battle verse, to guard against low-effort one-word entries", SettingValueType.Text, "12", WholeNumberRegex)]
public static string KasinoRapBattleMinimumVerseLength = "Kasino.RapBattle.MinimumVerseLength";
[BuiltInSetting("Minimum number of bars (sentences separated by full stops) a rap battle verse must contain. There is no maximum", SettingValueType.Text, "3", WholeNumberRegex)]
public static string KasinoRapBattleMinimumBars = "Kasino.RapBattle.MinimumBars";
[BuiltInSetting("Delay in milliseconds before cleaning up transient rap battle status / error messages", SettingValueType.Text, "15000", WholeNumberRegex)]
public static string KasinoRapBattleCleanupDelay = "Kasino.RapBattle.CleanupDelay";
[BuiltInSetting("Delay in milliseconds the bot spends 'evaluating' the verses (fake suspense) before revealing a rap battle result", SettingValueType.Text, "3500", WholeNumberRegex)]
public static string KasinoRapBattleEvaluatingDelay = "Kasino.RapBattle.EvaluatingDelay";
[BuiltInSetting("Path to the editable text file containing the pool of (fictional) rap battle feedback lines. One reason per line, lines starting with # are ignored, {winner}, {loser} and {verse} are substituted", SettingValueType.Text, "rapbattle_feedback.txt")]
public static string KasinoRapBattleFeedbackFile = "Kasino.RapBattle.FeedbackFile";
[BuiltInSetting("Path to the editable text file containing the pool of rap battle challenge flourishes appended to the challenge message (e.g. 'GET ON STAGE!'). One per line, lines starting with # are ignored, {challenger} and {opponent} are substituted", SettingValueType.Text, "rapbattle_challenges.txt")]
public static string KasinoRapBattleChallengeFile = "Kasino.RapBattle.ChallengeFile";
[BuiltInSetting("Whether the rap battle cheat code is active. Burned out permanently (set false) the first time both rappers invoke it in the same battle", SettingValueType.Boolean, "true", BooleanRegex)]
public static string KasinoRapBattleCheatEnabled = "Kasino.RapBattle.CheatEnabled";
[BuiltInSetting("Proxy to use when connecting to Kiwi Farms for WS and logging in", SettingValueType.Text)]
public static string KiwiFarmsProxy = "KiwiFarms.Proxy";
}