The post has been translated automatically. Original language: Russian
When people talk about Flutter, they most often represent mobile applications: online stores, banking services, or corporate systems. But I was wondering if Flutter could be used for a completely different task — to write my own visual novel engine.
Let me clarify right away: the goal was not to create one game, but to make a universal engine that can run different stories without changing the application code.
Of course, there are ready-made solutions like Ren'Py, Unity or Godot. But this project appeared more out of curiosity. I wanted to check how well Flutter is suitable for tasks that are not usually associated with mobile development.
The main idea was to completely separate the code from the content. The entire story is stored in a JSON file, and the application only reads it and performs the described actions: shows the background, characters, dialogues, plays music, offers a choice to the player and performs transitions between scenes.
This approach allows you to add new stories without changing the application logic.
During development, it became clear that Flutter does a good job not only with creating familiar applications. The declarative approach allows you to conveniently manage the state of game screens, and support for Android, iOS, Web, and Desktop makes it possible to run the same engine virtually unchanged.
Of course, Flutter will not replace game engines for projects with complex graphics or physics. But if the game is built around an interface, script, and logic, it turns out to be quite a suitable tool.
Now the engine already supports the display of scenes, dialogues, player selections, music, and a save system. In the future, it is planned to add variables, conditions, animations, and a script editor that will allow you to create new stories without having to write code.
Conclusion
For me, this project was an opportunity to look at Flutter from a different perspective. Instead of the usual application, a small game engine turned out, which helped to understand more deeply the architecture, working with the state and organization of data.
Sometimes it is such experiments that allow you to discover new features of familiar tools. And Flutter, as this project has shown, is suitable not only for creating mobile applications.
FLUTTER_VISUAL_NOVEL
│
├── assets/
,── backgrounds/ // Backgrounds of scenes
│ ├── characters/ // Character Sprites
│ ├── musics/ // Musical accompaniment
│ └── scripts/ // JSON scripts for short stories
│
├── common/ // Common Application components
│ ├── config/
│ ├── data/
│ └── presentation/
│
├── features/
│ └── novel/
│ ├── domain/ // Game models and logic
,── presentation/ // UI and Cubit
│ └── novel_screen.dart
│
start/ // Start and save screen
│
main.dart // Application entry point
The JSON contains the entire story: chapters, scenes, dialogues, characters, music, and player selections.
The Repository reads the script and converts it into application models.
NovelCubit manages the state of the game: tracks the current scene, performs actions, and handles transitions.
The UI only displays the current state — it shows the background, characters, text, and choices.
It was this separation that made it possible to make the engine universal. To add a new story, just create a new JSON script and the necessary resources in the assets folder. The logic of the application remains unchanged.

Когда говорят о Flutter, чаще всего представляют мобильные приложения: интернет-магазины, банковские сервисы или корпоративные системы. Но мне стало интересно, можно ли использовать Flutter для совершенно другой задачи — написать собственный движок визуальных новелл.
Сразу уточню: целью было не создать одну игру, а сделать универсальный движок, который сможет запускать разные истории без изменения кода приложения.
Конечно, существуют готовые решения вроде Ren'Py, Unity или Godot. Но этот проект появился скорее из любопытства. Хотелось проверить, насколько Flutter подходит для задач, которые обычно не ассоциируются с мобильной разработкой.
Основная идея заключалась в том, чтобы полностью отделить код от контента. Вся история хранится в JSON-файле, а приложение лишь читает его и выполняет описанные действия: показывает фон, персонажей, диалоги, воспроизводит музыку, предлагает выбор игроку и выполняет переходы между сценами.
Такой подход позволяет добавлять новые истории без изменения логики приложения.
Во время разработки стало понятно, что Flutter хорошо справляется не только с созданием привычных приложений. Декларативный подход позволяет удобно управлять состоянием игровых экранов, а поддержка Android, iOS, Web и Desktop дает возможность запускать один и тот же движок практически без изменений.
Конечно, Flutter не заменит игровые движки для проектов со сложной графикой или физикой. Но если игра строится вокруг интерфейса, сценария и логики, он оказывается вполне подходящим инструментом.
Сейчас движок уже поддерживает отображение сцен, диалоги, выборы игрока, музыку и систему сохранений. В дальнейшем планируется добавить переменные, условия, анимации и редактор сценариев, который позволит создавать новые истории без необходимости писать код.
Заключение
Для меня этот проект стал возможностью взглянуть на Flutter с другой стороны. Вместо привычного приложения получился небольшой игровой движок, который помог глубже разобраться в архитектуре, работе с состоянием и организации данных.
Иногда именно такие эксперименты позволяют открыть для себя новые возможности знакомых инструментов. И Flutter, как показал этот проект, подходит не только для создания мобильных приложений.
FLUTTER_VISUAL_NOVEL
│
├── assets/
│ ├── backgrounds/ // Фоны сцен
│ ├── characters/ // Спрайты персонажей
│ ├── musics/ // Музыкальное сопровождение
│ └── scripts/ // JSON-сценарии новелл
│
├── common/ // Общие компоненты приложения
│ ├── config/
│ ├── data/
│ └── presentation/
│
├── features/
│ └── novel/
│ ├── domain/ // Игровые модели и логика
│ ├── presentation/ // UI и Cubit
│ └── novel_screen.dart
│
├── start/ // Экран запуска и сохранений
│
└── main.dart // Точка входа приложения
JSON содержит всю историю: главы, сцены, диалоги, персонажей, музыку и выборы игрока.
Repository считывает сценарий и преобразует его в модели приложения.
NovelCubit управляет состоянием игры: отслеживает текущую сцену, выполняет действия и обрабатывает переходы.
UI только отображает текущее состояние — показывает фон, персонажей, текст и варианты выбора.
Именно такое разделение позволило сделать движок универсальным. Чтобы добавить новую историю, достаточно создать новый JSON-сценарий и необходимые ресурсы в папке assets. Логика приложения при этом остается неизменной.
