PulseCaster City¶
Автономная экономика зданий¶
Производственные здания — это точки работы на карте. У них нет владельца, директора, отдельного кошелька, ручного склада, оборудования, производственных заказов или управляемого найма. Вместимость задаётся каталогом здания, а смена всегда запускается с конкретным building_id.
Сырьё и результат принадлежат персонажу:
- при старте смены сырьё на все запланированные этапы переносится из
city_character_inventoryв резерв смены; - завершённый этап погашает соответствующую часть резерва и сразу выдаёт результат персонажу;
- отмена возвращает сырьё только незавершённых этапов;
- зарплата фиксируется при старте смены и начисляется отдельно от произведённого товара.
workhub возвращает все рецепты построенного объекта как постоянные, неограниченные заказы. Для каждого рецепта API показывает расход на один этап (needed_per_stage), количество в инвентаре, выпуск, длительность, диапазон зарплаты и доступные экземпляры здания с их координатами, вместимостью и активными сменами. Клиент пересчитывает полный расход и ожидаемый выпуск при смене выбранной длительности и передаёт выбранный building_id в StartWork.
Производства, парк, кальянная, столовая и ресторан не изнашиваются. Для них не создаются ремонтные заказы. Старые endpoints директоров, контрактов, производственных заказов, объектных продаж, оборудования и рабочих мест отвечают HTTP 410 со статусом economy_model_retired. Read-only карточка автономного здания содержит только карту, рецепты, вместимость, активные смены и рыночную статистику.
Игровой workhub не содержит слоя «Я управляю». Мэрская вкладка служб показывает только больницу и пожарную часть; автономные производства и заведения не возвращаются в её management read model. В административном реестре автономные здания остаются доступными для размещения, перемещения и удаления, но не получают ссылку на объектное управление.
Рынок ресурсов¶
Ресурсный лот создаёт сам персонаж. Выставленное количество изымается из доступного инвентаря в escrow. Цена лота фиксирована его автором; рекомендация рынка её не меняет.
- срок лота — семь суток;
- разрешены частичные покупки и ручная отмена;
- остаток отменённого или истёкшего лота возвращается продавцу;
- общая биржа использует
listing_scope=general; - источник — дом продавца или персональная ячейка ратуши;
- покупка создаёт
city_character_market_deliveries, а не выдаёт предмет сразу; - покупатель получает груз действием
receive, либо другой персонаж доставляет его действиемdeliver.
Рекомендация цены использует реальные продажи и активное предложение. Снимок пересчитывается не чаще раза в пять минут; новое рекомендуемое значение ограничено изменением ±15% от предыдущего. Зарплатный рынок также использует пятиминутный снимок, а конкретная зарплата записывается в смену при старте.
Основная страница рынка работает от всего инвентаря персонажа и больше не делится на «ресурсы» и «прочие предметы». Единственная вкладка «Ресурсы и материалы» объединяет ресурсные и обычные предметные лоты в одной таблице. Материалы создают лот city_resource_market_offers, а остальные разрешённые к торговле предметы — city_market_offers; тип лота клиент выбирает автоматически. На форме размещения явно подписаны товар, количество и цена за штуку; для ресурсов рядом показывается единая сглаженная рекомендация цены и сумма лота. Для совместимости miniapp-resolver принимает как slug/название города, так и числовой channel_id, но клиент всегда передаёт slug.
На рынке персонажа названия вкладок описывают действие игрока:
- «Продажа» содержит форму нового лота, собственные активные и завершённые лоты и золотые заявки мэрии. Золотую заявку можно частично закрыть прямо из подходящего инвентаря без промежуточного лота;
- «Покупка» содержит только активные предложения других продавцов;
- каждая строка показывает начальное количество, остаток и уже проданное количество;
- завершённые лоты имеют статусы
sold,cancelledилиexpired. При истечении обычного предметного лота escrow автоматически возвращается персонажу так же, как у ресурсного лота.
Мэрский рынок использует тот же inventory-first layout. Во вкладке «Покупка» мэрия выкупает лоты жителей только в городской склад. Во вкладке «Продажа» город резервирует ресурс со склада и создаёт публичный семидневный лот. Городская заявка на закупку резервирует бюджет, принимает частичные продажи игроков и всегда складывает купленное на городской склад.
В блоке управления городским складом один выбранный запас можно направить:
- на стройку — создаётся существующий
city_delivery_orders, ресурс резервируется со склада и появляется как работа курьера; - в городской магазин — ресурс сразу переносится в
city_shop_inventory; - на рынок — создаётся новый публичный лот города или пополняется выбранный активный лот.
Витрины столовой и ресторана¶
У заведений нет собственного запаса еды. Повар получает блюдо в свой инвентарь и выставляет его в escrow-витрину конкретного building_id с listing_scope=venue_showcase.
Покупатель выбирает конкретный offer_id:
eatатомарно списывает блюдо, деньги покупателя, налог и начисляет остаток продавцу, затем применяет эффект еды;buy(навынос) выполняет тот же расчёт и выдаёт блюдо в инвентарь покупателя;- отмена или истечение через семь суток возвращает остаток повару.
Столовая принимает canteen_meal, vegetable_soup и sweet_tea. Ресторан принимает только restaurant_meal. Если активных предложений нет, статус заведения возвращает meal_required; системная еда не создаётся.
Статус страницы заведения возвращает building_id, подходящие блюда текущего персонажа в showcase_inventory и те же resource_market_quotes, что использует общий рынок. Клиент показывает форму размещения прямо под витриной посетителя и позволяет снять собственный активный лот.
В пользовательском разделе «Сервисы» столовая и ресторан всегда остаются
доступными как точки входа в витрины, даже если краткий статус временно не
загрузился. Они не возвращаются в управление мэра: руководителей у этих
заведений нет. На странице заведения игрок выбирает конкретный лот повара;
запросы eat и buy обязательно передают его offer_id и building_id.
HTTP API miniapp¶
POST /city/miniapp/channels/{route}/resource-market— выставить общий лот персонажа.POST /city/miniapp/channels/{route}/resource-market/buy— частично или полностью купить общий лот.POST /city/miniapp/channels/{route}/resource-market/cancel— отменить свой лот.GET /city/miniapp/channels/{route}/resource-market/deliveries— покупки в доставке и история получения.POST /city/miniapp/channels/{route}/resource-market/receive— самостоятельно получить доставку.POST /city/miniapp/channels/{route}/resource-market/deliver— доставить покупку курьером.GET /city/miniapp/channels/{route}/services/{slug}/showcase?building_id=...— витрина заведения.POST /city/miniapp/channels/{route}/services/{slug}/showcase/list— выставить блюдо; тело содержитbuilding_id.POST /city/miniapp/channels/{route}/services/{slug}/showcase/cancel— снять собственный витринный лот.POST /city/miniapp/channels/{route}/services/{slug}/eat— съесть предложение; обязательныoffer_idиbuilding_id.POST /city/miniapp/channels/{route}/services/{slug}/takeaway— купить предложение навынос.
Для совместимости POST .../showcase и POST .../buy остаются псевдонимами list и takeaway.
Миграция¶
Миграция 20260727120000_city_autonomous_economy.sql:
- добавляет категорию предмета
material; - переносит старые
city_character_materialsв общий инвентарь через идемпотентный migration ledger; - переносит объектные ресурсы и остатки старых объектных лотов в городской склад, а объектные кошельки — в казну;
- возвращает персонажам результат завершённых этапов и сырьё незавершённых этапов активных старых смен, после чего останавливает эти смены;
- добавляет escrow scopes, семидневные лоты, резервы смен и персональные доставки.
Миграцию необходимо применить до запуска новой версии API.