123 lines
16 KiB
Markdown
123 lines
16 KiB
Markdown
# Журнал ревью — срез 9
|
||
|
||
## Срез 9. Этапы A–B — перепроверка мнений и разговоров
|
||
|
||
- **Фазы:** 41–43
|
||
- **Проверен на:** `a80c6f0`, 2026-08-20
|
||
- **Пути:** `src/HSchool.People/OpinionStore.cs`, `src/HSchool.People/OpinionGenerator.cs`, `src/HSchool.People/OpinionLabels.cs`, `src/HSchool.Ai/TalkCircles.cs`, `src/HSchool.Simulation/MorningOpinions.cs`, `src/HSchool.Simulation/TalkCircleSystem.cs`, `src/HSchool.Simulation/School.cs`, `src/HSchool.Server/Game/PersonCardReader.cs`, `src/HSchool.Server/Game/PersonCardReader.Connections.cs`, `src/HSchool.Server/mods/core/defs/topics/`, `src/HSchool.Server/mods/core/defs/traits/`, `src/HSchool.Client/src/ui/personCard.ts`, `src/HSchool.Client/src/ui/personCardConnections.ts`, `docs/protocol.md`, `tests/HSchool.People.Tests`, `tests/HSchool.Ai.Tests`, `tests/HSchool.Simulation.Tests`, `tests/HSchool.Content.Tests/TopicDefTests.cs`
|
||
- **Итог:** перепроверка после `b38d0bb` (дальше сели 44–47 и сплит карточки). Обещания 41–43 на месте; прошлые правки (сейв кружка, `PickTopic`) живы. Дописано 4 теста; исправлено вступление врага в чужой кружок. `Seed.Mix` в политиковых тестах не трогали. C–D не переписывали.
|
||
- **Открыто:** ванильный `talkCircleMax` 4 по-прежнему съедает `Outgoing.talkCircleBonus` (поле работает, если потолок ниже 4).
|
||
|
||
### Что проверено
|
||
|
||
Каждый пункт «Тесты, без которых фаза не закрыта» у 41–43 имеет отдельный тест. После 58 вкладка «Связи» в `personCardConnections.ts`; клиент рисует присланную `opinionLabel`, лог не монтирует, POST с вкладки нет. Каталог без `TopicDef` падает на загрузке. `RosterTalkDirty` после кружка жив. Сокет 41–43 не бампили (бамп — фаза 45). `dotnet test` с `--filter` по `TalkCirclesTests`, `TalkCircleTests`, `WhisperTests`, `OpinionStoreTests`, `OpinionGeneratorTests`, `MorningOpinionsTests`, `TopicDefTests` зелёный.
|
||
|
||
### Что дописано
|
||
|
||
- `TalkCirclesTests.Joiner_IsRejectedWhenEitherSideIsEnemy`
|
||
- `TalkCirclesTests.LessonWhisperFactor_CutsWhisper_LeavesOrdinaryChat`
|
||
- `TalkCirclesTests.Outgoing_RaisesMaxSize_WhenTalkCircleMaxIsBelowHardLimit`
|
||
- `TalkCircleTests.Enemy_StartsNeighborCircle_InsteadOfJoiningFriends`
|
||
- `TalkCirclesTests.AppearanceTopic_UsesDressAppropriateness` — усилен: `OpinionDelta` на теме внешности, не только хелпер
|
||
|
||
### Что исправлено
|
||
|
||
- `FindOpenCircle` / `JoinCircle` не смотрели мнения: враг в том же узле вступал в уже открытый кружок друзей, хотя старт кружка врагов не зовёт. Теперь отказ и соседний кружок, если есть с кем.
|
||
|
||
### Открытое
|
||
|
||
- Черта «общительный» задаёт `talkCircleBonus: 1`, но ванильный `talkCircleMax` уже 4, а жёсткий потолок тоже 4. Код бонус считает (тест с max 3), в ванили поле по-прежнему не двигает размер. Менять ванильный потолок ревью не стало.
|
||
|
||
## Срез 9. Этапы A–B — мнения и разговоры
|
||
|
||
- **Фазы:** 41–43
|
||
- **Проверен на:** `b38d0bb`, 2026-08-20
|
||
- **Пути:** `src/HSchool.People/OpinionStore.cs`, `src/HSchool.People/OpinionGenerator.cs`, `src/HSchool.People/OpinionLabels.cs`, `src/HSchool.Ai/TalkCircles.cs`, `src/HSchool.Simulation/MorningOpinions.cs`, `src/HSchool.Simulation/TalkCircleSystem.cs`, `src/HSchool.Simulation/School.cs`, `src/HSchool.Server/Game/PersonCardReader.cs`, `src/HSchool.Server/mods/core/defs/topics/`, `src/HSchool.Server/mods/core/defs/traits/`, `src/HSchool.Client/src/ui/personCard.ts`, `docs/protocol.md`, `tests/HSchool.People.Tests`, `tests/HSchool.Ai.Tests`, `tests/HSchool.Simulation.Tests`
|
||
- **Итог:** обещания 41–43 на месте; дописано 14 тестов; исправлено 2 расхождения (сейв мнений после разговора; `PickTopic` почти всегда брал последнюю тему). 44 и 46 — **в работе на момент проверки** (44 🔄, 46 ⬜). 45 и 47 в этот проход не входили.
|
||
- **Открыто:** `Outgoing.talkCircleBonus` не меняет размер кружка при `talkCircleMax` 4 и жёстком clamp 4.
|
||
|
||
### Что проверено
|
||
|
||
Каждый пункт «Тесты, без которых фаза не закрыта» у 41–43 имеет отдельный тест. Клиент рисует присланную `opinionLabel`, вкладка «Связи» не монтирует лог и ничего не POST-ит. Сокет 41–43 не бампили. `dotnet test` с `--filter` по затронутым классам зелёный.
|
||
|
||
### Что дописано
|
||
|
||
- `OpinionStoreTests.SetZero_RemovesTheEntry`
|
||
- `OpinionStoreTests.Set_ClampsToMinusOneHundredAndOneHundred`
|
||
- `OpinionGeneratorTests.RosterJson_RoundTripsFamilyOpinions`
|
||
- `OpinionGeneratorTests.SaveWithoutOpinionsField_SeedsFamilyOnLoad`
|
||
- `MorningOpinionsTests.DriftToZero_DropsTheRecord`
|
||
- `TalkCirclesTests.NodeFriendScore_PullsTowardFriends_NotEnemies`
|
||
- `TalkCirclesTests.LunchNodeBlockedByEnemy_OnlyWhenAnotherSeatExists`
|
||
- `TalkCirclesTests.GossipAndOutgoing_UseTraitFields_NotHardcodedIdLists`
|
||
- `TalkCirclesTests.GossipTrait_BiasesPickTopicTowardGossipTag`
|
||
- `TalkCirclesTests.AppearanceTopic_UsesDressAppropriateness`
|
||
- `TalkCirclesTests.CommunicationGain_IsLessThanLessonSkillPerHour`
|
||
- `TalkCirclesTests.PickTopic_IsNotAlwaysTheLastNameAlphabetically`
|
||
- `TalkCircleTests.TalkCircleFinish_MarksTickPeopleChangedSoSaveWritesOpinions`
|
||
- `WhisperTests.CaughtWhisper_BecomesDisciplineTalkWithTeacher`
|
||
|
||
### Что исправлено
|
||
|
||
- Конец кружка писал мнения в ростер, но `Tick` не возвращал `peopleChanged` — воркер не сохранял `people.json` до утреннего дрейфа.
|
||
- `PickTopic` сравнивал бросок в шкале `0…total` с курсором `0…1`, поэтому тема почти всегда была последней по имени, а сплетник не сдвигал выбор.
|
||
|
||
### Открытое
|
||
|
||
- Черта «общительный» задаёт `talkCircleBonus: 1`, но `MaxSize` клампит к 4 при уже `talkCircleMax` 4 — поле мёртвое, пока верхний потолок не ниже 4. Менять ванильный размер кружка ревью не стало.
|
||
|
||
## Срез 9. Этапы C–D — перепроверка конфликта, присутствия, речи и romance
|
||
|
||
- **Фазы:** 44–47
|
||
- **Проверен на:** `9972b30`, 2026-08-20
|
||
- **Пути:** `src/HSchool.Ai/Conflict.cs`, `src/HSchool.Simulation/TalkCircleSystem.cs`, `src/HSchool.Simulation/PresenceSystem.cs`, `src/HSchool.Simulation/AffinitySystem.cs`, `src/HSchool.Simulation/MorningOpinions.cs`, `src/HSchool.People/Affinity.cs`, `src/HSchool.People/OrientationGenerator.cs`, `src/HSchool.Content/SpeechRules.cs`, `src/HSchool.Protocol/ProtocolCodec.cs`, `src/HSchool.Client/src/net/protocol.ts`, `src/HSchool.Client/src/format/talkCircle.ts`, `src/HSchool.Client/src/ui/dressRulesPanel.ts`, `src/HSchool.Client/src/ui/personCardNow.ts`, `src/HSchool.Client/src/ui/personCardConnections.ts`, `src/HSchool.Server/mods/romance/`, `src/HSchool.Server/Game/PresenceFrame.cs`, `src/HSchool.Server/Api/SpeechRulesModels.cs`, `docs/protocol.md`, `tests/HSchool.Ai.Tests/ConflictTests.cs`, `tests/HSchool.Simulation.Tests/QuarrelFightTests.cs`, `tests/HSchool.Simulation.Tests/TalkCircleTests.cs`, `tests/HSchool.Simulation.Tests/MorningOpinionsTests.cs`, `tests/HSchool.Protocol.Tests/ProtocolCodecTests.cs`, `tests/HSchool.People.Tests/AffinityTests.cs`, `tests/HSchool.People.Tests/OrientationGeneratorTests.cs`, `tests/HSchool.Content.Tests/RomancePackTests.cs`, `tests/HSchool.AppHost.Tests/RomancePackTests.cs`, `tests/HSchool.AppHost.Tests/SpeechRulesApiTests.cs`
|
||
- **Итог:** перепроверка после `19554d4` (дальше сели A–B recheck в `TalkCircleSystem` и правки `protocol.md` у портретов). Обещания 44–47 на месте; прошлые правки (сейв ссоры, id жертвы задиры) живы. Дописано 3 теста; исправлено мнение жертвы о заступнике. `Seed.Mix` в политиковых тестах не трогали. A–B не переписывали. Хостовые `RomancePackTests` / `SpeechRulesApiTests` не гонялись.
|
||
- **Открыто:** строка локации для тем пака `romance` по-прежнему `defName`; ванильный `quarrelChance` 1 съедает `conflictChance` черт на ссоре.
|
||
|
||
### Что проверено
|
||
|
||
Каждый пункт «Тесты, без которых фаза не закрыта» у 44–47 имеет отдельный тест. Ссора/драка — поля черт, не `defName`; skip пустого двора бросает кружок; нужды «здоровье» нет. Кадр присутствия v9 несёт id кружка и темы, имён нет; «Сейчас» собирает ту же строку из directory. Политика речи — с завтра; POST сегодня не переписывает живой кружок. Ваниль и `example` без романтических тем; пара только 18+; учитель → ученик не получает симпатию. Отказ врагу в чужой кружок (A–B) не ломает заступника: ссора идёт через `FindOpenConflict`, не `JoinCircle`. `dotnet test` с `--filter` по `QuarrelFightTests`, `ConflictTests` и `AffinityTests` зелёный.
|
||
|
||
### Что дописано
|
||
|
||
- `QuarrelFightTests.Defender_AndVictim_OpinionsMoveAsAllies`
|
||
- `ConflictTests.QuarrelOpinion_IsStrongerThanRudeTalk`
|
||
- `AffinityTests.RosterJson_RoundTripsCrushesAndPartner`
|
||
|
||
### Что исправлено
|
||
|
||
- Конец ссоры с заступником писал жертве к заступнику тот же штраф, что к задире. Теперь жертва и защитник — союзники: мнение друг к другу растёт, к задире падает.
|
||
|
||
### Открытое
|
||
|
||
- Клиентский `talkTopicLabel` знает только ванильные ключи. Тема пака в локации — сырой id; в логе карточки подпись берётся из каталога. Вшивать строки пака в ванильный словарь ревью не стало.
|
||
- Ванильный `quarrelChance` уже 1, поэтому `conflictChance` задиры и вспыльчивого не двигает частоту ссоры (кламп 0…1). На драке поле живое (`fightChance` 0.1). Менять ванильный шанс ссоры ревью не стало.
|
||
|
||
## Срез 9. Этапы C–D — конфликт, присутствие, речь и romance
|
||
|
||
- **Фазы:** 44–47
|
||
- **Проверен на:** `19554d4`, 2026-08-20
|
||
- **Пути:** `src/HSchool.Ai/Conflict.cs`, `src/HSchool.Simulation/TalkCircleSystem.cs`, `src/HSchool.Simulation/PresenceSystem.cs`, `src/HSchool.Simulation/AffinitySystem.cs`, `src/HSchool.Simulation/MorningOpinions.cs`, `src/HSchool.People/Affinity.cs`, `src/HSchool.People/OrientationGenerator.cs`, `src/HSchool.Content/SpeechRules.cs`, `src/HSchool.Protocol/ProtocolCodec.cs`, `src/HSchool.Client/src/net/protocol.ts`, `src/HSchool.Client/src/format/talkCircle.ts`, `src/HSchool.Client/src/ui/dressRulesPanel.ts`, `src/HSchool.Client/src/ui/personCardNow.ts`, `src/HSchool.Client/src/ui/personCardConnections.ts`, `src/HSchool.Server/mods/romance/`, `src/HSchool.Server/Game/PresenceFrame.cs`, `src/HSchool.Server/Api/SpeechRulesModels.cs`, `docs/protocol.md`, `tests/HSchool.Ai.Tests/ConflictTests.cs`, `tests/HSchool.Simulation.Tests/QuarrelFightTests.cs`, `tests/HSchool.Simulation.Tests/TalkCircleTests.cs`, `tests/HSchool.Simulation.Tests/MorningOpinionsTests.cs`, `tests/HSchool.Protocol.Tests/ProtocolCodecTests.cs`, `tests/HSchool.People.Tests/AffinityTests.cs`, `tests/HSchool.People.Tests/OrientationGeneratorTests.cs`, `tests/HSchool.Content.Tests/RomancePackTests.cs`, `tests/HSchool.AppHost.Tests/RomancePackTests.cs`, `tests/HSchool.AppHost.Tests/SpeechRulesApiTests.cs`
|
||
- **Итог:** обещания 44–47 на месте; дописано 4 теста; исправлено 2 расхождения с тем же швом, что у 41–43 (сейв после ссоры; id жертвы задиры). `Seed.Mix` в политиковых тестах не трогали. Фазу 60 не закрывали.
|
||
- **Открыто:** строка локации для тем пака `romance` показывает `defName`, не локаль пака.
|
||
|
||
### Что проверено
|
||
|
||
Каждый пункт «Тесты, без которых фаза не закрыта» у 44–47 имеет отдельный тест. Ссора/драка — поля черт, не `defName`; skip пустого двора бросает кружок, а не тащит драку через выходные; нужды «здоровье» нет. Кадр присутствия v9 несёт id кружка и темы, имён нет; «Сейчас» собирает ту же строку из directory. Политика речи — с завтра, POST сегодня не переписывает живой кружок. Ваниль и `example` без романтических тем; пара только 18+; учитель → ученик не получает симпатию. Хостовые `RomancePackTests` / `SpeechRulesApiTests` в этом проходе не гонялись (политика тестирования: не AppHost, сервер пользователя не трогали). `dotnet test` с `--filter` по `QuarrelFightTests`, `RosterJson_RoundTripsBullyVictimId` и `PupilTalkWithTeacherCrush` зелёный.
|
||
|
||
### Что дописано
|
||
|
||
- `QuarrelFightTests.QuarrelFinish_MarksTickPeopleChangedSoSaveWritesOpinions`
|
||
- `QuarrelFightTests.BullyPickingAVictim_DirtiesRosterSoSaveKeepsTheId`
|
||
- `OpinionGeneratorTests.RosterJson_RoundTripsBullyVictimId`
|
||
- `AffinityTests.PupilTalkWithTeacherCrush_WritesRebuffAndDropsOpinion`
|
||
|
||
### Что исправлено
|
||
|
||
- Конец ссоры, драки и извинения писал мнения, но не ставил `RosterTalkDirty` — воркер не сохранял `people.json` до следующего чужого сдвига, как с кружком до ревью A–B.
|
||
- Первая запись `BullyVictimId` оставалась только в памяти: после перезагрузки задира бросал кубик заново.
|
||
|
||
### Открытое
|
||
|
||
- Клиентский `talkTopicLabel` знает только ванильные ключи. Тема пака в локации — сырой id; в логе карточки подпись берётся из каталога. Вшивать строки пака в ванильный словарь ревью не стало.
|