This commit is contained in:
33333-33333 2026-06-24 13:48:22 +09:00
commit d5c661bc22
53 changed files with 4264 additions and 950 deletions

View file

@ -1,6 +1,6 @@
# Architecture
Build target: static browser page. No bundler. Globals and ordered deferred scripts are intentional. Current inspected version: `15.20.16`.
Build target: static browser page. No bundler. Globals and ordered deferred scripts are intentional. Current inspected version: `15.24.33`.
## Load order
@ -12,6 +12,7 @@ The old `css/styles.css` compatibility shim and `js/ui_family.js` split marker h
- `World`: constructor in `js/world.js`; methods split into view, family/social, combat/effects, environment, spatial/budget, ants, update, placement/log, bootstrap.
- `Tarinai`: constructor in `js/tarinai.js`; methods split into identity/social, disease/nest, item effects, needs/items, social/move/life, render.
- Behavior text is composed from `behavior`, needs, tied needs, ActionSpec metadata, and forced-request cause metadata; stored explicit live text remains the display fallback to avoid player-visible wording churn.
- `Item`: item state, lifecycle, scaling, and field rendering in `js/items.js`.
- `Effect`: transient visuals in `js/sim_core.js`; combat/weather/food effects are spawned through `World` helpers.
- `TarinaiEvents`: global event bus for logs, terrain dirtiness, audio failures, phase/performance changes.
@ -46,7 +47,7 @@ The old `css/styles.css` compatibility shim and `js/ui_family.js` split marker h
`main.js` starts asset preload, world bootstrap, animation loop, deferred image loading, service-worker registration. `World.update(dt)` advances time, weather, items, ants, Tarinai, effects, budgets, terrain dirtiness. `render()` draws cached background/terrain, visible entities, weather overlay, cards, HUD, and debug overlays.
World time is `CONFIG.dayLength` seconds per day. Version `15.20.16` uses 120 seconds/day and weather changes every 46-96 seconds. The phase boundary rules live in `World.phaseName()`.
World time is `CONFIG.dayLength` seconds per day. Version `15.24.33` uses 120 seconds/day and weather changes every 46-96 seconds. The phase boundary rules live in `World.phaseName()`.
Domain events are emitted at central mutation points: placement, eating, decay, effect apply/remove, disease infect/cure, damage/death/birth, fight hit/loss/end, ant spawn/grab/carry/death, weather changes, and rain item drops. Logs/audio still use direct calls where they already existed; do not add duplicate log or sound side effects when subscribing to these events.
@ -57,3 +58,20 @@ Ant behavior remains intentionally conservative. `ANT_EXTENSION_HOOKS` names fut
Use `World.nearby*` helpers rather than full-array scans in hot paths. Terrain cache uses dirty/version flags; do not reintroduce every-frame full terrain hashing. Performance degradation should be centralized in `performance_manager.js`.
Family tree rendering is intentionally asynchronous and cached. `ui_family_async.js` chunks component discovery with `requestIdleCallback` when available; `ui_family_render.js` hydrates cached HTML, keeps archive dirty/version state, and exposes `validateFamilyTree()` plus `familyTreeDiagnostics()` for browser-console checks.
## Basic ActionSpec migration
Version `15.24.33` keeps low-risk need actions, social/fear/combat/mate/birth actions, and sunbath registered through ActionSpec factories. The former configureTarinaiNeedActions late-binding bridge has been removed; the existing sunbath subsystem remains as the body-level timer implementation called by the ActionSpec.
## Runtime diagnostics
`World.runtimeDiagnostics()` exposes spatial rebuild counters, draw-list status, item bucket counts, and behavior counts. `?debug=1` renders these values in the existing debug overlay for manual browser regression checks.
## Social balance guards
Version `15.24.33` adds explicit guardrails around combat-heavy social behavior. Normal conflict must be dominant over bond/mate/family pressure before `fight_rival` can start, and `World.startFight()` / `startConflict()` / `startForcedFight()` use pair-level cooldowns plus already-fighting checks to prevent burst re-entry. Fight mochi remains a strong forced exception, but ordinary proximity conflict is intentionally lower than mate/friend pressure.
## Pre-save runtime polish
Version `15.24.33` keeps item type buckets and item id lookup as runtime caches owned by `World.updateItemCounts()`. Runtime item additions should go through `World.addItem(item, reason)` when practical so spatial, terrain, and item-bucket invalidation stay synchronized. Save migration is still intentionally deferred until this runtime shape has been browser-observed.

View file

@ -0,0 +1,37 @@
# Compact Save V2 Report — 15.24.33
## 方針
15.24.33 では旧セーブ互換を捨て、保存形式を `v: 2` に作り直した。
目的はハッシュテキストを短くすることであり、旧 `TARINAI_SAVE_V1:` / `tarinai_save_slot_v1_` は読み込み対象外。
## 削除した保存対象
- ログ履歴。
- 一時エフェクト。
- UI選択状態。
- 描画用キャッシュ、spatial/grid、bucket、terrain cache。
- `needDisplay` / `needRawBase` / `previousNeeds` など、読み込み後に再計算または近似できる値。
- 短命な表示タイマー、吹き出し文、内部デバッグ計測値。
- 死亡者を含む完全な家系アーカイブ履歴。生存個体の親子関係は index 参照として保存し、読み込み後に `recordFamily()` で再構築する。
## 残した保存対象
- world の field / day / time / weather / camera / generation などの進行状態。
- 生存中たりないの名前、見た目、性格、遺伝、位置、主要欲求、病気、親子参照、友好・恐怖関係。
- 生存中アイテムの type / 位置 / 量 / type別に必要な追加状態。
- アリの巣・アリの主要状態。
- 構造物の owner / hp / attachment などのプレイに関わる状態。
## ハッシュテキスト
- Prefix: `TN2!`
- Codec: `D` = `CompressionStream("deflate-raw")``R` = fallback raw bytes。
- Text encoding: printable ASCII 33〜126 のうち `*`, `'`, `_` を除いた91文字集合。
- Binary-to-text は base91 相当の13/14bit詰め。
## 注意
- 旧セーブは読めない。これは意図した仕様。
- 家系図の死亡者履歴は保存しない。読み込み後の家系図は生存個体ベースになる。
- `CompressionStream` 非対応環境では raw bytes を同じ91文字集合で符号化する。短縮率は下がるが読み書きは維持する。

View file

@ -0,0 +1,52 @@
# Player-visible diff report: 15.24.20 initial ZIP vs 15.24.33
Comparison target: `tarinai_ui_revision_v15_24_20_pin_social_sign_polish(1).zip` → current build `15.24.33`.
## Verdict
No large UI/tool/item/save/family-tree specification change was detected. The intentional player-visible behavior change in this build is limited to social-action balance: ordinary fights and intimidation should occur less often, while friendship and reproduction should no longer be crowded out by conflict.
## Evidence
| Surface | Result | Notes |
|---|---|---|
| Top-level visible text in `index.html` | unchanged | Script tags/version params changed; visible UI copy is still the same. |
| Assets | unchanged | No sprite, object, UI icon, or sound asset change was introduced in this pass. |
| CSS | unchanged | No style-file change in this pass. |
| Tool/item definitions | unchanged | `js/data.js` tool/item definitions were not changed. |
| Tool UI binding | unchanged | No tool-list or operation binding change in this pass. |
| Item behavior/render definitions | unchanged | `items.js` was not changed. |
| Save/snapshot files | unchanged | Save migration remains intentionally deferred. |
| Family-tree UI modules | unchanged | Family-tree UI remains out of scope. |
| Tarinai social behavior | intentionally tuned | Conflict pressure and repeated-fight gates were adjusted to restore friend/mate/birth viability. |
## Files added since the original internal-structure pass
- `docs/REGRESSION_CHECKLIST.md`
- `docs/SOCIAL_BALANCE_FIX_REPORT.md`
- `js/tarinai_action_spec.js`
- `js/tarinai_behavior_state.js`
- `scripts/regression_check.py`
## Changed files with possible player-visible risk
| File | Risk | Assessment |
|---|---|---|
| `js/tarinai_needs_items.js` | Behavior selection and observation text | Social conflict is now less dominant; mate/friend actions are easier to select. |
| `js/world_family_social.js` | Fight/intimidation timing | Pair-level fight re-entry guard added; intimidation and fight durations shortened. |
| `js/tarinai_social_move_life.js` | Proximity conflict pressure | Ordinary close-contact fight probability reduced; fight mochi remains strong. |
| `js/render.js` | Draw ordering | Dynamic render stack remains cached for performance; possible minor y-sort delay under dense scenes. |
| `js/world_update.js` / `js/world_spatial_budget.js` | Simulation lookup performance | Spatial rebuild timing remains dirty/ensure style. |
| `service-worker.js` / `index.html` / `app_manifest.json` / `js/version.js` | Loading/cache | Version and script query params changed only. |
## Explicitly not changed
- No population cap was added.
- No family or generation cap was added.
- Family-tree UI was not modified.
- No tool category, tool name, item sprite, CSS layout, or field choice change was introduced.
- Save migration was not implemented in this pass.
## Residual risk
The remaining visible risk is balance rather than UI specification: social behavior should now produce fewer conflict loops, but exact rates still require browser playtesting with dense populations and multiple personality mixes.

View file

@ -0,0 +1,45 @@
# Regression Checklist
Version: 15.24.33
This pass freezes the current internal baseline before continuing deeper behavior refactors.
## Scope
- Static loading order must remain generated from `app_manifest.json`.
- `index.html` and `service-worker.js` must match the manifest after `scripts/generate_app_files.py`.
- JavaScript syntax must pass `node --check`.
- `ActionSpec` lifecycle helpers must support `selectTarget / canStart / start / tick / finish / fail`.
- Save-data migration is intentionally out of scope for this pass.
- Population caps and family-tree UI are intentionally out of scope.
## Command
```bash
python3 scripts/regression_check.py
```
Expected result: all checks print `[OK]` and exit with status 0.
## 15.24.28 runtime diagnostics
When opening with `?debug=1`, verify the overlay reports spatial rebuilds, draw-list state, item bucket/id-map state, forced/locked behavior counts, and top behavior ids. These are observation aids only and do not change player controls or simulation rules.
## Social balance regression checks
For `15.24.33+`, also verify:
- Ordinary conflict does not crowd out `approach_friend` / `approach_mate` in a neutral population.
- Fight mochi still forces conflict, but one individual should not start several fights at once.
- Intimidation resolves quickly enough that it does not visually lock the colony.
- With `?debug=1`, behavior counts should show non-conflict social actions appearing over time in a dense but non-drugged population.
## 15.24.33 runtime item-bucket checks
- Runtime-created items should go through `World.addItem()` where safe.
- `World.itemsOfType()` should call `ensureItemBuckets()` before returning a bucket.
- `World.itemById()` should not return dead items.
- The debug overlay should expose item bucket dirty state, id-map size, and bucket rebuild counters.
- Save migration remains out of scope until this runtime polish is observed in-browser.

View file

@ -0,0 +1,46 @@
# Remaining Work Split — after 15.24.32
## Bundled in 15.24.32
- Performance/runtime polish that does not alter save semantics.
- Item bucket/id-map coherence.
- Direct item creation helper consolidation.
- Regression guard expansion.
- Documentation update for the pre-save state.
## Still intentionally split
### 1. Browser long-run verification
Static checks pass, but long-run behavior still needs a real browser observation pass:
- 10+ minutes normal observation.
- Food/water/medicine/mochi placement.
- Friend formation, mate approach, birth ritual.
- Conflict/fight/intimidation cooldown behavior.
- Large population stress check with `?debug=1`.
### 2. Save migration
Do after the runtime shape is stable.
Target migration scope:
- Convert legacy `intent/currentAction/activeBehavior/activeForcedBehavior` save fields into `behavior`.
- Avoid saving transient display text and short-lived timers where possible.
- Keep old saves readable.
- Keep new saves simpler.
### 3. Compatibility-layer shrink
Only after save migration:
- Mark legacy behavior fields as deprecated runtime views.
- Remove direct write paths where no longer needed.
- Keep read-only compatibility only if old save support requires it.
## Not in scope by user preference
- Population cap.
- Family/generation cap.
- Family-tree UI rewrite.

View file

@ -0,0 +1,63 @@
# Runtime Polish Pre-Save Report — 15.24.32
This pass bundles the remaining low-risk internal cleanup that can be done before save-data migration.
## Scope
Included:
- Runtime item lookup coherence.
- Item bucket/id-map helper expansion.
- Common runtime item creation paths routed through `World.addItem()`.
- Regression guard updates.
- Final pre-save documentation.
Explicitly excluded:
- Save-data migration.
- Population or family caps.
- Family-tree UI performance work.
- Player-facing tool/UI redesign.
## What changed internally
`World.updateItemCounts()` now rebuilds both:
- `itemTypeBuckets: Map<string, Item[]>`
- `itemIdMap: Map<string, Item>`
The following helpers are available:
```txt
markItemBucketsDirty(reason)
ensureItemBuckets(reason)
addItem(item, reason, opts)
itemById(id)
itemsOfType(type)
liveItemsOfType(type, predicate)
```
This keeps high-frequency code from repeatedly scanning `world.items` for common lookups.
## Runtime creation paths routed through addItem
Common additions now dirty item buckets/spatial/terrain consistently:
- Player placement.
- Rain water drop.
- Grass spawn and grass seed growth.
- Zunchi burst/spawn.
- Ant corpse and ant nest creation.
- Tarinai death trace/splat/grass.
- Built owned structures.
- Field reset grass/stone.
## Player-visible impact
No intentional change to normal UI, tools, item definitions, population/family rules, family-tree UI, or save/load controls.
The only visible change is in `?debug=1`: item bucket dirty state, id-map size, and bucket rebuild counters are now exposed through runtime diagnostics.
## Remaining split
Save migration is still separated because it changes persistence semantics. It should run after this runtime structure has been observed in browser for basic stability.

View file

@ -0,0 +1,28 @@
# Social Balance Fix Report — 15.24.31
## Reported symptoms
- Tarinai rarely reproduced or formed friendships.
- Fights could start in rapid consecutive bursts.
- Intimidation lasted too long.
## Main cause
The ActionSpec social migration preserved the old combat hooks, but conflict pressure and same-priority social selection made `fight_rival` too competitive against `approach_friend` and `approach_mate`. Friend contact also routed into fight behavior whenever nearby conflict was detected, even when bond or mate pressure was stronger.
## Fixes
- Reduced ordinary conflict pressure and carried conflict weight.
- Lowered `fight_rival` and `intimidate_enemy` priority/weight.
- Raised `approach_mate` and `approach_friend` priority/weight.
- Required non-forced conflict to be genuinely dominant over bond/mate/family pressure.
- Added pair-level fight cooldown and already-fighting guards in `World.startFight()`, `startConflict()`, and `startForcedFight()`.
- Shortened intimidation and intimidation-defeat timers.
- Kept fight mochi as a high-priority forced behavior.
## Not changed
- No population cap.
- No family-generation cap.
- No family-tree UI work.
- No save migration.