153 lines
No EOL
10 KiB
Markdown
153 lines
No EOL
10 KiB
Markdown
# WINDSURF: Regret vs No Remorse
|
|
|
|
This note compares the exported `WINDSURF` USECODE handlers between the Regret corpus at `USECODE/REGRET/REGRET_USECODE_extracted/` and the No Remorse corpus at `USECODE/EUSECODE_extracted/`.
|
|
|
|
## Scope
|
|
|
|
- Regret source class: `WINDSURF` entry `179`, class id `0x0337`
|
|
- No Remorse source class: `WINDSURF` entry `180`, class id `0x0337`
|
|
- Active slots in both corpora:
|
|
- `0x06` `gotHit`
|
|
- `0x0A` `equip`
|
|
- `0x0B` `unequip`
|
|
- `0x10` `leaveFastArea`
|
|
|
|
Slot metadata confirms the same active event set in both builds:
|
|
|
|
- Regret: [USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv](USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv#L5715), [USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv](USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv#L5719), [USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv](USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv#L5720), [USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv](USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv#L5725)
|
|
- No Remorse: [USECODE/EUSECODE_extracted/class_event_index.tsv](USECODE/EUSECODE_extracted/class_event_index.tsv#L5743), [USECODE/EUSECODE_extracted/class_event_index.tsv](USECODE/EUSECODE_extracted/class_event_index.tsv#L5747), [USECODE/EUSECODE_extracted/class_event_index.tsv](USECODE/EUSECODE_extracted/class_event_index.tsv#L5748), [USECODE/EUSECODE_extracted/class_event_index.tsv](USECODE/EUSECODE_extracted/class_event_index.tsv#L5753)
|
|
|
|
## High-Level Read
|
|
|
|
Current best read: `WINDSURF` is a wind-force / push-volume helper that applies directional displacement to overlapping targets. It is not primarily an item-use script or a one-off effect trigger.
|
|
|
|
The strongest common behavior is in `gotHit`, which:
|
|
|
|
- resolves a target/reference pair from a helper call
|
|
- filters out unwanted targets by type, shape, overlap state, and actor flags
|
|
- converts a 16-step direction value into `x` and `y` offsets
|
|
- scales those offsets by a speed value, with a difficulty-based override when speed is `15`
|
|
- repeatedly applies movement toward the offset destination while the target remains within the effect
|
|
|
|
Regret evidence: [USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt](USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt#L1)
|
|
|
|
No Remorse evidence with preserved local names: [USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt](USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt#L1)
|
|
|
|
## Shared Behavior
|
|
|
|
The two corpora agree on the overall lifecycle.
|
|
|
|
### `equip`
|
|
|
|
Both versions:
|
|
|
|
- set local bookkeeping/info state
|
|
- register the object with a helper using selector `0x020C`
|
|
- skip the scan if a parameter is `0x00FF`
|
|
- otherwise iterate nearby candidates and spawn `WINDSURF::gotHit` for non-overlapping matches
|
|
|
|
Regret: [USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_0A_equip.txt](USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_0A_equip.txt#L1)
|
|
|
|
No Remorse: [USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_0A_equip.txt](USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_0A_equip.txt#L1)
|
|
|
|
### `unequip`
|
|
|
|
Both versions iterate the same candidate loop and re-spawn `gotHit` for the same overlap-based filter.
|
|
|
|
Regret: [USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_0B_unequip.txt](USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_0B_unequip.txt#L1)
|
|
|
|
No Remorse: [USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_0B_unequip.txt](USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_0B_unequip.txt#L1)
|
|
|
|
### `leaveFastArea`
|
|
|
|
Both versions only perform lightweight bookkeeping and unregister/update the `0x020C` helper state.
|
|
|
|
Regret: [USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_10_leaveFastArea.txt](USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_10_leaveFastArea.txt#L1)
|
|
|
|
No Remorse: [USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_10_leaveFastArea.txt](USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_10_leaveFastArea.txt#L1)
|
|
|
|
### `gotHit`
|
|
|
|
Both versions perform the same gameplay-side stages:
|
|
|
|
1. Resolve target and velocity/reference context from a helper call.
|
|
2. Reject cases on wrong map array/map number, wrong type/shape, missing overlap, and incompatible actor/NPC state.
|
|
3. Default `speed` to `3` when zero and expand `15` into a difficulty-scaled speed.
|
|
4. Map a 16-way direction into signed `xoff` and `yoff` steps.
|
|
5. Multiply those steps by speed.
|
|
6. Feed the result into a pair of movement/update helper calls.
|
|
7. Fall back to a separate spawned helper when the source object is on another map array.
|
|
|
|
The No Remorse decompile makes this especially clear because it preserved locals such as `item`, `xoff`, `yoff`, `speed`, and `dir`: [USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt](USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt#L1)
|
|
|
|
## Important Differences
|
|
|
|
The differences currently look like implementation/layout differences rather than a different gameplay role.
|
|
|
|
### 1. Body sizes are materially smaller in Regret
|
|
|
|
- Regret `gotHit`: `753` bytes vs No Remorse `1121` bytes
|
|
- Regret `equip`: `114` bytes vs No Remorse `193` bytes
|
|
- Regret `unequip`: `78` bytes vs No Remorse `145` bytes
|
|
- Regret `leaveFastArea`: `27` bytes vs No Remorse `59` bytes
|
|
|
|
Evidence:
|
|
|
|
- Regret metadata: [USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv](USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv#L5715), [USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv](USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv#L5719), [USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv](USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv#L5720), [USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv](USECODE/REGRET/REGRET_USECODE_extracted/class_event_index.tsv#L5725)
|
|
- No Remorse metadata: [USECODE/EUSECODE_extracted/class_event_index.tsv](USECODE/EUSECODE_extracted/class_event_index.tsv#L5743), [USECODE/EUSECODE_extracted/class_event_index.tsv](USECODE/EUSECODE_extracted/class_event_index.tsv#L5747), [USECODE/EUSECODE_extracted/class_event_index.tsv](USECODE/EUSECODE_extracted/class_event_index.tsv#L5748), [USECODE/EUSECODE_extracted/class_event_index.tsv](USECODE/EUSECODE_extracted/class_event_index.tsv#L5753)
|
|
|
|
At the current pseudocode fidelity, this does not yet prove a gameplay change. It more likely indicates one or more of:
|
|
|
|
- more compact compiled helper usage in Regret
|
|
- different trailer/debug-symbol coverage between variants
|
|
- helper-class renumbering and wrapper differences that the exporter is not yet lowering into named operations
|
|
|
|
### 2. Helper class IDs differ across the two corpora
|
|
|
|
The high-level actions align, but the helper targets differ:
|
|
|
|
- Regret tends to call/spawn `class_0A1D_*` and `class_0A17_slot_20`
|
|
- No Remorse tends to call/spawn `class_0A0C_*` and `class_0A18_slot_20`
|
|
|
|
Examples:
|
|
|
|
- Regret `equip` uses `class_0A1D_slot_3C`: [USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_0A_equip.txt](USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_0A_equip.txt#L4)
|
|
- No Remorse `equip` uses `class_0A0C_slot_33`: [USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_0A_equip.txt](USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_0A_equip.txt#L9)
|
|
- Regret `gotHit` spawns `class_0A1D_slot_3B` and `class_0A17_slot_20`: [USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt](USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt#L104), [USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt](USECODE/REGRET/REGRET_USECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt#L123)
|
|
- No Remorse `gotHit` spawns `class_0A0C_slot_32` and `class_0A18_slot_20`: [USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt](USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt#L118), [USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt](USECODE/EUSECODE_extracted/pseudocode/WINDSURF/slot_06_gotHit.txt#L145)
|
|
|
|
Current best read: these are corresponding support classes in different builds, not evidence that `WINDSURF` changed role.
|
|
|
|
### 3. No Remorse preserves clearer local names
|
|
|
|
The No Remorse `gotHit` pseudocode retained variable names such as `item`, `xoff`, `yoff`, `speed`, and `dir`, which makes the movement semantics explicit. The Regret decompile currently renders the same logic through anonymous locals like `local_02`, `local_04`, `local_06`, `local_08`, and `local_0A`.
|
|
|
|
This is a tooling/output-quality difference, not currently a behavior difference.
|
|
|
|
## Cross-Reference: Wind Vents
|
|
|
|
The No Remorse vent handlers `WVENTNS` and `WVENTEW` both carry a local variable named `windsurf`, which strongly supports the interpretation that `WINDSURF` is the reusable wind-effect object used by vent-style map machinery.
|
|
|
|
- [USECODE/EUSECODE_extracted/pseudocode/WVENTNS/slot_06_gotHit.txt](USECODE/EUSECODE_extracted/pseudocode/WVENTNS/slot_06_gotHit.txt#L1)
|
|
- [USECODE/EUSECODE_extracted/pseudocode/WVENTEW/slot_06_gotHit.txt](USECODE/EUSECODE_extracted/pseudocode/WVENTEW/slot_06_gotHit.txt#L1)
|
|
|
|
This supports the gameplay-facing name `wind surface / wind push field` much more strongly than anything like a weapon, NPC AI, or one-shot trap script.
|
|
|
|
## Current Conclusion
|
|
|
|
Current best read remains:
|
|
|
|
`WINDSURF` is a directional wind-force helper shared by both Regret and No Remorse. It registers an area-effect object, scans nearby candidates, and pushes overlapping targets along a configured direction and speed, with some actor/type filtering and an alternate map-array handling path.`
|
|
|
|
There is no strong evidence yet that the gameplay role changed between Regret and No Remorse. The main differences are:
|
|
|
|
- helper/wrapper class numbering
|
|
- larger compiled bodies in No Remorse
|
|
- better preserved symbolic locals in the No Remorse export
|
|
|
|
## Open Questions
|
|
|
|
- Whether Regret's smaller bodies reflect true logic removal or just tighter helper factoring.
|
|
- What helper families `0A1D` and `0A17` in Regret correspond to exactly relative to No Remorse `0A0C` and `0A18`.
|
|
- Whether shape `0x01D9` is the same excluded target class in both variants and why `WINDSURF` explicitly skips it.
|
|
- Whether the map-array fallback helper is a teleport/materialization path, a cross-map handoff, or a delayed movement dispatch. |