Skip to content
All posts
3 min read

Teaching the bot taste

The thumbnail bot keeps a per-game art direction, drafts its own lessons from my rejections, and learns nothing until I approve it. Taste should be a ratchet, not a drift.

AIGames

On Roblox, the thumbnail is most of the pitch. A player scrolls a grid, and a title like Craft Your Brainrot gets one small rectangle to explain itself; the distance between a click and a scroll-past is art direction. We built a Discord bot that generates those rectangles with an image model, and the interesting problem turned out not to be generation at all. It was memory.

A raw image model has no idea what I approved last week. Left alone, every generation starts from zero taste and regresses toward the same glossy median every other game on the platform regresses toward. So the bot keeps, per game, an art direction: a living text description of what this game's art is. Palette, energy, what the character is doing, what never appears. Every generation reads it before it draws. Editing that text is editing the bot's taste directly, and a good result has a save-to-art-direction button for exactly that reason: when something accidentally lands, the landing gets written down.

Rejection is the other input, and it is not allowed to be a shrug. Rejecting a thumbnail asks for a note, and the note works twice: it steers the retry immediately, and the system distills accumulated notes into proposed learnings. Proposed is the load-bearing word. The bot drafts what it thinks it should remember, and nothing enters the art direction until I review the proposal and apply it. There is a propose and apply screen whose entire job is this. The bot writes its own lessons; I grade them; only graded lessons persist.

References close the loop from the other side. A regeneration can carry reference images, the approved winners, so that more like this is a literal instruction instead of a vibe. The winners live in an asset manager built around buckets, uploadable in bulk and shareable across games, because a studio's characters and props recur and taste should not be re-explained to the model per title. And because a game needs a family of assets, wide thumbnails and square icons with their own subtypes, the taste has to survive the crop: per-ratio configuration exists so the same direction renders correctly at every shape the platform demands.

Volume is where all of this pays. Once a game's direction is dialed in, bulk generation becomes safe: ask for a batch of candidates and cherry-pick, because every candidate already starts from the accumulated taste instead of from zero. Before the memory existed, more generations just meant more variance. After it, more generations mean more chances within a style. That inversion is the entire feature.

Here is the opinion baked into the architecture: I do not want this system to self-improve. I want it to improve when told. Unsupervised improvement in a taste system is drift with good PR, the model optimizing toward its own idea of better, which is everyone's idea of better, which is nobody's. A taste system should behave like a ratchet: it holds position until a person turns it, and then it holds the new position just as stubbornly.

Art direction turned out to be a save file for taste. The bot reads it more faithfully than I read my own intentions, which is the point. Consistency was always the hard half of taste. Consistency is the half machines are good at.

Remiel Shirazi

CTO & Co-founder | AI, Roblox & Piano