В процессе тестирования выявил и исправил пару небольших багов, а также сделал некоторые корректировки параметров.
1. При рождении нового поселенца значения BirthPoints на экране города становились отрицательными. Через пару ходов все устаканивалось, но такого быть не может, так как значения BirthPoints не могут быть отрицательными по определению, ибо они привязаны к количеству потребляемой поселенцем еды.
Это происходило из-за того, что в CvCity.cpp на момент перехода расчет велся так:
Код:
setBirthPoints(iGrowthThreshold - iBirthPoints);
а должно было быть так:
Код:
setBirthPoints(iBirthPoints - iGrowthThreshold);
В таком виде все работает правильно.
2. Второй баг, уже в CvMainInterface.py, я создал сам, когда убрал в подсказку количество товаров на складе и его максимальную вместимость и оставил на экране только прирост наполняемости склада за ход (iProdusedYield).
Все работало нормально до того момента, пока значения были iProdusedYield > 0 или iProdusedYield < 0. Но в ситуации, когда iProdusedYield = 0, значок склада с экрана просто исчезал. Для исправления этого я добавил в CvMainInterface.py строку с "else"
Код:
if iProdusedYield > 0:
szBuffer += u"+" + u"%i%c" % (iProdusedYield, CyGame().getSymbolID(FontSymbols.BAD_GOLD_CHAR)) + u"</font>"
elif iProdusedYield < 0:
szBuffer += u"%i%c" % (iProdusedYield, CyGame().getSymbolID(FontSymbols.BAD_GOLD_CHAR)) + u"</font>"
else:
szBuffer += u"%i%c" % (iProdusedYield, CyGame().getSymbolID(FontSymbols.BAD_GOLD_CHAR)) + u"</font>" #KJ addon if "iProdusedYield = 0"
Так все работает правильно.
"BAD_GOLD_CHAR" пусть не смущает, так как в GameFont.tga значок склада я поместил вместо значка BAD_GOLD_CHAR, который в игре нигде не используется.
3. Удлинил до 10 ходов предупреждение о скором переполнении городского склада. Теперь в CvMainInterface.py это выглядит так:
Код:
elif iTotalYield + (10 * iProdusedYield) > iMaxYield: #"10 turns's alarm before Max Storage capacity"
szBuffer += u"255,255,0" #yellow
Как и было сделано VET'ом в оригинале, цифры перед значком склада меняют цвет с зеленого на желтый, но желтыми они становятся за 10, а не за 2 хода до возможного переполнения склада. Из-за обилия информации я частенько упускал этот момент и склад оказывался набит до предела.
Теперь несколько замечаний по вновь введенным параметрам.
4. Неприкосновенный запас продовольствия, задаваемый через
Код:
<DefineName>TURNS_FOR_FOOD</DefineName>
<iDefineIntVal>12</iDefineIntVal>
При скорости игры 1 ход = 1 месяц мы имеем годовой запас продуктов питания. Очень разумно. Если память мне не изменяет, то в СССР был 90 дневный неприкосновенный запас продовольствия. Тут же годовой. Так что мы имеем вполне соизмеримые величины.
5. Как показывает практика городской склад (BUILDING_WAREHOUSE) не является тем зданием, которое строится самым первым. Ни игрок, ни тем более AI, не начинают стоить склад сразу.
Это означает, что при нормальной скорости игры на самом первом ходу в городе может храниться только 100 единиц товара. Честно сказать, я не знаю откуда идет эта цифра, ведь склада в городе на самом первом ходу пока нет, а BUILDING_TOWNHALL, который есть по дефолту, имеет
Код:
<iYieldStorage>0</iYieldStorage>
Другие доступные по дефолту здания тоже. Возможно эта сотня где-то прописана в исходных кодах, но, признаюсь, я специально не искал. Это не важно, просто примем эту сотню как данность. Итак, на самом первом ходу в городе может храниться не более 100 единиц товара.
А теперь представим ситуацию, когда город основан юнитом, имеющим профессию "Драгун" (PROFESSION_DRAGOON). Согласно CIV4ProfessionInfos.xml в экипировку этого юнита входят:
Код:
<YieldEquipedNums>
<YieldEquipedNum>
<YieldType>YIELD_HORSES</YieldType>
<iYieldAmount>50</iYieldAmount>
</YieldEquipedNum>
<YieldEquipedNum>
<YieldType>YIELD_MUSKETS</YieldType>
<iYieldAmount>50</iYieldAmount>
</YieldEquipedNum>
</YieldEquipedNums>
То есть уже в момент основания все доступные в городе 100 единиц будут сразу же заполнены. Любой товар, что будет производиться в городе или собираться на клетках вокруг него, моментально будет подпадать под возможные сокращения.
Для исправления этой ситуациидля в BUILDING_WAREHOUSE я ввел
Код:
<iYieldStorage>100</iYieldStorage>
Таким образом, сейчас при нормальной скорости получается суммарная вместимость города (без еще не построенного склада!) равна 100 + 100 = 200, то есть в 2 раза больше прежней. В этом случае даже при создании города драгуном не происходит моментального переполения еще не построенного "склада".
Соответственно в сторону повышения скорректированы и значения для BUILDING_WAREHOUSE
Код:
<iYieldStorage>900</iYieldStorage>
вместо
Код:
<iYieldStorage>100</iYieldStorage>
и для расширенного склада (BUILDING_WAREHOUSE_EXPANSION), где сейчас
Код:
<iYieldStorage>1500</iYieldStorage>
вместо
Код:
<iYieldStorage>200</iYieldStorage>
Эти изменения абсолютно необходимы, так как сейчас заполненность склада считается как сумма всех товаров, что хранятся в городе, а не отдельно по каждой из позиций, как это было в оригинальной игре.
6. Максимальное значение BirthPoints, при котором рождается новый колонист. В самом начале это значение было равно 200:
Код:
<DefineName>BASE_BIRTH_POINTS_THRESHOLD</DefineName>
<iDefineIntVal>200</iDefineIntVal>
Но насколько оно оптимально?
Для ответа на этот вопрос надо совершить небольшой экскурс в историю и демографию.
Как известно, рост населения в любом городе определяется четырьмя слагаемыми.
- рождаемость,
- смертность,
- иммиграция (в город)
- эмиграция (из города).
Таким образом,
Прирост населения = (Рождаемость - Смертность) + (Иммиграция - Эмиграция).
В первых скобках - естественный прирост населения, во вторых - искусственный (или механический).
В данном моде мы не разделяем по отдельности "Рождаемость" и "Смертность". Введенный параметер "BirthPoints" нужно рассматривать как естественный прирост населения, то есть как (Рождаемость - Смертность).
Безусловно, оба эти значения можно развести и параллельно с "BirthPoints" ввести "DeathPoints". Но тогда в какой-то момент, когда набирается некое количество "DeathPoints", нужно убивать одного из жителей города. Причем в обязательном порядке! Это неприятно и вряд ли будет приемлемо играющими, так как сейчас все юниты практически бессмертны. По крайней мере до тех пор, пока не началась война с туземцами или соседями-европейцами.
Поэтому "Смертность" проще ввести через генерацию случайных событий. К примеру, в густонаселенном городе (более 8 или 10 жителей) с вероятностью Х% вспыхивает эпидемия. Если в городе нет доступа к чистой воде (родник), или нет госпиталя, или лекарств, то тогда с очень высокой вероятностью один из жителей умирает. Если все вышеперечисленное есть, то город в период эпидемии ничего не производит и все заканчивается без потерь для игрока.
Мне кажется, что такое решение намного проще, чем введение параметра DeathPoints. Вероятностное событие может произойти, а может и не произойти. Тут все зависит от самого игрока.
Итак, мы имеем два компонента, ответственных за прирост населения города - естественный и искусственный.
Если изучить динамику роста городов в Новом Свете в период колонизации, то станет совершенно очевидно, что в первые как минимум 100 лет преобладающим механизмом был "искусственный" рост населения за счет:
- иммигрантов из Европы (в самом начале игры мы их постоянно возим из Европы),
- рабов из Африки (в данном моде отсутствуют, но они уже есть в "1492: Slavery Market. The Orient. Port-Royal"),
- захваченных или присоединившихся к европейцам местных аборигенов (в нашем случае, это UNIT_CONVERTED_NATIVE).
Кстати, массовый завоз рабов из Африки как раз и был связан с отсутствием необходимой рабочей силы во вновь основанных городах и в особенности на плантациях Нового Света.
То есть другими словами, параметр BASE_BIRTH_POINTS_THRESHOLD мы должны задать таким, чтобы в течение очень длительного периода времени население города не могло увеличиваться. Если оставить его равным 200, то новый житель в нем появится через 100 ходов. Считаем 1 ход = 1 месяц, получаем 100 месяцев или 100 : 12 = чуть больше 8 лет. Лично мне кажется, что это очень быстро.
Безусловно, увеличив BASE_BIRTH_POINTS_THRESHOLD до 300 или даже 500, мы получим более приемлемые значения. По крайней мере более правильные с исторической точки зрения. Поэтому моя рекомендация - использовать параметр BASE_BIRTH_POINTS_THRESHOLD с очень большим значением. Впрочем, это дело вкуса каждого из игроков и любой вправе поменять его сам. Параметр BASE_BIRTH_POINTS_THRESHOLD выведен в GlobalDefinesAlt.xml и его очень просто отредактировать.
Других изменений, за исключением незаконченного пока редактирования текстовых файлов, я не делал. Сейчас я правлю статьи с CONCEPT_FOOD, CONCEPT_NEW_STORAGE и CONCEPT_POPULATION_GROWTH.
Если мне ничего не помешает, то к концу этой недели мод "BirthPoints_and_NewCapacity" будет готов для публикации и представления игрокам.
Предлагаю его переименовать и назвать к примеру "New Colonists" ("Новые колонисты"). При этом в описании указать, что в данном моде изменена логика генерации новых поселенцев. Новый колонист (см. предлагаемый вариант названия мода) появляется не в результате накопления еды, а как следствия набора "очков рождаемости" всеми жителями данного города. Плюс естественно описать радикальные изменения, произведенные с городским складом.
Если новое название приемлемо, то тогда заставка твоего мода может выглядеть например так:

Да, и последнее. При довольно продолжительном тестовом прогоне я открыл карту и видел, что и как делают мои европейские оппоненты и местные аборигены. Сразу же хочу сказать, что их поведение меня порадовало. Никто из них тупо не гнался за увеличением запасов еды. Все были заняты сбором или производством чего-то своего, имея при этом гарантированный запас продовольствия, который обеспечивал постоянный набор "очков рождаемости". И самое главное, это происходило независимо от того, что они делали в городе или на клетках вокруг города. Города росли не быстро, первоначально их рост происходил за счет прибытия новых колонистов из Европы, затем же они стали сами источниками новых поселенцев, которые постепенно расселялись по карте. Лично мне такое поведение очень даже понравилось.