RagnarokOnline: layer toggles, fog/light/sky overrides, music picker#913
RagnarokOnline: layer toggles, fog/light/sky overrides, music picker#913malvarezcastillo wants to merge 19 commits into
Conversation
|
Please remove music picker and color picker to start with. |
| export const VR_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="20" fill="white"><g><path d="M29,8H3A1,1,0,0,0,2,9V23a1,1,0,0,0,1,1H13a1,1,0,0,0,1-.83l.66-4A1.36,1.36,0,0,1,16,18a1.38,1.38,0,0,1,1.36,1.26L18,23.17A1,1,0,0,0,19,24H29a1,1,0,0,0,1-1V9A1,1,0,0,0,29,8ZM8.5,19A3.5,3.5,0,1,1,12,15.5,3.5,3.5,0,0,1,8.5,19Zm15,0A3.5,3.5,0,1,1,27,15.5,3.5,3.5,0,0,1,23.5,19Z"/></g></svg>`; | ||
| export const CUTSCENE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 142.448 142.448" height="20" fill="white"><g><path d="M142.411,68.9C141.216,31.48,110.968,1.233,73.549,0.038c-20.361-0.646-39.41,7.104-53.488,21.639 C6.527,35.65-0.584,54.071,0.038,73.549c1.194,37.419,31.442,67.667,68.861,68.861c0.779,0.025,1.551,0.037,2.325,0.037 c19.454,0,37.624-7.698,51.163-21.676C135.921,106.799,143.033,88.377,142.411,68.9z M111.613,110.336 c-10.688,11.035-25.032,17.112-40.389,17.112c-0.614,0-1.228-0.01-1.847-0.029c-29.532-0.943-53.404-24.815-54.348-54.348 c-0.491-15.382,5.122-29.928,15.806-40.958c10.688-11.035,25.032-17.112,40.389-17.112c0.614,0,1.228,0.01,1.847,0.029 c29.532,0.943,53.404,24.815,54.348,54.348C127.91,84.76,122.296,99.306,111.613,110.336z"></path> <path d="M94.585,67.086L63.001,44.44c-3.369-2.416-8.059-0.008-8.059,4.138v45.293 c0,4.146,4.69,6.554,8.059,4.138l31.583-22.647C97.418,73.331,97.418,69.118,94.585,67.086z"></path> </g></svg>` | ||
| export const EYE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none"><path d="M15.0007 12C15.0007 13.6569 13.6576 15 12.0007 15C10.3439 15 9.00073 13.6569 9.00073 12C9.00073 10.3431 10.3439 9 12.0007 9C13.6576 9 15.0007 10.3431 15.0007 12Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M12.0012 5C7.52354 5 3.73326 7.94288 2.45898 12C3.73324 16.0571 7.52354 19 12.0012 19C16.4788 19 20.2691 16.0571 21.5434 12C20.2691 7.94291 16.4788 5 12.0012 5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`; | ||
| export const MUSIC_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="20" fill="white"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>`; |
There was a problem hiding this comment.
This needs an attribution in README.md. If it was AI-generated, that is a hard reject.
There was a problem hiding this comment.
It's apache 2.0 but doesn't really matter since I'm collapsing all the submenus into one
The 400 @classic scene entries cluttered the map list while differing only in entity manifest (NPCs, mobs, warps) from their renewal aliases. Replace them with a single "Pre-Renewal Era" checkbox in the Layers panel that swaps the entity layer in place without reloading the scene. Era is a runtime selector backed by a ?era=classic query param. Toggling refetches <id>@<era>.json, tears down sprite/shadow/dust/label/warp-portal GPU state, and rebuilds with the new manifest. Camera, time of day, layer toggles all stay put.
…s in DataShare Adjacent maps reuse the same terrain BMPs, model RSMs, and water animation frames. Routing those loads through a DataShare-backed cache eliminates the fetch + decode + parse work on revisits and dedupes concurrent requests to the same asset. The cache holds only CPU data (decoded RGBA / parsed meshes); GfxTextures still live on the per-scene renderer and are recreated each load.
Previously each 8x8 GND lightmap tile became a layer of a 2DArray texture, which capped maps at MAX_ARRAY_TEXTURE_LAYERS (256 guaranteed by WebGL2; up to 2048 in practice). Large maps (WoE castles, prontera, dense outdoor fields) blew past that and failed to allocate the texture. Pack tiles into a square 2D atlas instead; the GND's reserved per-tile border means bilinear sampling stays inside each tile, so the change is invisible to the renderer beyond the UV remap. Vertex shrinks from 36 to 32 bytes (lightmap UV drops the layer index).
… maps Hash-diffing the pre-renewal kRO 2009 GRF against the current iRO renewal GRF surfaced 22 maps where Gravity actually rebuilt RSW/GND/GAT geometry (morocc, izlude, alberta, rachel, ...). Every model the pre-renewal RSWs reference is still in the renewal GRF, so the existing model/texture pool covers them; only the .rsw/.gnd/.gat triplets need staging as <id>@classic-suffixed files. regen-maps.ts now picks up <id>@classic.rsw siblings in the staged maps dir and emits dedicated scene entries with a "(Pre-Renewal)" name suffix and era: "classic". The scene loader overrides the RSW-embedded gnd filename for these scenes so the era-suffixed GND loads instead of the bare renewal one, and uses the bare base id for intra-map warp matching. The global "Pre-Renewal Era" toggle is hidden on dedicated @classic scenes because the scene id already pins the era. For the other ~378 entity-divergent maps with byte-identical geometry, the toggle continues to do a live entity swap.
The "re-" prefix was misleading: there is no separate initial-generation step, every invocation produces the same manifest from the staged inputs. Renaming to gen-maps to match the verb used by the other tools in this dir (extract-, audit-, validate-).
Manifest generation moved into its own tool (tools/gen-maps.ts) some commits ago, but the original parseMapNameTable + writeMapManifest implementation in extract.ts stuck around. Removing it along with the ASSET_MAP_NAME_TABLE and OUT_MAP_MANIFEST constants it referenced.
The original asset dump predates Episode 15+ content (verus, lasagna, ilusion, rockridge, ...) so hundreds of staged maps reference textures and models that never made it into data/RagnarokOnline_raw/assets/. The modern data.grf ships them, but it's the v0x300 "Event Horizon" variant the existing iro-grf/ Python reader doesn't understand. tools/grf.ts is a minimal TS reader for the v0x300 layout (u64 file-table offset, lowercased CP949 paths, no per-entry encryption flags). It's a small library, not a CLI. tools/extract-from-grf.ts uses it to walk every staged map, parse the referenced texture/model paths from its RSW/GND, and pull anything missing out of the GRF into the assets/ tree. Re-runnable; only copies what's actually absent. Run before tools/extract.ts when bringing in new maps so the CDN-staging pass has a complete source tree.
- render.ts: hoist EntityLayerBundle out of the import block; use clamp from MathHelpers in serializeSaveState; document the fog/light magic constants. Name the arrival-framing camera offset; drop the unused `= null` defaults from the renderer constructor (every callsite already passes every argument). - scenes.ts: fold the model and water-frame loaders into RagnarokSharedCache so the cross-scene cache owns all three asset kinds consistently; tighten a couple of let-without-type spots. Use clamp from MathHelpers for the fog density bound. - entity.ts: drop the redundant `// default "npc"` comment on EntityPlacement.kind; the default is encoded by the `?? "npc"` coalesce on the render side. - grf.ts: make the path field private. - gnd.ts / extract.ts / extract-from-grf.ts: trim the case-sensitive CDN explanations to one canonical comment in gnd.ts; drop the macOS-specific note from the GRF top-up tool.
# Conflicts: # src/RagnarokOnline/render.ts # src/RagnarokOnline/scenes.ts
8196a65 to
c77e119
Compare
Each surface stored one ARGB tint but the orig engine paints each top- quad corner with the surface color of the cell whose top-left lands on that corner (self / right / down / down-right), and walls borrow the matching neighbor colors. We were flooding the surface color across all 4 corners, so every tile edge showed a hard seam (visible as the staircase rim around dark sinkholes in moc_fild21 etc.). Sample the neighbors per corner so the GPU blends across boundaries.
fd4a576 to
3484ba1
Compare
| // data/RagnarokOnline_raw/assets/ | ||
| // Bulk-extracted GRF contents. Use tools/iro-grf/ (Python) for the iRO | ||
| // GRF; any standard reader works for legacy/. Layout mirrors the GRF. | ||
| // Stages 2 and 5 read this (data/maps, graphics/{texture,model,sprite}, | ||
| // data/misc/{mapnametable,fogparametertable}.txt). |
There was a problem hiding this comment.
You now have a grf parser directly in here so do we still need the Python iro-grf extractor?
There was a problem hiding this comment.
No, we dont, I'm going to modify read_grf.py with a --bulk-extract mode on Stage 1 so there's a single extractor.
probe_maps.py was an early prep script that nothing in the unified pipeline needs so it needs to be removed
| // data/RagnarokOnline_raw/iro_effecttool/ | ||
| // iRO effecttool .lub/.lua dump (per-map particle emitter specs). Side- | ||
| // channel client dump, not in the GRF. | ||
| // | ||
| // data/RagnarokOnline_raw/iro_eff_textures_all/ | ||
| // Pre-extracted effect textures the .lub emitters reference. Stage 3 | ||
| // copies the referenced subset into data/RagnarokOnline/textures/effect/. |
There was a problem hiding this comment.
What's the process to prepare these?
There was a problem hiding this comment.
It's a subset of the iRO GRF's data/texture/effect/ tree, originally extracted separately.
so the call here is to fold the path back into the shared assets/graphics/texture/effect/ (same place Stage 2 reads textures from) and dropping the separate dir
| // data/RagnarokOnline_raw/iro_tables/mapnametable.txt | ||
| // iRO English map name table. Stage 5 prefers this over the kRO Korean | ||
| // fallback at assets/data/misc/mapnametable.txt (which ships in the GRF). |
There was a problem hiding this comment.
Where is this retrieved from? Is it not in the iRO GRF?
There was a problem hiding this comment.
It's in the iRO GRF at data\mapnametable.txt, modifying Stage 5 so it now pulls it through the inlined Grf reader, and iro_tables/ is dropped from the inputs list.
The five stage scripts and the extract-all orchestrator collapse into src/RagnarokOnline/tools/extract.ts. Bare CLI args are the map-id filter; --only=stage1,stage2 (repeatable) restricts the run. The previously-missing extract-from-grf stage is now wired in.
3484ba1 to
6d5ff47
Compare
Stage 1 --bulk-extract dumps the whole iRO GRF (replaces tools/iro-grf/). Stage 5 reads the iRO mapnametable from the GRF directly. Stage 3 takes effect textures from assets/graphics/texture/effect alongside Stage 2. Header documents the mingw + wine build for the Granny baked outputs.
925e5c8 to
58f2815
Compare
Warning
The contributed code was written/generated largely by Opus 4.7
Follow-up to #911. Adds a Layers panel, fog/sun/sky overrides with share-URL persistence, and a music track picker.