How a Telegram Bot Brief Turned Into an MMORPG
A custom Telegram bot grew into a real game server: separate worlds per chat, PvP classes, an economy, and 400+ tests behind a one-tap interface.
A client came to me with a deceptively simple brief: “I want a full MMORPG inside a Telegram chat.”
Not a Mini App. Not a website. Not /start followed by five buttons.
Players needed characters, classes, abilities, resources, inventories, quests, and ways to affect one another.
It sounded like a good challenge, so I took it on.
Very quickly, though, it became clear that we were not building a bot. We were building a compact game server with Telegram as its client.
Every chat became its own game world
The first important decision was simple:
user_id + chat_id = one game character
The same person can be a vampire in one chat and a human in another, with different balance, inventory, and progress in each. Every Telegram chat is its own world.
The real heat arrived with classes and abilities. A player taps a button and expects to use an ability on another player.
In a fraction of a second, the system has to check:
- the player's class;
- whether the ability is available;
- the required resource;
- the cooldown;
- the target's state;
- defensive effects;
- other constraints;
- update both players' states;
- persist the long-lived data;
- refresh the cache;
- and, when needed, schedule a timer or notification.
To the player, it is just tap → result. That is exactly how it should feel.
Telegram became the game client's interface
Over time, Telegram stopped being “just a bot.”
- Messages became game events.
- Inline buttons became the interface.
- The finite-state machine became a sequence of game actions.
- PostgreSQL became the world's durable memory.
- Redis held the fast-moving state: cooldowns, effects, and cache.
The game rules moved into dedicated services, because nobody wants thousands of lines of if statements trapped inside Telegram handlers.
The economy was the hard part
Adding currency is easy. Keeping an economy in balance is not.
Once classes, items, resources, rewards, quests, and constraints enter the picture, changing one mechanic starts changing five others.
Too many rewards and the economy loses meaning. Too few and players lose motivation. A single new item can break an entire class.
Then came testing:
- an ability combined with an item;
- an ability combined with an effect;
- two players acting at once;
- a resource running out mid-action;
- stale state left in Redis;
- a player pressing an old button.
Each mechanic can work perfectly in isolation. The bugs live at the intersections.
The project eventually grew to roughly 15,000 lines of Python and more than 400 tests.
The point where the conversation became about the game
Then came the first major beta test.
I expected a list of broken flows and architectural rewrites. Instead, most of the feedback sounded like: “change this text,” “tweak this mechanic,” “word this differently.”
We were no longer discussing the system. We were discussing the game.
The result included:
- five character classes;
- PvP and abilities;
- inventory and items;
- quests;
- resources and cooldowns;
- an in-game economy;
- temporary effects;
- notifications;
- a separate world for every chat;
- and a web-based admin panel.
Under the hood: Python, Aiogram, PostgreSQL, Redis, and FastAPI.
The project went live. A few weeks later, the client came back — not with fixes, but with a new project. For custom development, that is one of the best quality signals there is.
But the lasting lesson was a different one.
At first, I thought we were squeezing an MMORPG into Telegram.
It turned out to be the reverse. We took what Telegram already has — people, groups, conversation, reactions, competition, and continuous social interaction — and made those things part of the game mechanics.
Telegram was not a limitation. It became part of the game engine.