Regalia v1.0.6 #19
YDW99
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
What's Changed
Full Changelog: v1.0.5...v1.0.6
Regalia v1.0.6 — Release Notes
📥 Download
Regalia-v1.0.6-release.apkRegalia-v1.0.6-manual-zh.htmlRegalia-v1.0.6-manual-en.html🆕 What's New in v1.0.6
v1.0.6 is a feature-enhancement release with 10 major new features and 4 rounds of bug fixes (including critical Chess960 castling fixes).
♟️ Chess960 Improvements
ECO Opening Recognition Suppression
Chess960 (Fischer Random Chess) has no fixed opening theory. When Chess960 mode is active, the in-game ECO Opening info panel and Opening Recommendation bar are now fully suppressed — no more meaningless ECO lookups for non-standard start positions.
Chess960 Castling Detection Overhaul
Replaced the legacy
Math.abs(to.col - from.col) === 2pattern (which only works for standard chess) with an explicitcastleflag on castling moves plus a unified_castleSide()helper:=== 2mv.castleflagFiles updated:
pseudoMoves(),makeMv(),makeMvInPlace(),moveAlg(),animateMove(),_uciToSimple(),tablebase.js applySANMove(),stats.html executeMove()🏰 King-then-Rook Castling Gesture
A new castling operation method — essential for Chess960 where some positions can only be castled this way.
How it works:
Why it matters: In Chess960, when the rook's source square is the king's destination (e.g. rook on g1, king castles kingside to g1), the traditional "click the king's destination" gesture is ambiguous. The king-then-rook gesture resolves this.
🔧 Implementation Details
_computeCastlingRookSetForSelection(selPos, moves)— pure helper, no global state mutation_updateChangedSquares()— lightweight update path now syncs the marker (was only in full render)castle-ringCSS — golden dashed border +castlePulsekeyframe animation_getCastlingRookForClick()— click handler detects rook clicks and triggers castling📊 Stats Page Per-Move Selection
Click any move or the initial FEN in the stats page's PGN Text panel to instantly view:
When nothing is selected, the final complete statistics are shown.
🔄 PGN
[SetUp]/[FEN]Round-Trip PreservationBefore: Importing a PGN with
[SetUp "1"]and[FEN "..."]headers, then exporting, would drop both headers.After:
importPGN()now correctly assignsresult.startFENto_setupFEN, so_buildPGNString()regenerates both headers on export.🎨 Unified Gray-Out Styling
When a toggle or stepper is grayed out (disabled), only the control itself is dimmed. Surrounding labels, descriptions, and explanations remain at full opacity.
New gray-out explanations:
📱 Portrait-Optimized New Game Dialog
The New Game Settings dialog now has dedicated portrait-mode CSS while preserving the landscape layout:
📜 Scroll-Position Preservation
Fixed a bug where scrollable windows would suddenly jump back to the top after a state change triggered a re-render.
Affected containers:
.dlg— dialogs (New Game, Engine Config, Import, About).panel— right-side info panel (landscape).review-moves— review mode move list.op-list— opening selectorstats.html#content— full document scrollMechanism:
_savedContainerScrollsarray capturesscrollTopbeforeapp.innerHTML = hand restores it after (clamped to newscrollHeight).⚙️ Engine Evaluation FEN Sanitization
Added
_sanitizeFenForEngine()— strips inconsistent castling rights before sending to Stockfish.Problem: The FEN
4k3/8/8/8/8/8/8/r1K4R w q - 1 3has black queenside castling right (q) but no black rook on a8. Stockfish would enter a degraded state — noinfolines, nobestmove, hanging until the 30s safety timer fired, then retrying indefinitely.Solution:
Applied to all
engineEval,engineEvalDeep,engineHint,engineGo,engineGoTimed, andstartPondercalls.🏅 SL Mode Skill-Level Display
When the AI opponent is in SL (Skill Level) mode, the actual skill level value is now shown:
SLSL20SLSL20[Black ""]tagAI Opponent SLAI Opponent SL20New Java bridge method:
getEngineSkillLevel()returns the currentengineSkillLevelint.🐛 Bug Fixes
Round 1 — Initial v1.0.6 Release
_WORKER_SOURCEtemplate literal (worker-pool.js) prematurely terminated the string, causing aSyntaxErrorthat blocked the entire script. Fixed by removing the backtick.executeMove()lostcastleflag — Themvobject was built as{from, to, piece, promotion}without copyingcastlefromlegalMvs, breaking Chess960 castling detection. Fixed by looking up the matching legal move._computeAndCacheVisualAnnotations()replay path — Samecastleflag loss during move replay. Fixed by restoring frommoveRecords.isCastling.Round 2 — Castling Root Cause
executeMove()castle flag propagation — Comprehensive fix ensuringcastleflag flows fromlegalMvs→mv→makeMv()/moveAlg()/_castleSide()._castleSide()fallback logic — Improved to use destination column + distance (≥2 cols) instead of just=== 2, covering 2+ col Chess960 castling._uciToSimple()Chess960 detection — Simplified to distance-based (≥2 cols) to avoid 1-col ambiguity with normal king moves._sanitizeFenForEngine()Shredder detection — Simplified from double-regex to single/^[KQkq-]+$/._finishAnim()cleanup — Now clears_lastAnimMvto avoid stale references.Round 3 — Chess960 Rook Capture & Analyze-All Off-by-One
Chess960 own rook captured during castling — In Chess960, when the rook's source square equals the king's destination (e.g. rook on g1, king castles kingside to g1),
makeMv()/makeMvInPlace()moved the king first (overwriting the rook), then tried to move the rook — but it was already gone.Fix: Detect castling before moving the king, save the rook piece reference, move the king, then place the saved rook at its destination. Also fixed
stats.html executeMove()(review mode replay).Test verification
"Analysis complete" never displayed —
_reviewEvalCacheis keyed byreviewStep(1-based), so cache size =moveRecords.length. But the check compared_reviewEvalCache.size >= reviewStates.length, andreviewStates.length = moveRecords.length + 1(includes initial position at index 0). This off-by-one meant the comparison was alwaysN >= N+1→ false.Fix: Three coordinated changes:
_totalSteps = moveRecords.lengthreviewAnalyzeAll(): iterate1..moveRecords.length_reviewAnalyzeAdvance(): terminate whennextStep > moveRecords.lengthRound 4 — Castling Rook Marker Display
_updateChangedSquares()(the lightweight update path) didn't includecastle-ringmarker logic — it was only inrenderInternal()._computeCastlingRookSetForSelection()computes the set without mutating globals._updateChangedSquares()now computes both current and previous sets, includes both in the update list, and correctly adds/removes thecastle-rookclass +castle-ringdiv.⚡ Performance Optimizations
_getCastlingRookSquares()removed (40 lines). It was redundant afterrenderInternalswitched to_computeCastlingRookSetForSelectiondirectly, and contained a wasteful double-computation ofchess960CastlingRookMove()._updateChangedSquares()castling-set computation — EliminatedlegalMoves()recomputation for the previous selection by deriving castling rooks from the already-tracked_prevLegalSet(Set ofrow*8+colkeys). If the previous piece was a king and_prevLegalSetcontains col 6 or col 2, castling was legal — no need to re-run the full move generator.🏗️ Technical Architecture
📦 Deliverables
Regalia-v1.0.6-release.apkRegalia-v1.0.6-manual-zh.htmlRegalia-v1.0.6-manual-en.html🔄 Upgrading from v1.0.5
v1.0.6 is fully compatible with v1.0.5's PGN archives and evaluation caches. Install directly over the existing app — no uninstall needed.
📜 License
🙏 Acknowledgments
📌 Known Limitations
Regalia uses "Regalia" solely as a project name. No trademark rights are claimed. Anyone is free to fork and rename their own version.
AI-generated
This discussion was created from the release Regalia v1.0.6.
All reactions