Bolt stringkey hashcode optimization 3369883024775733285#108
Closed
awest813 wants to merge 151 commits into
Closed
Bolt stringkey hashcode optimization 3369883024775733285#108awest813 wants to merge 151 commits into
awest813 wants to merge 151 commits into
Conversation
…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>
Phase 1 initialization
…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>
…map-fb7d Phase 1 documentation roadmap
…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>
Phase 2 validation
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>
User testing readiness
- 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>
Warcraft 3 OpenMW vision
Co-authored-by: awest813 <awest813@users.noreply.github.com>
Project next phase
…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>
Next phase development
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>
Next phase finalization
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>
…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>
…933932774237018
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.