Some releases add a command.
This one adds a room.
Not a literal room, of course. Mediabot is still a Perl IRC bot, not a confused castle architect.
But this update makes Mediabot feel like it has discovered a new chamber somewhere between the Room of Requirements, the Marauderβs Map, and a very opinionated observatory.
It can now read the channel more clearly. It can rank things without shouting. It can tell a channelβs story. It can keep achievements fun without turning every unlock into fireworks. It can gate the noisy toys behind chansets. It can watch, remember, summarize, and stay polite.
That last part matters.
A bot should be alive enough to be fun, but quiet enough not to become the problem.
The previous social pass gave Mediabot a lot of new personality:
achievements
profiles
radar
dashboard
duels
horoscope
compatibility
quotegame
mood detection
That was powerful, but with power comes the ancient sysadmin wisdom:
Do not annoy the channel.
This update focuses on control, polish, and channel-level tuning.
Two new chansets now help decide what kind of energy a channel wants:
+AchievementAnnounce
+Games
That means the bot can keep the features, but the channel can decide how loud or playful things should be.
Very civilized.
Even by wizard standards.
+AchievementAnnounce: achievements without the confetti stormAchievements are fun.
A channel flooded by achievement unlock messages is not.
So public achievement announcements are now controlled by:
chanset #channel +AchievementAnnounce
When this chanset is enabled, Mediabot can publicly announce unlocks:
π Achievement Unlocked! teuk β π Karma Star
When it is not enabled, achievements still work:
they unlock
they persist
they count
they can be displayed later
metrics still move
They just do not shout in public.
This is the right compromise.
The trophy cabinet still exists. It simply stops falling on peopleβs heads.
+Games: playful commands under channel controlSome commands are naturally playful:
!duel
!horoscope
!compat
!quotegame
They are good for a relaxed channel.
They may be too much for a serious one.
So they are now gated behind:
chanset #channel +Games
The default behavior keeps backward compatibility, but channels can opt out with:
chanset #channel -Games
That gives Mediabot a little more manners.
The gobstones stay available, but they are no longer thrown across every classroom.
!leaderboard: the enchanted scoreboardThis update adds:
!leaderboard
Aliases:
!lb
!top
The command gives a compact multi-category ranking for the current channel:
messages
karma
trivia
duels
achievements
Conceptually:
π
Leaderboard #boulets
π¬ msgs : π₯ teuk π₯ menz π₯ poyan
π karma : π₯ teuk π₯ menz π₯ gwen
π§ trivia : π₯ fantom π₯ teuk π₯ menz
βοΈ duels : π₯ menz π₯ teuk π₯ draco
π achievs : π₯ teuk π₯ menz π₯ poyan
It can also focus on a single category:
!leaderboard karma
!leaderboard trivia
!leaderboard duels
!leaderboard achievs
This is not meant to create war.
Well, not too much war.
It is more like the house points hourglasses: visible, a little competitive, but mostly there because people enjoy watching the sand move.
!chronos: the channel becomes a timelineThis is my favorite part of the pass.
Mediabot can now tell the story of a channel with:
!chronos
Aliases:
!chrono
!timeline
The command builds a narrative timeline from existing data:
first known message
peak day
peak hour
karma leader
trivia champion
quote vault size
latest activity
Conceptually:
π Chronos #boulets β a saga in chapters
π 2007-05-12 Genesis
π 2024-08-13 Peak day
π₯ 23:00 Peak hour
π all-time Karma king
π§ all-time Trivia champion
π all-time Quote vault
π now Last activity
That is more than a statistic.
That is memory with a shape.
IRC channels last for years. Sometimes decades. A command like this makes that history visible again.
It is a Pensieve, but with SQL and less dramatic forehead touching.
CHANSET_LIST is static reference data.
It does not need to be queried over and over like a nervous first-year asking where Potions is.
So getIdChansetList() now has a lazy in-memory cache.
That helps because chansets are checked in several hot paths:
bot messages
achievement announcements
game command gates
channel behavior checks
The cache also stores missing values, so a missing chanset does not cause repeated failed lookups.
Small optimization.
Very useful.
The kind of thing nobody sees, which usually means it was worth doing.
chanset_enabled: less repeated spellcastingA helper was added to make chanset checks clearer:
chanset_enabled($self, $channel, 'Games', default => 1)
Instead of repeating the same pattern everywhere:
get chanset id
check channel setting
decide default
return boolean
That makes the code easier to read and harder to get subtly wrong.
This is the kind of refactor that pays back later.
It turns a repeated incantation into a named charm.
The polyphony achievement is about being active on multiple channels.
It was originally checked from !mood, which worked, but was conceptually wrong.
A multi-channel activity achievement should not depend on someone asking for the channel mood.
So the check moved into the normal message flow:
Achievements::check_msg
with a cache to avoid hammering the database.
That is cleaner.
The achievement now lives where the behavior actually happens.
Good architecture is often just putting the spell in the right classroom.
The schema reference now includes KARMA_LOG, matching the databases where the migration had already been applied.
That matters because the drift checker previously saw KARMA_LOG as an extra DB table.
Now the main install schema and the real databases agree again.
The chanset migrations are idempotent and safe to rerun:
20260603_karma_log.sql
20260604_achievement_announce_chanset.sql
20260604_chansets_mb115_mb118.sql
The new reference data is:
AchievementAnnounce
Games
No destructive schema change was needed.
That is the sort of boring sentence that makes deployment much less scary.
One important thing was discovered while validating the schema drift tooling.
tools/check_schema_drift.pl can still misparse multi-line column definitions in some cases.
The immediate drift is resolved, but the tool itself deserves a future cleanup pass.
Backlog-worthy fixes include:
proper SQL comment header in generated migrations
multi-line column accumulation
reserved-word guardrails
better parsing of COMMENT / DEFAULT / COLLATE / CHARACTER SET
Not urgent for this commit.
But worth fixing soon.
The Sorting Hat has seen the parser and is mildly concerned.
Syntax:
perl -I. -c Mediabot/Helpers.pm
perl -I. -c Mediabot/Achievements.pm
perl -I. -c Mediabot/UserCommands.pm
perl -I. -c Mediabot/Mediabot.pm
perl -I. -c Mediabot/Metrics.pm
perl -I. -c mediabot.pl
git diff --check
Runtime smoke tests:
!leaderboard
!leaderboard karma
!chronos
!achievements
!profil teuk
!dashboard
!mood
!duel SomeNick
!quotegame
!quotegame stop
Chanset behavior:
chanset #i/o -AchievementAnnounce
chanset #i/o +AchievementAnnounce
chanset #i/o -Games
chanset #i/o +Games
Logs to watch:
Undefined subroutine
Incorrect string value
Wide character
SQL error
Use of uninitialized value
Achievements save error
This update is not only about adding more commands.
It is about giving Mediabot better judgment.
A bot that can play games should also know when games are disabled. A bot that can award achievements should not shout every trophy into the room. A bot that remembers a channel should be able to tell its story. A bot that checks settings constantly should do it efficiently.
That is the heart of this pass:
more life
more memory
more control
less noise
Mediabot is still becoming more social.
But now it is also becoming more courteous.
And honestly, that might be the better magic.
ποΈπ‘π―οΈ
You must be logged in to reply.