Enhance school creation functionality by introducing support for name sets in the API and UI. Update the catalog to include skills, traits, body attributes, needs, and name sets, improving character generation capabilities. Revise localization strings for better user guidance and update tests to validate the new name set functionality and ensure robustness in school creation processes.
ci / server (push) Failing after 3m45s
ci / client (push) Successful in 17s

This commit is contained in:
Leonid Pershin
2026-08-18 18:57:01 +03:00
parent 38afbcad36
commit e6182e0e45
56 changed files with 3706 additions and 9 deletions
@@ -0,0 +1,11 @@
{
"defName": "EyeColor",
"kind": "choice",
"options": [
{ "value": "BrownEyes", "weight": 40 },
{ "value": "BlueEyes", "weight": 20 },
{ "value": "GrayEyes", "weight": 20 },
{ "value": "GreenEyes", "weight": 12 },
{ "value": "HazelEyes", "weight": 8 },
],
}
@@ -0,0 +1,11 @@
{
"defName": "HairColor",
"kind": "choice",
"options": [
{ "value": "BlackHair", "weight": 25 },
{ "value": "BrownHair", "weight": 40 },
{ "value": "BlondHair", "weight": 20 },
{ "value": "RedHair", "weight": 8 },
{ "value": "GrayHair", "weight": 2, "ageMin": 40 },
],
}
@@ -0,0 +1,14 @@
{
"defName": "Height",
"kind": "number",
"distributions": [
{ "sex": "male", "ageMin": 6, "ageMax": 9, "distribution": { "mean": 128, "stdDev": 6 }, "range": { "min": 110, "max": 150 } },
{ "sex": "male", "ageMin": 10, "ageMax": 13, "distribution": { "mean": 150, "stdDev": 8 }, "range": { "min": 128, "max": 175 } },
{ "sex": "male", "ageMin": 14, "ageMax": 17, "distribution": { "mean": 172, "stdDev": 8 }, "range": { "min": 150, "max": 195 } },
{ "sex": "male", "ageMin": 18, "distribution": { "mean": 176, "stdDev": 7 }, "range": { "min": 155, "max": 205 } },
{ "sex": "female", "ageMin": 6, "ageMax": 9, "distribution": { "mean": 127, "stdDev": 6 }, "range": { "min": 108, "max": 148 } },
{ "sex": "female", "ageMin": 10, "ageMax": 13, "distribution": { "mean": 148, "stdDev": 7 }, "range": { "min": 128, "max": 170 } },
{ "sex": "female", "ageMin": 14, "ageMax": 17, "distribution": { "mean": 163, "stdDev": 6 }, "range": { "min": 145, "max": 185 } },
{ "sex": "female", "ageMin": 18, "distribution": { "mean": 164, "stdDev": 6 }, "range": { "min": 145, "max": 190 } },
],
}
@@ -0,0 +1,14 @@
{
"defName": "Weight",
"kind": "number",
"distributions": [
{ "sex": "male", "ageMin": 6, "ageMax": 9, "distribution": { "mean": 27, "stdDev": 5 }, "range": { "min": 16, "max": 45 } },
{ "sex": "male", "ageMin": 10, "ageMax": 13, "distribution": { "mean": 42, "stdDev": 8 }, "range": { "min": 25, "max": 70 } },
{ "sex": "male", "ageMin": 14, "ageMax": 17, "distribution": { "mean": 62, "stdDev": 10 }, "range": { "min": 40, "max": 95 } },
{ "sex": "male", "ageMin": 18, "distribution": { "mean": 78, "stdDev": 12 }, "range": { "min": 50, "max": 130 } },
{ "sex": "female", "ageMin": 6, "ageMax": 9, "distribution": { "mean": 26, "stdDev": 5 }, "range": { "min": 15, "max": 44 } },
{ "sex": "female", "ageMin": 10, "ageMax": 13, "distribution": { "mean": 42, "stdDev": 8 }, "range": { "min": 24, "max": 70 } },
{ "sex": "female", "ageMin": 14, "ageMax": 17, "distribution": { "mean": 54, "stdDev": 8 }, "range": { "min": 38, "max": 85 } },
{ "sex": "female", "ageMin": 18, "distribution": { "mean": 62, "stdDev": 10 }, "range": { "min": 42, "max": 110 } },
],
}
@@ -0,0 +1,131 @@
{
"defName": "Slavic",
"patronymicRule": "slavic",
"defaultGivenDeclension": "hard",
"defaultSurnameDeclension": "ov",
"maleGiven": [
{ "form": "Александр" },
{ "form": "Алексей" },
{ "form": "Андрей" },
{ "form": "Антон" },
{ "form": "Артём" },
{ "form": "Борис" },
{ "form": "Вадим" },
{ "form": "Валерий" },
{ "form": "Виктор" },
{ "form": "Виталий" },
{ "form": "Владимир" },
{ "form": "Владислав" },
{ "form": "Григорий" },
{ "form": "Денис" },
{ "form": "Дмитрий" },
{ "form": "Евгений" },
{ "form": "Егор" },
{ "form": "Иван" },
{ "form": "Игорь", "declension": "soft" },
{ "form": "Илья", "declension": "ya" },
{ "form": "Кирилл" },
{ "form": "Константин" },
{ "form": "Максим" },
{ "form": "Михаил" },
{ "form": "Никита", "declension": "a" },
{ "form": "Николай" },
{ "form": "Олег" },
{ "form": "Павел" },
{ "form": "Пётр" },
{ "form": "Роман" },
{ "form": "Сергей" },
{ "form": "Станислав" },
{ "form": "Степан" },
{ "form": "Фёдор" },
{ "form": "Юрий" },
],
"femaleGiven": [
{ "form": "Александра", "declension": "a" },
{ "form": "Алина", "declension": "a" },
{ "form": "Анастасия", "declension": "iya" },
{ "form": "Анна", "declension": "a" },
{ "form": "Валентина", "declension": "a" },
{ "form": "Валерия", "declension": "iya" },
{ "form": "Вера", "declension": "a" },
{ "form": "Виктория", "declension": "iya" },
{ "form": "Дарья", "declension": "ya" },
{ "form": "Екатерина", "declension": "a" },
{ "form": "Елена", "declension": "a" },
{ "form": "Елизавета", "declension": "a" },
{ "form": "Ирина", "declension": "a" },
{ "form": "Ксения", "declension": "iya" },
{
"form": "Любовь",
"cases": {
"nom": "Любовь",
"gen": "Любови",
"dat": "Любови",
"acc": "Любовь",
"ins": "Любовью",
"pre": "Любови",
},
},
{ "form": "Людмила", "declension": "a" },
{ "form": "Маргарита", "declension": "a" },
{ "form": "Мария", "declension": "iya" },
{ "form": "Надежда", "declension": "a" },
{ "form": "Наталья", "declension": "ya" },
{ "form": "Нина", "declension": "a" },
{ "form": "Оксана", "declension": "a" },
{ "form": "Ольга", "declension": "a" },
{ "form": "Полина", "declension": "a" },
{ "form": "Светлана", "declension": "a" },
{ "form": "София", "declension": "iya" },
{ "form": "Татьяна", "declension": "a" },
{ "form": "Юлия", "declension": "iya" },
{ "form": "Яна", "declension": "a" },
{ "form": "Вероника", "declension": "a" },
{ "form": "Диана", "declension": "a" },
{ "form": "Марина", "declension": "a" },
],
"surnames": [
{ "male": "Иванов", "female": "Иванова" },
{ "male": "Петров", "female": "Петрова" },
{ "male": "Смирнов", "female": "Смирнова" },
{ "male": "Кузнецов", "female": "Кузнецова" },
{ "male": "Попов", "female": "Попова" },
{ "male": "Васильев", "female": "Васильева" },
{ "male": "Соколов", "female": "Соколова" },
{ "male": "Михайлов", "female": "Михайлова" },
{ "male": "Новиков", "female": "Новикова" },
{ "male": "Фёдоров", "female": "Фёдорова" },
{ "male": "Морозов", "female": "Морозова" },
{ "male": "Волков", "female": "Волкова" },
{ "male": "Алексеев", "female": "Алексеева" },
{ "male": "Лебедев", "female": "Лебедева" },
{ "male": "Семёнов", "female": "Семёнова" },
{ "male": "Егоров", "female": "Егорова" },
{ "male": "Павлов", "female": "Павлова" },
{ "male": "Козлов", "female": "Козлова" },
{ "male": "Степанов", "female": "Степанова" },
{ "male": "Николаев", "female": "Николаева" },
{ "male": "Орлов", "female": "Орлова" },
{ "male": "Андреев", "female": "Андреева" },
{ "male": "Макаров", "female": "Макарова" },
{ "male": "Никитин", "female": "Никитина", "declension": "in" },
{ "male": "Захаров", "female": "Захарова" },
{ "male": "Зайцев", "female": "Зайцева" },
{ "male": "Соловьёв", "female": "Соловьёва" },
{ "male": "Борисов", "female": "Борисова" },
{ "male": "Яковлев", "female": "Яковлева" },
{ "male": "Григорьев", "female": "Григорьева" },
{ "male": "Романов", "female": "Романова" },
{ "male": "Воробьёв", "female": "Воробьёва" },
{ "male": "Сергеев", "female": "Сергеева" },
{ "male": "Кузьмин", "female": "Кузьмина", "declension": "in" },
{ "male": "Фролов", "female": "Фролова" },
{ "male": "Александров", "female": "Александрова" },
{ "male": "Дмитриев", "female": "Дмитриева" },
{ "male": "Королёв", "female": "Королёва" },
{ "male": "Громов", "female": "Громова" },
{ "male": "Ильин", "female": "Ильина", "declension": "in" },
{ "male": "Козловский", "female": "Козловская", "declension": "sky" },
{ "male": "Орловский", "female": "Орловская", "declension": "sky" },
],
}
@@ -0,0 +1,6 @@
[
{ "defName": "Sleep", "initial": 1, "decayPerHour": 0, "min": 0, "max": 1 },
{ "defName": "Hunger", "initial": 1, "decayPerHour": 0, "min": 0, "max": 1 },
{ "defName": "Toilet", "initial": 1, "decayPerHour": 0, "min": 0, "max": 1 },
{ "defName": "Social", "initial": 1, "decayPerHour": 0, "min": 0, "max": 1 },
]
@@ -0,0 +1,69 @@
[
{
"defName": "Mathematics",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 14 },
"ageMeans": [
{ "age": 7, "mean": 28 },
{ "age": 17, "mean": 55 },
],
},
{
"defName": "RussianLanguage",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 52, "stdDev": 13 },
"ageMeans": [
{ "age": 7, "mean": 32 },
{ "age": 17, "mean": 56 },
],
},
{
"defName": "Literature",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 14 },
},
{
"defName": "Physics",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 48, "stdDev": 15 },
"ageMeans": [
{ "age": 12, "mean": 30 },
{ "age": 17, "mean": 50 },
],
},
{
"defName": "History",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 13 },
},
{
"defName": "PhysicalEducation",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 55, "stdDev": 14 },
},
{
"defName": "Biology",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 13 },
},
{
"defName": "Chemistry",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 48, "stdDev": 15 },
},
{
"defName": "Geography",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 12 },
},
{
"defName": "Informatics",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 48, "stdDev": 16 },
},
{
"defName": "ForeignLanguage",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 15 },
},
]
@@ -0,0 +1,30 @@
[
{
"defName": "Agility",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 14 },
"bodyLimits": [
{ "attribute": "Build", "value": "Obese", "max": 25 },
{ "attribute": "Build", "value": "Heavy", "max": 45 },
{ "attribute": "Build", "value": "Athletic", "min": 40 },
],
},
{
"defName": "Strength",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 14 },
"bodyLimits": [
{ "attribute": "Build", "value": "Skinny", "max": 45 },
{ "attribute": "Build", "value": "Athletic", "min": 40 },
],
},
{
"defName": "Endurance",
"range": { "min": 0, "max": 100 },
"distribution": { "mean": 50, "stdDev": 13 },
"bodyLimits": [
{ "attribute": "Build", "value": "Obese", "max": 35 },
{ "attribute": "Build", "value": "Athletic", "min": 40 },
],
},
]
@@ -0,0 +1,78 @@
[
{
"defName": "Diligent",
"weight": 8,
"incompatible": ["Lazy", "AbsentMinded"],
"skillModifiers": [
{ "skill": "Mathematics", "offset": 8 },
{ "skill": "RussianLanguage", "offset": 6 },
],
},
{
"defName": "AbsentMinded",
"weight": 6,
"incompatible": ["Diligent"],
"skillModifiers": [
{ "skill": "Mathematics", "offset": -6 },
{ "skill": "Informatics", "offset": -4 },
],
},
{
"defName": "Bully",
"weight": 4,
"incompatible": ["Kind", "Quiet"],
"roles": ["student"],
"age": { "min": 7, "max": 18 },
"skillModifiers": [
{ "skill": "Strength", "offset": 8 },
{ "skill": "Literature", "offset": -4 },
],
},
{
"defName": "Quiet",
"weight": 7,
"incompatible": ["Leader", "Bully"],
},
{
"defName": "Leader",
"weight": 4,
"incompatible": ["Quiet"],
"skillModifiers": [
{ "skill": "History", "offset": 4 },
],
},
{
"defName": "Lazy",
"weight": 6,
"incompatible": ["Diligent"],
"skillModifiers": [
{ "skill": "PhysicalEducation", "offset": -8 },
{ "skill": "Mathematics", "offset": -6 },
],
},
{
"defName": "Curious",
"weight": 7,
"skillModifiers": [
{ "skill": "Physics", "offset": 6 },
{ "skill": "Informatics", "offset": 6 },
],
},
{
"defName": "HotTempered",
"weight": 5,
"incompatible": ["Quiet"],
},
{
"defName": "Kind",
"weight": 8,
"incompatible": ["Bully"],
},
{
"defName": "Neat",
"weight": 6,
"skillModifiers": [
{ "skill": "Chemistry", "offset": 4 },
],
},
]
@@ -44,4 +44,52 @@
"ComputerLab": "Computer lab",
"GymHall": "Gym",
"ChangingRoom": "Changing room",
"Mathematics": "Mathematics",
"RussianLanguage": "Russian",
"Literature": "Literature",
"Physics": "Physics",
"History": "History",
"PhysicalEducation": "PE",
"Biology": "Biology",
"Chemistry": "Chemistry",
"Geography": "Geography",
"Informatics": "Informatics",
"ForeignLanguage": "Foreign language",
"Agility": "Agility",
"Strength": "Strength",
"Endurance": "Endurance",
"Diligent": "Diligent",
"AbsentMinded": "Absent-minded",
"Bully": "Bully",
"Quiet": "Quiet",
"Leader": "Leader",
"Lazy": "Lazy",
"Curious": "Curious",
"HotTempered": "Hot-tempered",
"Kind": "Kind",
"Neat": "Neat",
"Height": "Height",
"Weight": "Weight",
"HairColor": "Hair colour",
"EyeColor": "Eye colour",
"BlackHair": "Black",
"BrownHair": "Brown",
"BlondHair": "Blond",
"RedHair": "Red",
"GrayHair": "Grey",
"BrownEyes": "Brown",
"BlueEyes": "Blue",
"GrayEyes": "Grey",
"GreenEyes": "Green",
"HazelEyes": "Hazel",
"Sleep": "Sleep",
"Hunger": "Hunger",
"Toilet": "Toilet",
"Social": "Social",
"Slavic": "Slavic",
"Skinny": "Skinny",
"Average": "Average",
"Athletic": "Athletic",
"Heavy": "Heavy",
"Obese": "Obese",
}
@@ -44,4 +44,52 @@
"ComputerLab": "Компьютерный класс",
"GymHall": "Спортивный зал",
"ChangingRoom": "Раздевалка",
"Mathematics": "Математика",
"RussianLanguage": "Русский язык",
"Literature": "Литература",
"Physics": "Физика",
"History": "История",
"PhysicalEducation": "Физкультура",
"Biology": "Биология",
"Chemistry": "Химия",
"Geography": "География",
"Informatics": "Информатика",
"ForeignLanguage": "Иностранный язык",
"Agility": "Ловкость",
"Strength": "Сила",
"Endurance": "Выносливость",
"Diligent": "Усидчивый",
"AbsentMinded": "Рассеянный",
"Bully": "Задира",
"Quiet": "Тихоня",
"Leader": "Лидер",
"Lazy": "Лентяй",
"Curious": "Любопытный",
"HotTempered": "Вспыльчивый",
"Kind": "Добрый",
"Neat": "Аккуратный",
"Height": "Рост",
"Weight": "Вес",
"HairColor": "Цвет волос",
"EyeColor": "Цвет глаз",
"BlackHair": "Чёрные",
"BrownHair": "Каштановые",
"BlondHair": "Русые",
"RedHair": "Рыжие",
"GrayHair": "Седые",
"BrownEyes": "Карие",
"BlueEyes": "Голубые",
"GrayEyes": "Серые",
"GreenEyes": "Зелёные",
"HazelEyes": "Ореховые",
"Sleep": "Сон",
"Hunger": "Голод",
"Toilet": "Туалет",
"Social": "Общение",
"Slavic": "Славянский",
"Skinny": "Худощавое",
"Average": "Обычное",
"Athletic": "Атлетическое",
"Heavy": "Плотное",
"Obese": "Полное",
}