604 Commits

Author SHA1 Message Date
0xcjy 9bc1dd8fcb Restore upstream runtime dependencies and clone-ready defaults [skip ci] tag 2026-10-02 22:00:37 +08:00
0xcjy d6efc31917 Publish current live selection and graphics source with external keys release-20261002 2026-10-02 12:07:33 +08:00
0xcjy 737d34db87 Remove PMX viewer section from README
Removed outdated PMX viewer instructions and related content.
2026-10-01 19:54:38 +08:00
0xcjy d70a65c7ce Publish verified live restoration source snapshot and known limits 2026-10-01 19:42:22 +08:00
0xcjy 0dd0d3bdaa Fix live monitor video and camera rendering 2026-08-10 10:54:07 +08:00
0xcjy fdc8635379 Live: add monitors, cyalumes, and skirt collision tuning 2026-08-09 22:55:16 +08:00
ritenseki c744e16fca StageBlend: report renderers, not just materials — one material covers the whole stage
The log said "1 of 31 materials corrected" and that read like a one-off fix for one lamp, which
prompted the reasonable question of why far more than one lamp got better. The count was right
and the unit was wrong.

Materials are heavily shared here: roughly 1500 renderers across live10149 draw from 31 unique
materials. The single corrected one, mtl_env_live10149_blinklight000 on LightBlinkBlend, is the
blink-light material for the entire stage — it appears in all 27 BlinkLight groups, about 1450
renderers: audience_light 95, mob000 570, glow_object 67, glow_ramp 58, the mirror ball flare
quads 83, every wash group, and the LED panels. So the same fix that cleared the ground wash
wedges is also why the small bulbs stopped rendering as black blocks, which had been sitting in
LIVE_TRACKS.md as an unexplained symptom.

The log now counts affected renderers alongside materials and prints the per-material tally, so
the blast radius is legible without cross-referencing the BlinkLight lines by hand.

Both docs are corrected in the same pass. The earlier note narrowed the claim correctly — only
materials whose current shader declares the property are touched — but by leading with "only 1"
it understated the result in the other direction. That is three scope misstatements about this
one fix in a day, so the rule now sits next to it: report the unit that matches the question
being asked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 14:32:17 +08:00
ritenseki 09d0373c00 docs: narrow the blend-state claim to what the live run actually showed
The fix is confirmed working — the black wedges are gone — but the log corrects the scope I
wrote yesterday. [StageBlend] reports 1 of 31 materials corrected, not the 26 the offline dump
suggested: mtl_env_live10149_blinklight000 on LightBlinkBlend, _DstBlend 0 -> 1, which is
exactly the ground wash beams.

Both numbers are right about different things. All 26 materials do store One/Zero, but a stored
value only matters when the current shader declares the property and reads it as render state.
Everywhere else it is another stale saved-properties entry that nothing consults — the same
trap this file already warns about, which I then walked into while describing the fix. The
self-limiting design held: only shader-declared properties were touched, so the other 30
materials were left alone.

Corrected in both places rather than left standing, since an overstated claim in these files is
what cost the most time this week.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 14:22:01 +08:00
ritenseki 662ba936aa Remove StageAnimationPlayer: a stand-in with guessed timing is worse than nothing
Its premise was that a single clip is an unambiguous instruction to play. It is not — it means
the object has one state, while whether that state is running was AnimationObjectController's
per-frame decision, and that class has zero serialized fields, so no amount of dumping recovers
it. What was left was policy invented here: the wash lights whipping through a 2-second sweep
the original does not perform, and a mirror ball turning at a rate nothing can validate.

After today's exclusions it took over exactly one object on live10149. Two hundred lines to spin
one ball at a speed we cannot check, in a subsystem that also claims — by existing — that this
area has been dealt with. That last part is the real cost: a wrong stand-in reads as done and
stops anyone looking again.

So the stage's 283 Animation components now play nothing, deliberately. The disco balls do not
turn, the wash lights do not sweep, the neon signs do not move. That is the honest state given
what is recoverable, and it is the prefab author's pose rather than our invention.

The file is renamed to StageMissingScriptCensus.cs, keeping only the census that was sharing it
— that one is a genuine progress meter for rebuilt signatures and never had anything to do with
animation playback.

One finding survives the deletion and is written into LIVE_TRACKS.md so a future attempt starts
from it rather than rediscovering it: do not drive stage animation with Animation.Play(), which
runs on Unity's own clock and desyncs the moment the live is paused or the scrubber moves. Set
AnimationState.time from LiveTimelineControl.currentLiveTime (seconds) and Sample(). The same
entry records why the feature is off, what would be needed to revive it (per-stage calibration
against reference footage, or IL2CPP metadata), and that the clip assets themselves are fully
readable — which is the trap, since knowing the asset says nothing about when the original plays
it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 14:19:00 +08:00
ritenseki 966e566112 docs: AnimationObjectController has no serialized fields — rebuilding it is a dead end
Asked whether the missing AnimationObjectController would be easy to implement, and the honest
answer was that nobody had dumped it. Dumping settles it: all 282 instances carry zero
serialized fields. It is pure behaviour.

So rebuilding its signature — the technique that paid off for BillboardController and
MirrorReflection — returns nothing here. It would take the missing-script count from 892 to 446
and yield not one bit of information. Which clip plays, whether it plays, and how fast all live
in the method body, and that is exactly what IL2CPP keeps from us. None of StageAnimationPlayer's
open timing questions can be closed this way; the direction is dead and is now marked as such so
the instance count does not tempt anyone back into it.

That also sharpens the triage rule added in the previous commit with a step zero: dump the
missing component's fields before deciding it is worth rebuilding. Instance count is not a proxy
for payoff — AnimationObjectController is the largest and worth nothing, while CustomLensFlare
carries a full field set and led to LensFlareData.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 14:12:14 +08:00
ritenseki 0ccf6b09f4 docs: record the triage rule — a stage element behaving wrong usually means a missing component
Two of this session's bugs had the same shape, and naming that shape is worth more than either
fix: the wash lights whipping back and forth, and the billboards spinning. In both cases the
data was fine — clip curves and serialized fields dumped clean and checked out — and what was
wrong was behaviour we had inferred on behalf of a script that does not exist.

So the default hypothesis for "this stage element moves when it shouldn't / doesn't move when it
should / moves at the wrong rate" is now written down as: the original component is missing and
something of ours is standing in for it. Not: the data was parsed wrong. That is justified by
the ledger — 728 MonoBehaviour instances are still empty, AnimationObjectController alone
accounting for 282, and every decision about what animates and when lived in those method
bodies. Data is dumpable and has repeatedly proven correct; behaviour is the part we cannot
retrieve.

Two practical corollaries go with it: check what scripts an object carried and whether we have
them ([StageScripts] plus the signature list) before suspecting the parser; and when standing in
for a missing component, say in the source whose decisions you are making, and mark whether the
rule came from bundle data or from watching reference footage. The latter is real evidence but
not ground truth, and may not hold on another stage.

The counter-example is recorded in the same breath so the rule does not become a reflex: the
black light shafts were a data problem after all — every material carries a URP Lit property
table whose opaque preset (_DstBlend = Zero) overrode the additive blend 14 of the 16 relevant
shaders declare. That one was found by dumping, and the general lesson — a stale saved-property
table can override render state, not just colour — now sits next to the existing warning about
saved properties.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 14:10:19 +08:00
ritenseki 1ee570f3e9 StageAnim: stop free-running the wash light sweep clips
"Only one clip" tells you the object has only one state. It does not tell you that state is
playing — that decision belonged to AnimationObjectController, which we do not have. The
takeover rule conflated the two, and wash_ground_b/c/d is where it shows: their single clip
swings the swing_* node 90deg -> 0 -> 90deg every 2.0 s, twelve lamps in lockstep, so the whole
row sits there whipping back and forth. The reference MV has the ground wash lights holding
still and blinking instead.

Same failure shape as the billboard facing behaviour: the target objects were verified, the
behaviour was inferred. Sweep rigs (name contains _wash_, the same test StageController already
uses to identify wash lights) are now skipped and logged.

The mirror ball keeps playing. Its clip winds monotonically to -359 deg about Y, which is a
self-evident idle spin, and the ball does turn in the original. Whether it turns at 1.0x is
still unsupported and stays on the unknown list.

Recorded in the source that this exclusion comes from watching reference footage, not from
bundle data, so a stage whose wash lights genuinely do sweep needs new evidence rather than an
argument from this line.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 13:59:22 +08:00
ritenseki f75e6fdd1f Stage: restore the authored blend state that a URP Lit property table overwrote
Chasing "why does this ground wash light keep swinging as a black wedge" landed on something
much wider than one lamp.

Gallop's light shaders take their blend state from material properties — LightBlinkBlend and
friends declare `Blend [_SrcBlend] [_DstBlend]`. Every one of live10149's 26 materials stores
_SrcBlend=One, _DstBlend=Zero, i.e. opaque overwrite. That is not authoring intent: all 26 also
carry _WorkflowMode, _Surface, _ClearCoatMask, _Smoothness and _Blend in their float tables,
which is URP Lit's property set, and One/Zero is URP Lit's opaque preset. The table was stamped
over the whole batch.

The authored values are recoverable, because the shaders declare their own defaults. Of the 16
shaders in the bundle that expose these two properties, 14 default to One/One — additive — and
they are exactly the emissive family: LightBlinkBlend, LightBlend, StageBeamLight and its
Cutoff/Fadeout variants, StageLightBlinkCutoff/Fadeout, the three StageProjectorBlend variants,
StageMonitorBlend*, MirrorBallProjector, BgUnlitStencilAlpha.

Forced opaque, an additive beam whose _BlinkLightColor is black stops being "adds nothing, so
invisible" and becomes a solid black wall — which is what the swinging wash beams look like on
screen, and very likely also what LIVE_TRACKS.md has been recording as "small bulbs render as
black blocks".

So on stage init, every material whose shader declares _SrcBlend/_DstBlend gets those reset to
the shader's declared default. The correction is self-limiting: for a shader that really is
opaque the default is already One/Zero and nothing changes. Only properties the current shader
actually declares are touched — the material's saved table is the thing we do not trust here,
so it is not consulted for what to write.

Every change is logged with material, shader and before/after, so the next run says exactly what
was corrected rather than leaving it to inference.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 13:57:41 +08:00
ritenseki 3b4485506a Billboard: fix the stale camera reference, and gate the unverified facing behaviour off
Reported from a live run: a light keeps rotating, and the object visibly should not be
rotating. Two separate problems, only one of which is a bug.

The bug — BillboardController resolved its target camera once and cached it forever, while
Director.MainCameraTransform is reassigned every frame (_cameraTransforms[_activeCameraIndex])
and switches between three cameras whenever the CameraSwitcher track fires. After the first
switch the billboards face a camera the viewer is not looking through, and that camera keeps
moving along its own timeline — which reads exactly as "spinning for no reason". Now resolved
per frame. Any stage script that references "the current camera" has this hazard.

The guess — whether _rotationType == 0 means "face the camera on all axes" at all, and whether
the up vector should be the camera's (screen-aligned, rolls with the shot) or world up (yaw
only), have no ground truth behind them, and the two look completely different on screen. Per
the project rule, that goes off: EnableRotation now defaults to false, same treatment as
PostFilmRendererFeature._enableRendering. With it off the quads keep the orientation the prefab
author gave them, which is real data rather than my inference.

Target selection was checked rather than assumed, and it holds up: all 106 type-0 instances are
named *_billbord / *_billboard / glow_plane / spotlight, all 106 carry a MeshRenderer, and the
lamp bodies are further up the chain (swing_ < arm_ < stand_). So "these should billboard" is
probably right; "how they should turn" is what is unsupported.

Docs also walk back an over-claim from 050a2c9. That commit said the mirror ball rotation was
settled and "already correct in our build". The clip rate is ground truth for the clip
(-179.50 deg/s, and currentLiveTime is in seconds so there is no unit error), but the same live
run reports the balls are still too fast — so the original either applies a playback multiplier
or does not drive the ball with this clip at all. Data settles the asset, not what the original
does with the asset. The multiplier goes back on the unknowable list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 13:41:37 +08:00
ritenseki f5368031af docs: settle the mirror ball rotation question with dumped data
Chased the lead that MirrorBallProjector's shader might cross-validate the ball's rotation
speed. It does — by showing there was never an unknown constant to recover.

  * All four MirrorBallProjector instances on live10149 carry MirrorBallIsLoopRotation = 0,
    MirrorBallLoopRotationSpeed = 0, MirrorBallLoopRotationValue = 0. The shader's own
    loop-rotation path is switched off on this stage, so it is not the rotation source.
  * The source is the clip StageAnimationPlayer already plays. Its six quaternion curves
    (mirrorball_a_000 and b_000..004) give a constant -179.50 deg/s about Y — the same figure
    at every one of the seven keys — 2.0 s per loop, last key -359 deg so the loop seam does
    not repeat a frame. The ball speed in our build is therefore already correct.

The general lesson is recorded too: "the value is 0" and "the value is unknown" are different
findings, and this one was filed as the latter for weeks. Check the enable flag before
declaring a constant unrecoverable.

What genuinely is blocked here is narrower than "the script's behaviour": the shader wants
_MirrorBallPosWS / _MirrorBallScale / _MirrorBallRotateValue, the component holds no reference
to any ball, all four projectors sit at the origin sharing one material, and the balls are at
six scattered positions. The object-to-object binding lives in the method body. The Blocked
section now says that instead of using this field as its example.

Two other things fell out of the same dump pass:

  * LensFlare is not a "build a system from scratch" item at all. CustomLensFlare's Flare
    points at Gallop.RenderPipeline.LensFlareData — a ScriptableObject in the same assembly,
    so rebuildable by signature — whose fields are a verbatim copy of Unity's legacy Flare
    (TextureLayout, Texture, ElementArray[ImageIndex/Position/Size/Color/UseLightColor/
    Rotate/Zoom/Fade], UseFog). That means the semantics are Unity's own and not blocked by
    IL2CPP, and URP ships LensFlareComponentSRP as the target. 199+5 objects carry it, and
    the stage has no legacy LensFlare component anywhere. Promoted to the next thing to do.
  * ShaderParamController, previously ranked "cheapest", is a no-op: its only two entries are
    _AmbientColor and _CharaColor, both (1,1,1,1). Struck from the list rather than left as
    bait.

The stale-saved-properties warning gains a worked example, because mtl_env_live10149_
projector001 is a good one: 40+ saved entries against 22 real ones, including _IsLoopYRotation
and _LoopYRotationSpeed, which are older spellings of properties that do exist — a near-miss
that reads as a discovery.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 13:29:20 +08:00
ritenseki 050a2c9a2f docs: bring the maps up to where the code actually is
Several rows had gone stale, and two of them were actively misleading — the kind that sends
the next session down a path that has already been closed.

Corrected claims:
  * "LensFlare — UmaBuild has no source" is wrong. Rebuilding a class from its signature gets
    the real serialized fields; only the method bodies are unrecoverable. The row is marked as
    a correction rather than quietly edited, because it is the assumption that kept 892
    MonoBehaviour slots written off as unreachable.
  * "Environment (58) — planar reflection does not exist at all" is no longer true.
    MirrorReflection implements the whole second-camera -> RT -> mirror-shader path; what the
    track still needs is its keyframes routed into it, which is a much smaller job than the
    "build a rendering system from scratch" tier it was filed under.
  * The floor blow-out and the BlinkLight palette slot mapping are both listed as open
    problems in LIVE_TRACKS.md. Both are solved; the slot rule is recorded (slot = the
    lightNNN_/alphaNNN_ prefix of the renderer or its nearest ancestor), and the floor entry
    keeps the fact that the symptom belonged to a different object than the one documented,
    since that is the reusable part.
  * The audit's C4 row still said "located to DefaultEnvMapNoAmbient, diagnostic added", which
    the section below it had already overturned.

Added: the stage-script table now carries per-class status, so the two that are built are
distinguishable from the eight that are not; what a rebuilt signature does and does not give
you (MirrorReflection got behaviour because the receiving shader was identifiable,
BillboardController stopped at data because _rotationType is an enum); StageAnimationPlayer
and why it samples currentLiveTime instead of calling Animation.Play(); the shared property
block convention and the Get -> modify -> Set rule that goes with it; HdrBloom marked as
deliberately handler-less rather than "safe to delete".

The audit gains a closing section for the work that came after it, and its suggested order now
records which items landed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 13:10:36 +08:00
ritenseki 30ef1b1929 cleanup: one shared property block, explicit resolve report, drop dead diagnostics
No behavioural change intended; this is the tidy-up pass after five rounds of track fixes.

Director.cs
  * Six MaterialPropertyBlock fields (chara / bgColor1 / bgColor2 / spotlight / uvScroll /
    blinkLight) become one shared `PropBlock`. Every use is the same self-contained
    Get -> modify -> Set, and the block carries no state across frames or handlers, so the
    separate fields were pure duplication. The reason the Get is mandatory (SetPropertyBlock
    replaces rather than merges — this is what made GlobalLight dead for 59/59 songs) now
    lives on the one shared field instead of being restated per handler.
  * ResolveStageTargets wrote four instance fields as de facto out-parameters that
    LogBgColor1Resolution read back. Replaced with a returned StageResolveReport, which also
    lets the logger become static. `props` is now a required parameter — the `= null` default
    silently meant "BgColor1's channel", which is the wrong default for a BgColor2 caller.
  * Three duplicated blocks removed: shader-description building (BgColor1 and BlinkLight
    logs -> DescribeRendererShaders), vocal entry resolution (InitializeMusic and
    GetLiveAllVoiceEntry -> ResolveVocalEntry), and the FOV frame marking copied verbatim
    into SaveCameraVMD and SaveMultiCameraVMD (-> MarkFovFrames, which additionally no longer
    throws on an empty frame list).
  * OnEffectUpdate's three identical "record the frame, bail out" branches collapse into
    LoadEffectPrefab returning null.
  * HdrBloom's handler and the Bloom volume override are gone. hdrBloomKeys is empty in all
    59 songs, and the field-to-URP mapping was never confirmed — so this was code that could
    only ever be wrong, plus an effect nobody wrote to. The data layer and the dispatch stay,
    so re-adding it is one subscription.
  * The BlinkLight TODO no longer lists palette slot mapping: that was reverse-engineered
    (slot = the lightNNN_/alphaNNN_ prefix of the renderer or its nearest ancestor).

StageEnvMapDiag.cs deleted (with StageEnvRateToggle and its F9 hotkey). It existed to test one
hypothesis — that the floor blow-out came from DefaultEnvMapNoAmbient's env reflection — and
the verdict experiment ran: _EnvRate = 0 changed nothing. The real cause turned out to be
mirror_a and is fixed. Keeping it meant a full-hierarchy sweep on every stage load and a
hotkey, for a question already answered.

StageController no longer calls it; StageMissingScriptCensus's doc comment stops restating the
signature list that CLAUDE.md already carries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 13:10:13 +08:00
ritenseki 390d715d42 Live: register PostFilmRendererFeature in the URP renderer asset
The feature was added in a3a7b83 but never wired into
UMAUniversalRenderPipelineAsset_Renderer.asset, so its passes could not run at all. This
registers it, with _enableRendering left at 0 — the data layer (three tracks -> Layers) is
verified, but the vignette geometry is not: the shader that defines it ships in the app's own
resources.assets and is absent from all 499 shaders in the `shader` bundle, so drawing would
be a guess. Registering it now means enabling the flag is the only remaining step.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
2026-08-07 13:10:10 +08:00
ritenseki 546d8ef7ba Live: implement MirrorReflection — and it resolves the stage floor blow-out
Rebuilt Gallop.MirrorReflection from its original signature, so Unity deserializes the real
fields out of the bundle rather than anything being inferred. All 13 field names are copied
verbatim from the TypeTree, including the original's typo `_mirrorCliipPlaneOffset` — spelling
it correctly would silently receive no data.

The receiving end was looked up, not guessed. mtl_env_liveNNNNN_mirror000 uses
Cygames/MirrorAndShadow/ReceiveMirror, which declares exactly four properties — _MainTex,
_ReflectionTex, _Color, _ReflectionRate — and the component's _mirrorReflectionColor and
_mirrorReflectionRate line up with the last two name for name. Texture size, cull mask, clear
colour and clip-plane offset all come straight from the serialized values, which differ per
stage (256/12544 on live10149, 512/12288 on live10132), confirming real data is arriving.

Deliberately not implemented, because there is no ground truth for them:
  * _direction is an enum whose meaning is unrecoverable — IL2CPP metadata is encrypted.
    The mirror plane is derived from the mesh's own normals instead, which is geometry rather
    than a guess, and yields (0,1,0) on both stages. The field's value is logged as unused.
  * _mirrorDistortionTileOffset / _mirrorDistortionPower belong to the ReceiveDistortionMirror
    variant; these materials use the plain one.
  * _useMirrorTextureScale / _mirrorTextureScaleForBaseCamera — semantics unknown.

Rendering goes through RenderPipelineManager.beginCameraRendering and RenderSingleCamera.
Camera.Render() is not supported under SRP and would have failed silently.

This also settles the long-standing floor blow-out, and the diagnosis I had been running was
aimed at the wrong objects the entire time. ReceiveMirror's _ReflectionRate defaults to 1.0
while _ReflectionTex had never been assigned, and Unity substitutes a white texture for an
unbound sampler — a full-strength white reflection, i.e. a solid white floor. Binding the
reflection RT fixes it.

CLAUDE.md recorded the blown-out objects as plane_000 / stage_object_001 / specular_002 and I
took that as given, spending four rounds eliminating mechanisms on those three. The actual
culprit is mirror_a, which sits at the same position and scale under the same parent — visually
indistinguishable, entirely different name. The earlier "_EnvRate = 0 changes nothing" result
was consistent all along: it was toggling a different set of objects.

Both files gain the lesson: field values and shader property tables are hard data, but a
document's description of which object looks wrong is not, and a visual bug should start by
confirming which object the symptom belongs to.

Water surfaces are absent, not broken — none of the three downloaded stages has a ReceiveWater
material; each has exactly one ReceiveMirror.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 14:45:12 +08:00
ritenseki 4d7a7c3373 Live: rebind the stage's own scripts; fix mirror ball colour; map what is recoverable
The big finding is structural, and it corrects something I asserted two commits ago.

Stage prefabs reference 11 script classes and UmaViewer implemented one of them, leaving
892 MonoBehaviour instances with a null script. I claimed those serialized fields were
unreachable at runtime and that reimplementing the scripts would need name heuristics or a
baked parameter table. That was wrong, and the diagnostic I wrote to confirm it disproved it
instead: among the 7 surviving components were AssetHolder (bundle namespace Gallop) and
StageController (Gallop.Live). Unity resolves MonoScript by class name + namespace +
assembly, and Assets/Scripts/umamusume.asmdef is named "umamusume", exactly matching every
MonoScript in the bundles. The project was organised for this from the start — it is the same
mechanism LiveTimelineWorkSheet relies on to read cutt data.

So the 892 are simply unwritten. Declaring a class with the matching signature makes Unity
deserialize the real fields.

BillboardController (Gallop.Live, 164 instances) is the first one rebuilt, and it confirms
the mechanism: missing-script count drops 892 -> 728, exactly -164. _rotationType is now read
per object rather than guessed. Type 0 (106 objects) faces the camera; type 2 (58, all
glow_ramp) is logged and left alone — the enum's meaning is not recoverable, see below.

BlinkLight palette slots — the mirror ball was solid pink
  * color0Array/powerArray are a 10-slot palette and every renderer was taking slot 0.
    The slot is the object's own or nearest ancestor's `lightNNN_` / `alphaNNN_` name prefix.
    Confirmed across all groups on live10149: the number of distinct prefixes equals the
    number of distinct colours in slots 0..N-1, with slots N..9 uniform white filler, in
    every group without exception. mirrorball 3 (pink/blue/yellow), wash_truss 4, glow_object
    2, audience_light 9.
  * Renderers with no prefix are not palette lights and are now skipped when the group has
    any. The mirror ball body uses Gallop/3D/Bg/BgMirrorBall, whose _MulColor0 belongs to
    BgColor1 — which drives it to white, the silver ball seen in the reference footage.
    BlinkLight runs after BgColor1 and was overwriting it with palette pink.

Stage animation is now driven by the timeline, not Unity's clock. Using Animation.Play() plus
a default clip with playAutomatically meant the stage kept moving while the live was paused
and ignored scrubbing. AnimationState.time is now set from currentLiveTime and sampled.

CLAUDE.md gains a ground-truth map: what the bundles yield, the rebinding trick above with
its signature table, and what is permanently blocked. global-metadata.dat is neither on disk
nor inside GameAssembly.dll (magic 0xFAB11BAF absent, identifier strings absent) — the game's
anti-tamper keeps it encrypted until runtime. Every enum's meaning, the original method
bodies, and any tuning constants are therefore unrecoverable; rebuilding a signature yields
data, never behaviour. The mirror ball's 2.0s-per-revolution is authored in the clip and
reproduced faithfully; if the reference looks slower, the factor lives in code we cannot read.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 14:25:37 +08:00
ritenseki b2c607b7d8 Live: play the stage's own Animation clips (missing AnimationObjectController)
The stage prefab references 11 script classes and UmaViewer implements exactly
one of them (StageController). The other ten deserialize with a null script
reference and never run: AnimationObjectController, BillboardController,
CustomLensFlare, UnityLensFlareController, CustomProjector, LightProjection,
MirrorBallProjector, MirrorReflection, ShaderParamController, WashLightController.

AnimationObjectController's absence has the most visible effect. live10149 has
283 Animation components, all 283 with playAutomatically = true and all 283 with
a null default clip. playAutomatically plays the default clip, so a null one
plays nothing — the original drives them with an explicit Play(name). The result
is that no stage animation runs at all: the mirror ball does not spin, the wash
lights do not sweep, the neon signs do not move.

Only the unambiguous case is handled. Clip counts per component are 1 (4
objects), 3 (6), 5 (272) and 0 (1). The single-clip objects are all named
*_loop_000 — mirrorball_flarelight and wash_ground_b/c/d — and are played. The
3-clip sets are loop_000 / up_000 / loop_001, a transition plus two loop states,
and AnimationObjectController carries no serialized fields at all, so nothing in
the data says which to pick or when to switch. Those and the 5-clip sets are
logged with their clip names and left alone rather than guessed at.

Playback happens in OnEnable, not once at init: timeline-controlled lights start
inactive and Play() does not stick on an inactive object. The mirror ball's
container is pfb_env_live10149_blinklight_mirrorball_flarelight, which is exactly
that case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 13:51:20 +08:00
ritenseki 652c306099 docs+diag: audit report, stage env-map diagnostic, verified/unverified marks
LIVE_AUDIT_2026-08-05.md records the audit behind the previous commit: the
evidence for each fix, the tool invocations that produced it, and — deliberately
— the three conclusions I got wrong before the data corrected them, since each
was a plausible-sounding guess:

  * "66 same-named wash lights stay lit" — that 66 is the mob_a000 crowd, not
    lights. live10149 has 4 duplicated light names, 10 objects.
  * "the light handlers need name -> List support first" — every one of song
    1177's 28 BlinkLight group names maps to exactly one GameObject; the groups
    address containers and GetComponentsInChildren already covered the children.
  * "plane_000 should look lighter than the other two" — _EnvRate 0.75 vs 1.00
    cannot be distinguished once the term saturates to white, so that comparison
    could never have decided anything either way.

Also records which song exercises which fix, since only 1177 is downloaded
locally and it carries no bgColor2 / spotlight3d / transform data.

Stage floor blow-out (plane_000 / stage_object_001 / specular_002): four
mechanisms now ruled out rather than one cause found. Not lighting — live10149
has 10102 GameObjects and zero Light components, and the Live code never touches
Light at all. Not a missing reflection texture — StageEnvMapDiag reports 0 of 3
null. Not the unwritten _ColorPower — BgColor1's power field has a median of
1.000 on all three groups, which retroactively supports reverting that write.
Not the env reflection term — F9 zeroes _EnvRate on all three renderers, and the
log confirms it fired nine times with no visible change. Also corrects a sampling
error of mine: frame 0 is near-black, but across all 257 keys the floor's median
luminance is 0.548 and 81% of keys exceed 0.3, so it is meant to be bright for
most of the song. Next binary test is forcing _MulColor0 to black.

StageEnvMapDiag logs the env-map bindings once at stage init and attaches an
opt-in F9 toggle that flips _EnvRate between its authored value and 0 through a
property block. Diagnostic only; inert unless the key is pressed.

LIVE_DEV_MAP.md now separates "implemented" from "checked". Ten rows drop to
"OK?" because nobody has verified them — this session found four tracks that
were marked done and had never once produced output, so an unchecked mark is
not evidence of health. GlobalFog drops to partial: its data is height fog
(isDistance=0, isHeight=1) but the handler enables Unity distance fog, and
RenderSettings has no height fog. The claim that BlinkLight and Spotlight3d
drive child Light components was wrong and is corrected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 13:42:47 +08:00
ritenseki 64087b534e Live: fix five silently-failing track paths + one init bug
All found by auditing the tracks LIVE_DEV_MAP marked as done. Every one of
them parses its keyframes correctly and then drops the result downstream with
no error, so the picture looks plausible and nothing ever surfaces the failure.
Verified against the bundles with tools/ before changing anything.

GlobalLight (48) — 9636 keys / 59 songs, never worked
  * Renderer.SetPropertyBlock() replaces the whole block rather than merging.
    AlterLateUpdate runs GlobalLight then BgColor1, and both allocated a fresh
    block for the same container.Renderers, so BgColor1 wiped all 13 rim
    properties every frame. Song 1177 carries GlobalLight x2 and CharaColor x2,
    and bgColor1/globalLight both cover 59/59 songs — this was never once live.
  * Both handlers now GetPropertyBlock -> modify -> SetPropertyBlock, sharing
    one persistent block. The stage-side BgColor1 branch and BlinkLight already
    did this; the two character-side handlers were the only exceptions.
  * _UseOriginalDirectionalLight / _OriginalDirectionalLightDir moved into the
    block too. They were written through renderer.materials, which instantiates
    a material copy and allocates an array on every frame, per renderer.

BgColor2 (9) — 14346 keys / 15 songs, at most one group survived
  * The dispatcher never filled the group name and the handler never read one,
    so up to 15 groups (son1010 carries BgWashA..BgWashO) each repainted the
    entire stage every frame and only the last one in list order survived.
  * Name is now threaded through and resolved via ResolveStageTargets, writing
    _AmbientColor through a MaterialPropertyBlock, resolved once and cached.
  * The name -> renderer mapping is still unknown and is NOT guessed here.
    BgWashA..O / LaserA..C are neither GameObject names nor _stageObjectUnits
    unit names (the three downloaded stages use concrete names like neonsign),
    and BlinkLight carries no index back into BgColor2. Unresolved names fall
    back to the previous whole-stage write and log a warning, so behaviour is
    never worse than before; delete the fallback once the mapping is known.

Spotlight3d (68) — 1089 keys / 31 songs
UVScrollLight (46)
  * Both wrote _Color. Enumerating all 499 shaders shows no Gallop/3D/Live/Stage
    shader declares it — the only two stage/Bg shaders that do are BgShadowOnly
    and RedAlphaGreenColorShadowFogUVScroll, neither related. Spotlight beams are
    StageBeamLight*, and UVScroll targets LightAdd1_UV and
    StageLightAdd1_UVAlphaMask_TransmittedLightMask; all use _MulColor0 /
    _MulColor1 / _ColorPower. The colour write was a no-op while _ColorPower kept
    working, so the lights tracked the music in brightness but never in colour.
  * This is the same defect as the BlinkLight _Color bug fixed in a3a7b83, twice
    over. "The property exists" is not "the target shader has it" — all three
    slipped through on that distinction.
  * UVScrollLight also gains the previously unused mulColor1, and both now use
    MaterialPropertyBlock with cached lookups instead of walking every renderer
    on the stage and touching r.materials each frame.

Transform (31) — 681 keys / 12 songs, never worked
  * UpdateTransform only consulted StageObjectUnitMap and had no else branch, so
    a group named after a GameObject silently did nothing. son1028's first group
    is light001_glow_001. This is the mirror image of the Object-track fix in
    a3a7b83, which was missing the unit-name path instead.
  * Also strips "(Clone)" on the child lookup, which UpdateObject already did.
  * TypeTree confirms LiveTimelineKeyTransformData has only position/rotate/
    scale and no OffsetType, so absolute writes are correct here.

StageController init — 4 permanently dark lights on live10149
  * SetActive(false) sat inside the dedupe check, so among same-named objects
    only the first was disabled. Track groups address containers, and the lights
    are their children: light001_wash_ground_a (x4), swing_wash_ground_a (x2),
    base_rotate_wash_ground_a (x2) and light000_wash_ground_a (x2) all sit under
    pfb_env_live10149_blinklight_wash_ground_a. The handler re-enables only the
    container, so that one disabled child was never turned back on.
  * Now only the topmost timeline-controlled light in each branch is disabled;
    descendants keep their prefab state and follow the parent. Dedupe and insert
    also agree on the stripped name now.

Only GlobalLight could be verified in the editor — song 1177 carries no
bgColor2, spotlight3d or transform data. The rest is code review plus bundle
ground truth.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 13:42:18 +08:00
ritenseki d6c262ba93 docs: correct the track data, record what is blocked and why
The pre-2026-08-04 scan data was wrong in two systematic ways, and acting on
it wasted real time. Re-measured everything with tools/ against all 59 songs.

  * Eleven tracks marked "WorkSheet 无 X 字段" do have the field, several with
    substantial data: MobControlKeys (2392 keys), CyalumeControlKeys (2372),
    nodeScaleList (57/59 songs), monitorCameraPos/LookAtKeys, sweatLocatorList,
    facialNoiseKeys, charaMotionNoiseKeys, LipSyncPattern*, and the multi-camera
    bloom keys. These are "just needs a C# declaration", not blocked.
  * Six tracks marked "全 0 keyframe 空占位" carry thousands of keys. PostFilm
    is the worst case at ~20200 keys over 59/59 songs; live-shader-todo.md was
    right to rank it first and LIVE_TRACKS.md was wrong to write it off.

Rows that have been re-measured are tagged ✅实测; untagged rows are still old
data and should be re-verified before anyone acts on them. Priorities are now
ordered by measured data volume crossed with the kind of work required.

Also recorded:
  * The stage shader colour/brightness channel table, and the warning that a
    material's m_SavedProperties lists properties its current shader no longer
    has — enumerate the shader, never trust that table.
  * A working rule: no ground truth, no implementation. Guessing cost two wrong
    PostFilm vignette implementations before it turned out the defining shader
    is not shipped in any bundle. Note that "the property exists" is not "this
    field maps to that property" — that distinction is why BgColor1's power ->
    _ColorPower write was reverted while BlinkLight's was kept.
  * A 「已知未解问题」 section splitting open items into: has ground truth so
    can be built, lacks it so disabled, and rendering problems unrelated to the
    timeline (the stage floor blowing out predates all of this work; the small
    bulbs render black because their shaders expose no colour property at all).
  * Song 1177 (stage live10149) is the reference song used throughout. Earlier
    notes said 1157, which was wrong — that song uses stage live10146.
  * The old UmaCrack tool paths are gone; tools/ replaces them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 01:12:22 +08:00
ritenseki a3a7b83236 Live: fix six silently-failing track paths, add PostFilm data layer
Every fix here is the same shape: the keyframe data was already parsed
correctly and then dropped somewhere downstream, with no error logged.
Found by dumping the authoritative schema with tools/ and comparing against
what the handlers actually consume.

BgColor1 (8) — the largest track in the corpus, 43617 keys / 59 songs
  * AlterUpdate_BgColor1 filtered on a `validBgColorNames` whitelist of four
    character group names, discarding the other 16 stage groups outright.
    On song 1177 that is ~92% of the track's keys. Filter removed; Director
    now routes by group name (characters vs stage).
  * Stage branch resolves renderers by walking the whole stage hierarchy.
    StageObjectMap alone is not enough: it dedupes by name, and crowd groups
    have 66-570 same-named objects, so only the first was ever coloured.
  * Writes _MulColor0, confirmed by enumerating the shaders' property tables.
    _AmbientColor belongs to BgColor2 — they are separate channels on the
    same shader and must not be written by both.
  * Populates fields the dispatcher had always left at default: colorPower,
    scale, vertexColorToonPower, outlineWidthPower, LightBlendMode,
    IsSilhouette, IsProjector, TimelineName.

Object (33) — the neon sign never descended from the ceiling
  * The group name `neonsign` is a StageController._stageObjectUnits *unit*
    name; no GameObject of that name exists, so the whole track never fired.
    UpdateObject now falls back to StageObjectUnitMap and applies to each
    child of the unit.
  * ObjectUpdateInfo.OffsetType was populated by the dispatcher but never
    read, so Add-relative positions were written as absolute and objects
    snapped to their parent's origin. Now honoured against a lazily captured
    base local TRS.

BlinkLight (45) — 19420 keys / 57 songs, the biggest lighting payload
  * Wrote _Color, which does not exist on Gallop/3D/Live/Stage/LightBlinkBlend
    (its colour channel is _BlinkLightColor), so the write was a no-op and the
    lights rendered black. Now probes the shader for the real property.
  * Brightness goes to _ColorPower instead of being folded into the colour,
    falling back to colour*power only where that property is absent.
  * Uses MaterialPropertyBlock; the old path hit Renderer.materials every
    frame, allocating and breaking batching.

PostFilm (39) — ~20200 keys / 59 songs, previously recorded as empty
  * Data class fields reordered to the bundle's TypeTree order and the five
    missing BlinkLight* fields added; LiveTimelineKeyPostFilmDataList created;
    postFilmKeys / postFilm2Keys / postFilm3Keys declared on the worksheet.
    Runtime now deserializes 100 / 161 / 87 keys on song 1177.
  * AlterUpdate_PostFilm dispatch with interpolation, PostFilmUpdateInfo,
    a URP ScriptableRendererFeature and a full-screen blit shader.
  * Rendering is disabled by default: filmOptionParam's geometry is undefined
    anywhere we can read. All 100 keys on song 1177 are Vignette variants, so
    that parameter decides the whole look, and the shader that defines it is
    not in the `shader` bundle (all 499 searched by name and by property
    signature) — it ships inside the app binary.

Diagnostics
  * LiveTimelineWorksheetDiag dumps every track field with group names and key
    counts, and Probe() tests whether a candidate field name matches the
    bundle TypeTree. Confirmed worksheetList.Count == 1 (SheetType MainLive),
    and that WashLightList really is spelled with a capital W — upstream
    katboi01 uses washLightList, which never populates.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 01:11:57 +08:00
ritenseki fbdc97c164 tools: rebuild the asset dump toolchain in-repo
The previous toolchain (C:\Users\riten\Desktop\UmaCrack\) was deleted, taking
with it the only way to read authoritative field names out of the game bundles.
Reimplemented from the decryption logic already in Assets/Scripts.

- uma_common.py        key constants, bundle XOR, MetaDb (path->hash, UnityPy load)
- dump_meta.py         decrypt meta -> meta_plain.db; find / info / songs
- dump_bundle.py       list / tree / json / save / gameobjects for any bundle
- dump_cutt_typetree.py  authoritative LiveTimelineWorkSheet schema per song
- scan_live_tracks.py  all 59 songs -> out/scan_{keys,groups}.csv, scan_summary.txt

cutt bundles ship full TypeTrees, so field names and keyframe counts read back
out of them are ground truth. All 70 worksheets across all 59 songs share one
128-field schema.

Needs UnityPy + apsw-sqlite3mc (not plain apsw); see tools/requirements.txt.
Generated output under tools/out/ is gitignored (meta_plain.db alone is 151 MB).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 01:10:07 +08:00
ritenseki 7fc1511fd4 Fix StageController light filter: use explicit patterns instead of Contains("light")
Replace broad Contains("light") with IsTimelineControlledLight() that matches
only objects actually controlled by timeline handlers (blinklight, spotlight3d,
_wash_, laser). Neonsigns, glow meshes, UV scroll objects and other static stage
props now keep their prefab default state instead of being silently disabled.

Also fix UVScrollLight handler to use GetComponentsInChildren<Renderer>(true)
so inactive renderers are included in material search.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 20:19:45 +08:00
ritenseki e76dd1c6f0 Fix BgColor2 to write _AmbientColor on stage materials
Replaces incorrect RenderSettings.ambient* with per-material
_AmbientColor writes on stage renderers, confirmed via live10106
material dump.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 19:52:38 +08:00
ritenseki d0c1a20e95 Add LIVE_DEV_MAP.md; split live-shader-todo.md to post-processing only
LIVE_DEV_MAP.md: architecture overview, track→API mapping, blocked track
categorization, and implementation priority ordering.

live-shader-todo.md: trimmed to post-processing effects only (URP Volume
and ScriptableRendererFeature tracks), with updated coverage numbers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 18:58:59 +08:00
ritenseki 04d8db3bb1 Fix UVScrollLight offset accumulation; update track docs
scrollSpeedX/Y was incorrectly passed to SetTextureScale (tiling),
now accumulated as per-frame offset delta on top of keyframe scrollOffsetX/Y.
Added _uvScrollAccum dict cleared on InitializeTimeline.

Also updated LIVE_TRACKS.md with full-scan coverage numbers and
live-shader-todo.md with blocked-track categorization.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 18:55:17 +08:00
ritenseki 5fdbad92d2 Fix BgColor2 dispatch and unify Director handler style
- Fix LiveTimelineBgColor2Data.keys type (BgColor1DataList → BgColor2DataList)
- Add AlterUpdate_BgColor2 call and implementation in LiveTimelineControl
- Subscribe OnUpdateBgColor2 in Director with ambient color handler
- Extract all anonymous delegates in Director to named OnXxxUpdate methods
- Add LIVE_TRACKS.md: full track reference table (IDs 0–102)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 16:08:22 +08:00
ritenseki 988e8789f4 Fix BlinkLight, WashLight, Spotlight3d to use material properties
Stage light objects have no Unity Light components — they are
self-illuminated meshes. All three handlers now write to MeshRenderer
material properties instead.

BlinkLight: GetComponentsInChildren<Renderer> → _Color + _ColorPower.
pattern==0 uses per-renderer color0Array/powerArray; blink cycle
multiplies col * intensity into _Color.

Spotlight3d: adds _Color + _ColorPower writes after transform update.
color/colorPower fields were previously unused.

WashLight: sets _ProjectorColorPower from CameraProjectionColorPower
on projector materials. _ProjectorMulColor0 left at material default
(no color field in keyData).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:38:36 +08:00
ritenseki a4821f4e82 Add Core RP assembly reference to umamusume.asmdef
Volume, VolumeProfile, TextureCurve are in Unity.RenderPipelines.Core.Runtime,
not in the URP Runtime assembly. asmdef references are non-transitive so
both assemblies must be listed explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:23:11 +08:00
ritenseki dde480daea Add URP runtime assembly reference to umamusume.asmdef
Required for UnityEngine.Rendering.Universal namespace used
in Director.cs post-processing handlers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:20:39 +08:00
ritenseki fefcd96b07 Add ChromaticAberration, HdrBloom, ColorCorrection post-processing tracks
Three new URP Volume Override tracks (Path A):

ChromaticAberration (73): power → intensity, isEnable toggles effect.
Per-channel redOffset/greenOffset/blueOffset not expressible in URP built-in CA.

HdrBloom (38): bloomIntensity → Bloom.intensity, threshold → Bloom.threshold.
Fields unconfirmed (no bundle data in 30-song scan).

ColorCorrection (61): saturation (game 1.0=neutral) → ColorAdjustments.saturation
(URP range -100..100). redCurve/greenCurve/blueCurve → ColorCurves via TextureCurve.
Depth curves and selective color have no URP equivalent.

Director.InitializeTimeline() acquires or creates a Volume on Camera.main and
adds the required overrides programmatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:17:41 +08:00
ritenseki c0c7a5bfbe Fix BlinkLight flicker and ParticleGroup dual-rate emission
BlinkLight (pattern != 0): was always on; now computes intensity each
frame from turnOnTime/keepTime/turnOffTime/intervalTime/waitTime/
loopCount/powerMin/powerMax — supports fade-in, hold, fade-out, interval
cycle. pattern == 0 retains the original static per-light path.

ParticleGroup: was driving emission from FlickerLightRate only;
now uses MinMaxCurve(FlickerDarkRate, FlickerLightRate) so Unity
randomly samples between the two rates each emission event.

Also adds TODO comments on WashLight, Laser, UVScrollLight incomplete
fields, updates CLAUDE.md track table and live-shader-todo.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 13:16:44 +08:00
ritenseki af9316b2ea Add live post-processing shader implementation roadmap
Documents 8 shader effects needed for Live post-processing,
with URP migration paths, field mappings, and priority order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 11:46:47 +08:00
ritenseki 2e0f28ad7e Add Live stage lighting and effects tracks
New data classes (11):
  BlinkLight, GlobalFog, Spotlight3d, UVScrollLight,
  VolumeLight, LightShafts, Particle, ParticleGroup,
  WashLight, Laser + CLAUDE.md

WorkSheet: added 11 new [SerializeField] fields
LiveTimelineControl: added 9 new events + AlterUpdate_SimpleListControl helper
Director: added handlers for all new tracks

Key fixes:
  - StageController: register light objects in StageObjectMap (was skipped
    with continue), fixes missing stage props like ceiling neonsign
  - Spotlight3d handler: use keyData.assetName for StageObjectMap lookup
  - BlinkLight: SetActive + child Light color/intensity from timeline data

Coverage (58 songs): BlinkLight 56/58, Effect 55/58, GlobalFog 40/58,
  UVScrollLight 32/58, Spotlight3d 30/58

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 11:34:04 +08:00
ritenseki 4d5593dd22 Update .gitignore and add missing .meta file
- Ignore Unity auto-generated files (packages-lock.json, ShaderGraphSettings.asset)
- Ignore investigation/build scripts (umamusume.csproj, etc.)
- Add LiveTimelineEffectData.cs.meta

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 07:44:22 +08:00
ritenseki abdbfc0f42 Add Live Effect track (track ID 60) implementation
- LiveTimelineEffectData.cs: new data class with full field set
  (color, offset, owner, occurrenceSpot, IsLinkOwner*, etc.)
  derived from actual cutt asset bundle TypeTree dump
- LiveTimelineWorkSheet: add effectList field
- LiveTimelineControl: add OnUpdateEffect event and AlterUpdate_EffectControl
- Director: add OnEffectUpdate handler and ApplyEffectTransform helper
  loads prefab from 3d/effect/live/pfb_{name}, instantiates per key frame

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 21:24:52 +08:00
katboi01 37f5352277 Merge pull request #161 from Maidd/master
Added support for Global's encrypted DB
2025-11-11 21:36:09 +01:00
Maidd ffb9973455 Added support for Global's encrypted DB 2025-11-12 03:22:47 +07:00
katboi01 3cb3239316 Fixed loaded file export on global
Added workaround for isReadable error on scene export to .pmx
Fixed compilation on android
Incremented version
2025-10-04 00:27:12 +02:00
Ji O 5351f82f09 Load assets via Stream
* Load assets via Stream, Compatible with new versions of unencrypted DB
2025-10-03 23:21:48 +02:00
Sera eb35f2db0f Update README.md (#146)
* Update README.md
2025-10-03 11:00:39 +02:00
katboi01 6e3b53abb2 Removed automatic database update for standalone mode. Incremented version. 2025-09-28 14:30:50 +02:00
CroakFang d66991c2ef Add support for exporting prop, compatible with the new version, add the EnableRootMotion option (#143)
* update BillboardBuilder

* add a new enum value

* Add the EnableRootMotion option to support scenarios where the character is not within the camera view

* Add support for exporting prop

* update

* compatible with the new version 2

* update

---------

Co-authored-by: 左右看 <1918891542@qq.com>
2025-09-28 12:10:18 +02:00
katboi01 2f2f06eadc Updated translation source and credits 2025-09-01 22:51:01 +02:00
katboi01 21c7dea855 Added auto region detection 2025-09-01 22:41:41 +02:00
katboi01 b3d4e912ac Merge pull request #115 from croakfang/master
fix missing mesh in Cheval Grand swimsuit export
2025-08-03 21:23:17 +02:00