Osegi
Software·2 min read

Doom Runs Inside a Telegram Message With 1,024-Byte Frames

A developer got Doom playing inside a single Telegram message. The engine runs on a Mac, and each frame must fit in a 1,024-byte bot response.

A tiny low-resolution Doom hangar frame with a door and muzzle flash shown inside a Telegram chat message with six control buttons.
Image: Хабр

A developer has made Doom playable inside a single Telegram message. The engine stays on his Mac, while the chat shows only a small image and six buttons: forward, back, turn left, turn right, fire and open door.

Pressing a button makes the widget call TelegramWidget.request("right"), for example. The bot finds the player's session and passes the input to ViZDoom, which advances the simulation by five ticks. Players turn, enemies move and projectiles fly, then the world freezes again. The bot grabs the frame from the screen buffer and returns it through answerWidgetQuery, and the widget swaps the image source in the same element, so the chat keeps just one game message even after dozens of moves.

The 1,024-byte limit

ViZDoom outputs a 320 × 200 RGB frame, which is 192,000 bytes uncompressed. The whole response must fit in 1,024 bytes and carry the image as a Base64 string. Since every three bytes become four characters, the WebP itself can be at most 768 bytes.

The author keeps WebP quality constant and varies resolution per frame. He tries a width of 120 pixels first, then 96, 80, 64, 48 and 32, scaling height proportionally. The size check runs on the final encoded string, so an empty wall and a room with an enemy may arrive at different resolutions. Distant enemies are hard to make out, but you can open a door and see who is behind it. The widget ignores new presses while a reply is in flight, with at least 1,010 ms between requests. Because the world is turn-based, monsters do not close in during the wait.

Testing and setup

In Telegram for macOS, the author checked the route from the starting room to the door, turning and shooting. He ran the full level separately in local ViZDoom with the same six buttons and five ticks per move: reaching the exit switch took 537 moves, ending with 48% health and six enemies killed.

Running it yourself requires Python 3.12, your own bot token and the original DOOM1.WAD from Doom Shareware 1.9, which is not included in the repository. The path is set through DOOM_WAD. The game bot holds up to six sessions and frees them after ten minutes of inactivity.

The project grew into Awesome Telegram Widgets. The @awesomewidget_bot offers Doom, turn-based Pacman, a calculator, a demo weather forecast, route selection and demo mail, with categories, search and links to each original project. Developers can submit their own widgets to the catalog.

Apps worth a look

SUMO: the number puzzle

Tap the right tiles, add them up, hit the target. Easy to learn, hard to master. Free, for all ages.

Tags:doomtelegramvizdoomtelegram widgetswebpbots

More from this day

See all →

More in: Software

See all →