Консольная narrative-игра на Python с модульной архитектурой, внешним хранением сценарного контента в JSON, системой состояний игрока и несколькими концовками, зависящими от принятых решений.
Этот проект начинался как учебная текстовая игра, а затем был переработан в более чистое и структурированное Python-приложение.
Главная цель переработки:
- разделить монолитный скрипт на отдельные модули;
- вынести сценарный контент из кода в JSON;
- централизованно хранить состояние игры;
- сделать проект удобнее для поддержки, расширения и публикации как pet-project.
В игре пользователь проходит несколько миров-испытаний, принимает решения, использует предметы, получает достижения и приходит к одной из нескольких концовок в зависимости от накопленного состояния.
- модульная структура проекта;
- отдельный игровой цикл;
- централизованное состояние игры через
GameState; - хранение сценарного контента во внешних JSON-файлах;
- система инвентаря;
- система достижений;
- логирование прохождения в
gameplay.txt; - несколько игровых миров с разной логикой;
- несколько концовок, зависящих от поведения игрока;
- на первом уровне сложности игроку дается "амулет" на каждый мир, что позволяет переигрывать события без потери набранных характеристик, вследствие чего выходить на некоторые концовки;
- количество неправильно введенных ответов не сбрасывается после получения 1 правильного, так как дает достижение;
- Python 3
dataclassesjsonpathlib
Проект не использует сторонние библиотеки и запускается на стандартном Python.
project/
├── main.py
├── engine.py
├── models.py
├── logger.py
├── inventory.py
├── content_loader.py
├── worlds/
│ ├── miroh.py
│ ├── noeasy.py
│ └── star.py
├── content/
│ ├── engine.json
│ ├── miroh.json
│ ├── noeasy.json
│ └── star.json
└── gameplay.txt
main.py— точка входа в приложение;engine.py— основной игровой цикл и логика определения концовки;models.py— модель состояния игры и значения по умолчанию;logger.py— вывод текста в консоль и запись прохождения в лог-файл;inventory.py— логика работы с инвентарём и амулетом;content_loader.py— загрузка JSON-контента;worlds/*.py— логика отдельных миров;content/*.json— внешний сценарный контент.
В начале игры пользователь выбирает уровень сложности.
От выбранной сложности зависит стартовый инвентарь.
- 1 —
фонарик,компас,амулет - 2 —
фонарик,компас - 3 —
фонарик
После этого игрок попадает в SKZ Verse и может проходить миры в произвольном порядке.
Мир городского лабиринта, где нужно:
- выбирать действия в опасных ситуациях;
- взаимодействовать с роботом;
- искать правильный маршрут;
- использовать предметы из инвентаря.
Мир шума и слов, где прохождение строится на ответах игрока:
- выбор ответов влияет на внутренние характеристики;
- учитываются грубость и доброжелательность;
- результат прохождения зависит не только от “правильности”, но и от стиля поведения.
Сценическое испытание, где игрок:
- выбирает стиль подготовки;
- принимает решения во время выступления;
- набирает условные “звёзды” за действия.
Состояние игрока хранится централизованно и обновляется по мере прохождения.
Хранятся:
- количество ошибок ввода;
- количество “сбросов” после неправильного ввода;
- уровень грубости;
- уровень доброжелательности;
- выбранная сложность;
- количество использований амулета;
- количество “лишних” использований амулета;
- текущий инвентарь;
- полученные достижения;
- символы успешно пройденных миров.
Такой подход позволяет:
- определять концовку по накопленным действиям;
- хранить важные игровые показатели в одном месте;
- легче расширять проект новыми механиками.
Во время прохождения игра записывает события в файл gameplay.txt.
Это полезно для:
- анализа сценарных веток;
- отладки;
- проверки прохождения;
- просмотра истории конкретной игровой сессии.
Перед запуском новой игры лог очищается, а состояние игры сбрасывается.
Итоговая концовка зависит от совокупности факторов:
- сколько миров было успешно пройдено;
- как часто использовался амулет;
- насколько доброжелательно или грубо вёл себя игрок;
- сколько символов миров удалось собрать.
Таким образом, игра использует не одну линейную проверку, а набор накопленных условий, формирующих результат прохождения.
Изначально проект был реализован как один большой файл.
В переработанной версии были сделаны следующие улучшения:
- код разделён на отдельные модули;
- текстовый контент вынесен в JSON;
- игровое состояние выделено в отдельную модель;
- логика инвентаря вынесена отдельно;
- логирование оформлено в отдельном модуле;
- структура проекта стала чище и понятнее;
- проект стал лучше подходить для дальнейшего рефакторинга и расширения.
git clone <repo_url>cd <repo_name>python main.py- Python 3.10+
или другая современная версия Python 3 с поддержкойdataclassesи type hints.
Возможные направления для развития проекта:
- добавить автотесты для ключевых игровых механик;
- снизить зависимость логики от глобального состояния;
- улучшить обработку ошибок при загрузке JSON;
- вынести больше игровых правил в данные, а не в код;
- добавить сохранения/загрузки прохождения;
- сделать проект более универсальным как основу для других текстовых игр.
С технической точки зрения это pet-project про:
- декомпозицию Python-кода;
- отделение данных от логики;
- организацию модульного консольного приложения;
- хранение состояния приложения;
- работу с пользовательским вводом;
- рефакторинг учебного проекта в более чистую архитектуру.
Никита Мальков