Skip to content

Bolt stringkey hashcode optimization 3369883024775733285#108

Closed
awest813 wants to merge 151 commits into
Retera:mainfrom
awest813:bolt-stringkey-hashcode-optimization-3369883024775733285
Closed

Bolt stringkey hashcode optimization 3369883024775733285#108
awest813 wants to merge 151 commits into
Retera:mainfrom
awest813:bolt-stringkey-hashcode-optimization-3369883024775733285

Conversation

@awest813
Copy link
Copy Markdown

@awest813 awest813 commented Jun 1, 2026

No description provided.

awest813 and others added 30 commits March 1, 2026 22:57
…rnization

Add desktop launcher tuning flags and modernization roadmap
- StartupDiagnostics: logs GL vendor/renderer/version, GLSL version,
  display resolution, Java version, and OS info at launch
- FramePacingTracker: reports min/max/avg frame time and effective FPS
  to stdout every 60 seconds using a 600-frame ring-buffer window
- WarsmashGdxMultiScreenGame: wires both utilities into create() and render()

Co-authored-by: awest813 <awest813@users.noreply.github.com>
Adds -validate / --validate launcher flag that:
- Reads warsmash.ini (honoring -ini <path> if provided)
- Checks each [DataSources] entry path exists on disk
- Prints a pass/fail line per entry and a summary count
- Exits 0 if all paths found, 1 if any are missing
- Also adds -validate to the -help output

Co-authored-by: awest813 <awest813@users.noreply.github.com>
Gradle 7.3.3 fails to compile its own build scripts when run on Java 21
(class file major version 65 not supported). Gradle 8.6 + beryx.runtime
1.13.1 support Java 17 and Java 21.

Co-authored-by: awest813 <awest813@users.noreply.github.com>
Runs ./gradlew assemble on ubuntu-latest and windows-latest against
Temurin Java 17 and 21. Triggers on push to main/cursor/** branches
and on pull requests targeting main.

Co-authored-by: awest813 <awest813@users.noreply.github.com>
Covers minimum requirements, tested configurations, WC3 patch asset
compatibility matrix, known issues (light leak, GLSL mismatch, FLAC
audio, DDS gamma), troubleshooting steps, and startup report example.

Co-authored-by: awest813 <awest813@users.noreply.github.com>
CONTRIBUTING.md covers:
- Build prerequisites and quick-start commands
- Coding conventions (Java 8 syntax, style, architecture boundaries)
- PR workflow and changelog requirements
- Profiling workflow (built-in frame-pacing log, VisualVM/JProfiler steps,
  known hotspot candidates, reproducible benchmark recipe)
- Changelog category definitions

CHANGELOG.md documents all Phase A changes with compat/qol/perf categories.

Co-authored-by: awest813 <awest813@users.noreply.github.com>
…cal analysis

- CHANGELOG.md: move Phase A items to a dated release section; add
  Unreleased stub for Phase B work
- README.md: add Project Status & Roadmap section summarising all phases
  and Phase B targets (light leak, shader normalization, parser design)
- ENGINE_MODERNIZATION_ANALYSIS.md: mark all Phase A deliverables as done;
  add detailed Phase B sections covering root-cause analysis for the Light
  leak, GLSL version inventory and migration plan, parser consolidation
  design scope; expand Phase C table

Co-authored-by: awest813 <awest813@users.noreply.github.com>
…r design

B.1 Light-system memory leak fix:
- Scene.update() now calls removeLights(scene) on each instance pruned from
  the active list before discarding it, so LightInstance objects are properly
  unregistered from W3xSceneWorldLightManager. Previously orphaned lights
  accumulated indefinitely, causing memory growth and frame-time drift.
- W3xSceneWorldLightManager.remove() documented as idempotent (ArrayList.remove
  is a no-op for absent elements, preventing state corruption on double-calls).
- W3xSceneWorldLightManager logs active dynamic light count to stdout every
  ~60 s ([LightManager] active dynamic lights=N) for leak verification.

B.2 Shader target normalization:
- vsHd / fsHd upgraded from #version 120 to #version 330 core:
  attribute → in, varying → out/in, texture2D() → texture(),
  gl_FragColor → explicit out vec4 fragColor.
- BONE_TEXTURE_330 helper in MdxShaders provides a #version 330 core-safe
  copy of Shaders.boneTexture (texture2D → texture) used exclusively by vsHd.
- Shaders.transforms updated: attribute → in (used only by vsHd, safe).
- WarsmashTestGame2 and WarsmashTestGame3 test shaders lowered from
  #version 450 core to #version 330 core (no 450-specific features used).

B.3 Parser consolidation design:
- docs/PARSER_CONSOLIDATION_DESIGN.md: unified TableDataSource interface,
  DataTable as canonical backend, adapter layer, migration order, test
  strategy, and open questions. Implementation deferred to Phase C.

Docs: CHANGELOG.md and ENGINE_MODERNIZATION_ANALYSIS.md updated; Phase B
marked complete, Phase C promoted to Next.

https://claude.ai/code/session_015jYzYrpFJctvaAqjpvw6m7
…r design

B.1 Light-system memory leak fix:
- Scene.update() now calls removeLights(scene) on each instance pruned from
  the active list before discarding it, so LightInstance objects are properly
  unregistered from W3xSceneWorldLightManager. Previously orphaned lights
  accumulated indefinitely, causing memory growth and frame-time drift.
- W3xSceneWorldLightManager.remove() documented as idempotent (ArrayList.remove
  is a no-op for absent elements, preventing state corruption on double-calls).
- W3xSceneWorldLightManager logs active dynamic light count to stdout every
  ~60 s ([LightManager] active dynamic lights=N) for leak verification.

B.2 Shader target normalization:
- vsHd / fsHd upgraded from #version 120 to #version 330 core:
  attribute → in, varying → out/in, texture2D() → texture(),
  gl_FragColor → explicit out vec4 fragColor.
- BONE_TEXTURE_330 helper in MdxShaders provides a #version 330 core-safe
  copy of Shaders.boneTexture (texture2D → texture) used exclusively by vsHd.
- Shaders.transforms updated: attribute → in (used only by vsHd, safe).
- WarsmashTestGame2 and WarsmashTestGame3 test shaders lowered from
  #version 450 core to #version 330 core (no 450-specific features used).

B.3 Parser consolidation design:
- docs/PARSER_CONSOLIDATION_DESIGN.md: unified TableDataSource interface,
  DataTable as canonical backend, adapter layer, migration order, test
  strategy, and open questions. Implementation deferred to Phase C.

Docs: CHANGELOG.md and ENGINE_MODERNIZATION_ANALYSIS.md updated; Phase B
marked complete, Phase C promoted to Next.

https://claude.ai/code/session_015jYzYrpFJctvaAqjpvw6m7
Previously removeLights() ignored the scene parameter and used
this.scene instead. While the values are typically identical, using
the parameter is semantically correct and prevents stale-reference
issues when the instance's scene field is out of sync with the
caller's scene (e.g. during Scene.update() pruning).

Co-authored-by: awest813 <awest813@users.noreply.github.com>
- Configure JUnit 5 dependency and test source set for core module.
- Add MdxShadersTest with 21 assertions validating the GLSL 120->330
  core migration: version directives, keyword replacements (attribute
  -> in, varying -> out, texture2D -> texture, gl_FragColor ->
  fragColor), bone-texture 330 helper, and transforms shared string.
- Update CI workflow to run :core:test after assemble.

Co-authored-by: awest813 <awest813@users.noreply.github.com>
Five correctness fixes identified during pre-release review:

1. Particle emitters killed on view-cull (MdxComplexInstance / Scene)
   removeLights() previously also called particleEmitter.onRemove() on every
   view-culled instance, silently destroying active particle effects whenever
   a unit scrolled off screen. Separated concerns: removeLights() now only
   deregisters LightInstance objects; a new onInstanceRemoved() hook in
   ModelInstance handles particle teardown and is called only from
   Scene.removeInstance() (permanent removal path).

2. Ghost batched instances after removal (Scene.removeInstance)
   The method removed from this.instances but not from this.batchedInstances,
   leaving a removed unit in the batched render list for one extra frame.
   Added batchedInstances.remove(instance) to the permanent-removal path.

3. vsHd GLSL divide-by-zero with empty light texture (MdxShaders)
   First light read used '0.5 / u_lightTextureHeight' unconditionally, giving
   +Infinity when no lights are active. Wrapped in 'if (u_lightTextureHeight >
   0.5)' and pre-initialised v_lightDir = vec4(0.0) for the no-light case.

4. Uninitialised mat4 bone in vertex-group shader (Shaders.transforms)
   Non-SKIN getVertexGroupMatrix() declared 'mat4 bone;' without an initialiser.
   GLSL 3.30 core does not zero-initialise locals; bone accumulation ran on
   garbage. Changed to 'mat4 bone = mat4(0.0);'.

5. Paired log file names (DesktopLauncher)
   Two separate currentTimeMillis() calls could assign different prefixes to the
   .out.log and .err.log files from the same session. Captured a single value.

Also added 3 new unit tests (MdxShadersTest, now 23 total) and updated CHANGELOG.

Co-authored-by: awest813 <awest813@users.noreply.github.com>
- LightInstance: add float[] cache and static generation counter so each
  light's packed 16-float GPU block is computed at most once per frame.
  LightInstance.advanceGeneration() is called once by W3xSceneWorldLightManager.
  Subsequent bind() calls within the same generation use FloatBuffer.put(float[])
  bulk copy instead of re-evaluating all keyframe tracks.

- W3xSceneWorldLightManager: replace shared lightDataCopyHeap with separate
  unitLightBuffer and terrainLightBuffer; fill both in a single loop over
  this.lights. Remove the clear()/reuse pattern that forced sequential uploads.

- MdxComplexInstance.updateBoneTexture(): replace 16 absolute-indexed
  FloatBuffer.put(int,float) calls per bone with a single put(val,0,16) bulk
  copy + flip(). LibGDX Matrix4.val[M00..M33] are contiguous indices 0-15 so
  the data written is identical; JVM maps the bulk put to native memcpy.

- FramePacingTracker: sort a copy of the ring buffer in report() to compute
  p95 and p99 percentile frame times alongside avg/max. Adds spike-detection
  warning when p99 > 3x avg. Zero per-frame overhead.

- Add ObjectPool<T>: fixed-capacity stack-backed pool with acquire()/release()
  semantics and hitRate() diagnostic. Infrastructure for Phase D GC reduction.

- Add SimulationBudgetTracker: ns-resolution tick timer with avg/max/overrun
  reporting every ~60 s. Ready to wire around CSimulation.step() in Phase D.

Co-authored-by: awest813 <awest813@users.noreply.github.com>
Co-authored-by: awest813 <awest813@users.noreply.github.com>
…telemetry, profiles

- Wire SimulationBudgetTracker around CSimulation.update() in War3MapViewer:
  each simulation tick is now timed via beginTick()/endTick(); avg/max/overrun
  stats reported every ~60 s via [SimBudget] log lines.

- Named launch profiles (-profile safe|balanced|high) in DesktopLauncher:
  safe = windowed 1280x720, no MSAA, vsync, 60 fps cap;
  balanced = windowed 1280x720, 2x MSAA, vsync, 60/30 fps;
  high = fullscreen, 4x MSAA, vsync, uncapped.
  Individual flags override profile settings.

- GL version guard in StartupDiagnostics.checkGLRequirements(): called from
  WarsmashGdxMultiScreenGame.create() after the capability report. Prints a
  user-readable error with detected/required version and driver-update hints,
  then exits with code 1 when OpenGL < 3.3 is reported.

- Server hardening in GamingNetworkServerBusinessLogicImpl:
  - New LoginRateLimiter blocks an IP for 5 min after 5 failed auth attempts
    in 60 s; applied to login() and createAccount().
  - New writerToSession reverse map makes disconnected() O(1) instead of O(n)
    over all sessions, eliminating the documented DDoS amplification path.

- Asset cache telemetry via new AssetCacheTelemetry class: instruments both
  ModelViewer.load() and loadGeneric() cache paths; logs [AssetCache] hit/miss
  summary every 50 misses.

- Package ownership markers: package-info.java for render (viewer5),
  simulation, net (networking), and assets (datasources) layers, documenting
  allowed and forbidden cross-layer dependencies.

- New unit tests (29 tests added):
  ObjectPoolTest (8), SimulationBudgetTrackerTest (5),
  StartupDiagnosticsTest (9), AssetCacheTelemetryTest (7).

- CHANGELOG.md and ENGINE_MODERNIZATION_ANALYSIS.md updated.

Co-authored-by: awest813 <awest813@users.noreply.github.com>
Co-authored-by: awest813 <awest813@users.noreply.github.com>
Co-authored-by: awest813 <awest813@users.noreply.github.com>
Co-authored-by: awest813 <awest813@users.noreply.github.com>
Extracted anonymous inner classes (CUnitEnumFunction, CDestructableEnumFunction), AtomicIntegers, and AbilityPointTarget instances from the update methods of CPsuedoProjectile and CCollisionProjectile into class-level fields. This significantly reduces garbage collection pressure by preventing the continuous per-frame instantiation of these objects during spatial queries for every active projectile.

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
awest813 and others added 29 commits March 19, 2026 21:21
…ty-7856269807176679145

🎨 Palette: Add tooltip and accessible name to TerrainViewPanel
…13750215547298966320

🎨 Palette: [Add mnemonics to animation controller panel]
…acktraces

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
Add monospaced font to ExceptionPopup for better stack trace readability.

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
Add a `JLabel` linked to the `JComboBox` for animation sequence selection in `AnimationControllerPanel`.
This improves accessibility by allowing screen readers to properly identify the combobox, and provides a keyboard mnemonic (Alt+S) for quicker navigation.

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
Added standard cross-platform Ctrl+O/Cmd+O shortcuts to the "Open" JMenuItems in `TerrainEditorPanel`, `YseraPanel`, and `AbilityBuilderUIPanel`. This is a significant micro-UX improvement that provides standard power-user functionality and better keyboard accessibility when navigating the desktop editors.

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
Extracts anonymous CUnitEnumFunction classes in heavily used
skills (WarStomp, ThunderClap, Kaboom, AuraBase) into
cached inner classes with `reset` methods to eliminate GC
allocations during spatial queries.

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
…76343283153048

🎨 Palette: [Add Open keyboard accelerators]
…835567343069554693

⚡ Bolt: [performance improvement] Optimize spatial query callbacks
…iring-2043788448023227089

⚡ Bolt: [Reduce GC allocations in active pairing spatial queries using Object Pooling]
…allback-4341334117258771361

⚡ Bolt: [performance improvement] Cache neutral building enum callback
…34116067229925701

🎨 Palette: [Add accessibility label to animation sequence selector]
…ror popups

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
…al queries

This change replaces anonymous implementations of `CUnitEnumFunction` in frequently called Jass native spatial queries (e.g., `GroupEnumUnitsInRect`, `GroupEnumUnitsInRangeCounted`) with a single pooled `CountedUnitEnumFunction`.

By properly utilizing a libGDX `Pool` and implementing `Pool.Poolable` to ensure objects are cleaned out on `reset()`, we prevent memory leaks and significantly reduce object churn and Garbage Collection (GC) pauses during intensive game ticks.

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
…68148616

⚡ Bolt: [performance improvement] Eliminate GC overhead in Jass spatial queries
…0152970540

🎨 Palette: [UX improvement] Fix mnemonic clash & add a11y names to error popups
…9831499837864851

🎨 Palette: [UX improvement] Link Level of Detail label to spinner
…paced-font-6706355053595229712

🎨 Palette: [UX improvement] Set monospaced font for ExceptionPopup stacktraces
Replaced lambda allocations in `enumUnitsInRect`, `enumUnitsInRange`, and similar spatial query methods with object pools for `CUnitEnumFunction` wrappers. Extracted capturing lambdas into static inner classes (`UnitEnumIntersector`, `UnitInRangeCallback`, `DestructableInRangeCallback`) that are acquired from pools and reset with relevant context before querying. Clear methods are explicitly called in finally blocks to prevent memory leaks from object loitering within the pools.

This reduces per-frame heap allocations during frequent ability, aura, or unit movement spatial queries.

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
…ack slider

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
…0583203542

🎨 Palette: [UX improvement] Add accessible name and tooltip to audio playback slider
…timization-4186608132807931908

⚡ Bolt: [Performance] Eliminate GC allocations in CWorldCollision spatial queries
…976445354825

🎨 Palette: [UX improvement] Add accessible name to Main Toolbar
The previous implementation of `StringKey.hashCode()` computed
`this.string.toLowerCase().hashCode()`, allocating a new String on every lookup.
Since `StringKey` is widely used in Game Objects and Datatables, this was a massive bottleneck.
Now we cache the case-insensitive hashCode during initialization without allocating intermediate strings.

Co-authored-by: awest813 <208855664+awest813@users.noreply.github.com>
@awest813 awest813 closed this Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants