Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,344 changes: 2,344 additions & 0 deletions asset-source/playtests/evidence/environment-impact/acceptance.json

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions asset-source/playtests/evidence/environment-impact/moving.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 13 additions & 1 deletion docs/features/character-vfx-proposal.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Proposal: Character VFX — Dark, Living, Forceful

**Trạng thái:** đã triển khai một proof Aren Thunder Cleave ([issue #126](https://github.com/img2threejs/wild-crown/issues/126), [PR #127](https://github.com/img2threejs/wild-crown/pull/127)); chưa nghiệm thu proposal toàn bộ hero/companion và chưa duyệt nhân rộng art direction.
**Trạng thái:** đã triển khai proof Aren Thunder Cleave ([issue #126](https://github.com/img2threejs/wild-crown/issues/126), [PR #127](https://github.com/img2threejs/wild-crown/pull/127)) và phản ứng vật thể/môi trường theo simulation ([issue #128](https://github.com/img2threejs/wild-crown/issues/128)); chưa nghiệm thu proposal VFX toàn bộ hero/companion và chưa duyệt nhân rộng art direction.

## 1. Mục tiêu và phạm vi

Expand Down Expand Up @@ -182,3 +182,15 @@ Chọn **Dark, Living, Forceful**: tối ở chất liệu và khoảng nghỉ;
- Hai lệnh mở rộng gộp thêm weapon/audio/story-animation timeout ở **180s / 90s**; effect suite chạy riêng và native get-up chạy riêng đều pass. Chưa kết luận nguyên nhân của timeout hoặc tuyên bố full-suite pass.
- CPU presentation p95 quan sát trong paired capture: **9.80ms → 8.30ms**, sau warm-up 150 bước; 247 render samples gồm frame setup, không tính screenshot readback. Không cô lập tải nền trong capture nên **không coi đây là benchmark tải máy được kiểm soát**. Đây là thời gian CPU submit/render của fixture headless, không phải total frame time/GPU time; không chứng minh mục tiêu hiệu năng toàn proposal hoặc phần cứng tham chiếu.
- [Trace, guard checks, hash và giới hạn](../../asset-source/playtests/evidence/aren-thunder-cleave/acceptance.json). Đã kiểm tra get-up immunity và zero-damage suppression bằng focused suite; targeted strike này không có block path để giả lập. Canopy, đông hiệu ứng, toàn roster và art/release verification của native assets **chưa được chứng nhận bởi proof này**.

## 11. Bổ sung lực tác động môi trường — issue #128

Đây là phần simulation bổ sung, không còn chỉ là presentation của proposal ban đầu. Skill tấn công thật truyền lực và hư hại tới vật thể native trong phạm vi tiếp xúc: đá rời bật/dịch chuyển/lăn rồi lắng xuống, cây có gốc rung lệch ngắn, cây mềm bị ép xuống và bề mặt lưu dấu hư hại. Không dùng camera shake hoặc particle thay cho chuyển động vật thể.

- Giữ damage/timing/mana/cooldown của nhân vật; tách từng contact/pulse thật và không gây damage từ windup, hỗ trợ hoặc VFX trang trí. Pause, hit-stop, slow motion, restore và reset theo simulation.
- Bảo vệ cầu, cổng, support, vật thể nhiệm vụ/delivery/movable và các cụm rễ đỡ đường. Không biến toàn bản đồ thành môi trường phá hủy được; cây lớn không bị bật gốc, terrain không bị biến dạng và chưa có mesh fracture.
- Tái sử dụng native GLB, thêm ba viên đá rời tại Greenwake; không generation trả phí, không thay native bằng proxy và không nâng trạng thái candidate/blocked thành release-verified.
- **Nguồn REA:** lịch sử chỉ cung cấp Kena và Zenless Zone Zero làm tham chiếu hình ảnh, không có binary để decompile. Lần này REA quan sát bundle Last Stand/Three.js và trực tiếp ghi replay native Wild Crown. Không suy diễn thuật toán phá hủy của hai game thương mại từ những bằng chứng đó.
- Đối chứng native bật/tắt môi trường giữ HP **1000 → 964 → 946**, mana **100 → 80**. REA ghi được instance matrix dịch chuyển, material hư hại, hai contact riêng của melee/lightning, pause ngoài hit-stop và trạng thái hư hại còn rõ khi bật Reduced Effects. **143 test pass / 0 fail**; không cộng các bộ test trước đó vào tổng này.
- [Hợp đồng simulation và giới hạn](combat.md#offensive-environmental-response-128), [trace/hashes/giới hạn của REA](../../asset-source/playtests/evidence/environment-impact/acceptance.json), [đối chứng không phản ứng môi trường](../../asset-source/playtests/evidence/environment-impact/before-control.png), [vật thể đang chuyển động](../../asset-source/playtests/evidence/environment-impact/moving.png), [hư hại sau khi lắng xuống](../../asset-source/playtests/evidence/environment-impact/after-settled.png).

37 changes: 37 additions & 0 deletions docs/features/combat.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,40 @@ A standalone canonical Bamboo engine smoke measured Asha's first shelter charge
The native Yara/Heartroot fitting smoke completed in 7.23 s after this change; the prior measured construction took 12.19 s (11.05 s under CPU profiling). These are individual local observations, not a release benchmark. All 34 weapon tests passed, including wrist preservation, fist clearance, pose sampling, and repeated equip/dispose, without increasing their timeouts.

The ranged camp hunter's crossbow repair removes detached clavicle/forearm weight islands while retaining connected wrist blends. Its native pose sheet was regenerated and inspected; the Bamboo asset suite passed all 83 tests, including rigid weapon distance across clips, manifest hashes, and byte-identical re-authoring. Generate these clips with Node **22.22.3**: Node 20.18.1 produced a different animation fingerprint. The current ranged animated GLB hash is `4041ef84aa834e3d06d0e84e6cef8ec55bfd37a0bebe5791f08c25cd8291901a`. Asset evidence remains `blocked` pending user approval; no paid generation was performed for this repair.

## Offensive environmental response (#128)

`EngineState.environment` owns local prop health, material resistance, impulse, position, angular response and sleep state. `CombatSnapshot.environmentProps` is its sparse presentation projection; `EnvironmentPropVisuals` never awards damage. No physics dependency or replacement prop mesh was introduced.

| Eligible native material | Physical response |
|---|---|
| Rooted wood/bamboo | Brief bounded spring deflection and accumulated surface scars; the root and its collision/support authority remain fixed. |
| Soft fern/reeds | Deflection, accumulated damage and a flattened native remnant when crushed; broken foliage contributes no remaining native blocker. |
| Large structural rock | Surface damage only; standable tops, decks and navigation do not move. |
| Explicit small loose stones | Directional impulse, gravity, wall collision, ground friction and tumbling; a damaged chipped core remains visible. |

Three existing `prop-mire-bank-rock` GLBs are placed as loose stones beside Greenwake's first combat pocket. Only the `environment-loose-` prefix **plus** the small-scale stone allowlist opts into this role. Native geometry measures their body bounds without creating a stationary actor/camera blocker or standable top. Loose travel is bounded to 4 m from its authored origin and supported playable space. Bodies sleep only after landing, never at a zero-speed airborne apex; native-support refresh wakes impacted bodies.

### Contact and authority

- Aren's active light/heavy windows, actual delayed Thunder Cleave and Judgement detonations, Heartroot lanes/bursts, swept projectiles, Vesper/Sakda kit strikes, confirmed Vara damage and active offensive hazards transfer force through their real shapes. Support, anticipation, cosmetic cues and Orun possession do not.
- Stable action/projectile/hazard contact identities deduplicate sustained windows. Distinct real pulses remain separate: Sakda's limb/ring and six Hundred Elbows contacts plus uppercut are not collapsed into one hit.
- Material resistance and distance attenuate environmental damage. Narrow solid-volume visibility checks walls, terrain and measured supports; they do not run the expensive character movement/landing sweep for every force query.
- A nearby eligible prop can be the target of Aren's heavy without manufacturing an actor. Empty-air rejection, mana/cooldowns and actor hit resolution remain unchanged. A real fused Bloomseed burst still resolves its existing offensive explosion; ordinary projectile expiry does not invent one.
- Conditional/story interaction targets, movable/delivery objects, collider-paired route dressing and Greenwake's named corridor root cluster are protected. Bridges, gates, quest state, rewards, actor movement and `CameraDirector` retain their existing authority.

### Lifetime and presentation

Physics advances only on scaled world time, freezes under pause/hit-stop and resumes with slow motion. Engine serialization preserves local health, momentum and pose; restore baselines prevent old contacts from replaying chips. Encounter checkpoint/region replacement restores its own local baseline. Campaign Continue retains the existing safe-checkpoint policy: this is not a new permanent destruction world fact or save format.

Native instanced transforms and per-instance scar shading retain their response through visibility changes and LOD projection. A bounded 64-slot secondary chip pool is cosmetic and non-colliding. Reduced Motion/Effects suppresses chips and reduces rooted deflection, but does not hide damage or undo loose-body displacement.

### Exercised evidence and limits

- **143 tests / 0 failures**, 1,841 assertions across the environmental, four-hero, run-reset, native-collider and Thunder Cleave suites. Regression coverage includes thin walls/stacked floors, genuine multi-hit pulses, zero-damage/support suppression, serialization, retry, airborne apex, resting bodies and removed native support.
- Final TypeScript + Vite production build passed; the existing large-chunk warning remains. Release-validator unit tests passed **236 / 236**. These validator tests do not certify the current candidate native assets for release.
- REA controlled the actual `CombatEngine` + `GameRenderer` + `StoryPresentation` native Greenwake fixture. Paired environmental response on/off retained the same actor HP **1000 → 964 → 946** and mana **100 → 80**. Contact advanced prop serial 1, delayed lightning serial 2; native matrices/materials changed, bodies settled, pause outside hit-stop held their exact pose, and Reduced Effects kept their damage/displacement. Native asset errors and missing actor assets were empty.
- Production UI smoke entered Greenwake as Aren/Koro, accepted real K down/up input (mana **100 → 88**, heavy cooldown shown) and exercised Escape/Resume. This verifies boot/input, not an additional environmental-contact or campaign-save claim. Five audio requests reported `net::ERR_ABORTED`; audio playback was not accepted by this smoke.
- [Captured transitions, source hashes, assertions and REA limitations](../../asset-source/playtests/evidence/environment-impact/acceptance.json); [moving native bodies](../../asset-source/playtests/evidence/environment-impact/moving.png), [settled damage](../../asset-source/playtests/evidence/environment-impact/after-settled.png), [Reduced Effects](../../asset-source/playtests/evidence/environment-impact/reduced.png).
- This is bounded native prop response, **not** triangle fracture, tree uprooting, terrain deformation, loose-body-to-loose-body collision, a whole-roster native art pass or an FPS/release certification.

4 changes: 4 additions & 0 deletions src/content/levels/act-i.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export const ACT_I_REGIONS: readonly RegionDefinition[] = [
id: "greenwake", authoringStatus: "unaccepted", name: "Greenwake", biome: "Forest-edge settlement and the Erya boundary", bounds: { min: v(-56, -1, -52), max: v(108, 14, 88) }, environmentRecipeId: "greenwake-environment",
props: [
prop("greenwake-yara-courtyard", "prop-greenwake-houses", v(-12, 0, -4), "ground"),
// Reused native river stones: small, non-blocking loose bodies beside the first combat pocket.
prop("environment-loose-greenwake-west", "prop-mire-bank-rock", v(5.05, 0, -2.4), "ground", 0.3, v(0.12, 0.12, 0.12)),
prop("environment-loose-greenwake-east", "prop-mire-bank-rock", v(7.15, 0, -3.1), "ground", 1.1, v(0.14, 0.12, 0.13)),
prop("environment-loose-greenwake-north", "prop-mire-bank-rock", v(6.25, 0, -4.7), "ground", 2.2, v(0.11, 0.1, 0.12)),
prop("greenwake-erya-edge", "prop-erya-edge-tree", v(17, 0, -9), "ground", -0.22, v(1.5, 1.5, 1.5)),
prop("greenwake-entry-tree-west", "prop-erya-edge-tree", v(-19, 0, -14), "ground", -0.18, v(0.6, 0.6, 0.6)),
prop("greenwake-entry-tree-center", "prop-erya-edge-tree", v(-13, 0, -14), "ground", 0.31, v(0.6, 0.6, 0.6)),
Expand Down
3 changes: 3 additions & 0 deletions src/content/solid-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { GROVE_BOUNDARY_ID_PREFIX, GROVE_SOLID_PROFILES } from '../game/combat/G
import { MISTVEIL_BOUNDARY_ID_PREFIX, MISTVEIL_SOLID_PROFILES } from '../game/combat/MistveilContent.js';
import { MOONPINE_BOUNDARY_ID_PREFIX, MOONPINE_SOLID_PROFILES } from '../game/combat/MoonpineContent.js';
import type { WorldAssetPlacement } from '../game/contracts.js';
import { isLooseEnvironmentProp } from '../game/combat/EnvironmentProps.js';

export type SolidPropKind = 'trunk' | 'solid' | 'arch' | 'platform' | 'decoration';
const PROFILES: Readonly<Record<string, SolidPropKind>> = {
Expand All @@ -24,6 +25,8 @@ const DECORATION_PREFIXES = [GREENWAKE_BOUNDARY_ID_PREFIX, CANOPY_BOUNDARY_ID_PR
/** Only explicitly soft vegetation is passable; unknown props remain physical. Boundary dressing of the playtest regions is visual only. */
export function solidPropKind(placement: WorldAssetPlacement): SolidPropKind {
if (DECORATION_PREFIXES.some(prefix => placement.id.startsWith(prefix))) return 'decoration';
// Small loose rubble can be stepped over; it must never contribute a stationary collider or standable top.
if (isLooseEnvironmentProp(placement)) return 'decoration';
return PROFILES[placement.assetId] ?? 'solid';
}

Expand Down
Loading
Loading