Installation, rules coverage, testing, and open-source acknowledgments.
Stockfish complete corresponding source · Evaluation network for rebuilding · GPL license · Chess.js source · BSD license
# BecknerWeb Chess — installation 1. Back up the current website files. Upload the complete `chess/` directory to `/chess/` on your Windows IIS website. Open `/chess/index.html` over HTTPS. No Node.js, npm, build service, CDN, or extra production runtime is required. 2. Local computer and same-device games are available immediately from static HTTP(S) hosting. Do not launch by double-clicking `index.html`; browser worker restrictions on `file:` URLs prevent reliable engine loading. 3. Enable Classic ASP for private rooms. This implementation uses the built-in **JScript** language of Classic ASP, not ASP.NET. Keep the supplied `api/web.config` so errors are JSON and `.inc` files cannot be downloaded. 4. Execute `sql/install.sql` inside the existing **BecknerWeb** SQL Server database. No CREATE DATABASE, logins, or server-role changes are needed. If the application account cannot create tables, have the database owner run the script and grant SELECT/INSERT/UPDATE/DELETE on `dbo.BecknerChessRooms` to the existing application account. 5. `chess/api/config.asp` is the only database configuration file. Its connection is reused from your Battleship package. Update it only if your working Battleship connection has changed. Credentials are confined to this server-side file; the ZIP contains that private configuration, so keep it private. Do not serve this folder through a server that exposes ASP source. 6. Replace the existing site's `games.asp` with `menu-update/games.asp`, **in the same location as the original `games.asp`** (the page alongside its existing `includes/` folder). Do not put it inside `/chess/`. Chess is between Checkers and Chinese Checkers, with exactly `../chess/`. Every other entry and the existing header/footer includes are preserved from the latest Word Salon package. 7. Run the deployment checklist in `TEST-REPORT.md` on IIS with two separate browsers/devices. Actual IIS and SQL Server execution could not be verified in the build environment. 8. Schedule `sql/cleanup.sql` daily, repeating batches if necessary. Rooms expire 14 days after creation; an expired code is rejected even before cleanup runs. No public lobby, accounts, or chat are included. ## Files - `chess/index.html`, `style.css`, `app.js`: responsive game interface. - `chess/vendor/chess.js`: BSD-licensed chess.js 0.10.3. - `chess/rules.js`: shared validation, clocks, claims and result adjudication. - `chess/api/game.asp`: authoritative private-room endpoint, SQL transactions and parameterized commands. - `chess/api/chess.inc`, `rules.inc`: exact server copies of the browser rules, wrapped in ASP delimiters. Tests check byte equality. - `chess/engine/`: unmodified single-thread Stockfish 17.1 Lite JS/WASM, GPL license and corresponding source. - `chess/pieces/`: original SVG artwork; no font or image service dependency. - `chess/tests/`: developer verification scripts. These are **not** required to play; Node/Playwright were used only as development test tools. - `chess/docs/README.html`: linked documentation and source downloads. ## Troubleshooting **Engine error:** upload both `stockfish-17.1-lite-single-03e3232.js` and `.wasm` with their exact names. Verify `/chess/engine/stockfish-17.1-lite-single-03e3232.wasm` responds successfully as `application/wasm`. Use Retry engine under More. No weaker fallback is substituted. This single-thread build requires no cross-origin-isolation headers. **HTTP 500 / non-JSON response:** confirm Classic ASP/JScript is enabled; the `api/config.asp`, `json.inc`, `chess.inc`, and `rules.inc` includes exist; the table was created; and the database credentials match the working Battleship application. A locked IIS configuration section may require the host to apply the included MIME mappings. ASP parse errors occur before the JSON error handler; inspect the host's private logs. **Generic server-unavailable JSON:** check the DB connection and table permissions privately. Database details and credentials are deliberately omitted from responses. **Room already full:** a room supports exactly two seats. Return using the browser in which you joined, with its local storage intact. Seat credentials are separate from the shareable invitation. If a create/join response was lost before credentials reached the browser, create a new room; unused rooms expire automatically. Ordinary move-response loss is recoverable by polling and does not replay a move. **Expired/unknown room:** create a new room. Clearing browser storage removes locally saved games and seat credentials. Invitations grant entry only to an unfilled second seat. **No sound:** turn sound on in Settings and interact with the page; browser autoplay restrictions prevent audio before a gesture. **Rules scope:** read the known limitation below before treating this as tournament software.
# Rules coverage, clocks, and engine behavior ## Implemented Standard move generation, own-king safety, check, mate, stalemate, both castlings, permanent loss of castling rights, immediate en passant with discovered-check legality, and all four promotions are supplied by chess.js 0.10.3. Additional FEN validation rejects missing/duplicate kings, back-rank pawns, inconsistent castling rights, inconsistent en passant state, and check on the side that just moved. This validates basic legal structure, not a retrograde proof that a FEN can arise from the initial position. The app does NOT use chess.js `game_over()` or `in_draw()` to decide results: those APIs combine claimable draws with automatic endings. The shared Salon layer implements threefold and 50-move claims, intended-move claims, automatic fivefold and 75-move draws, and checkmate precedence. Repetition keys include the side to move, piece placement, castling rights, and en passant only when a legal en passant capture exists. Standard dead material positions include bare kings, a single minor piece against a bare king, and bishops confined to one square color without other pieces. Two knights against a king are not automatically drawn merely because mate cannot be forced. Timeout checks are side-specific: a bare king cannot win on time; single-minor cases consider the opponent's possible blocking material. A lone bishop with an opponent rook may have a legal mating sequence and is not incorrectly treated as insufficient. ## Known rules limitation — not tournament-complete The engine does **not** solve arbitrary legal reachability to recognize every rare blocked/dead position with remaining pawns or other material. Such a position may continue instead of drawing automatically. The same limitation can affect timeout adjudication in unusual locked positions: a material-based test may award a win even though that particular position admits no legal mating sequence. Use an agreed draw for recognized dead positions before time expires. Do not use this build for tournament adjudication requiring exhaustive FIDE dead-position coverage. No claim of full coverage of that requirement is made. ## Clock policy - Untimed, 1/3/5/10/15 minutes, 3+2, 5+3, 10+5, and custom 0.1–180 minutes with 0–120 seconds Fischer increment. - Local clocks start when Start game is pressed. Online clocks start when the second player joins. White's clock runs immediately; loading or computer startup also consumes the active clock. - Elapsed timestamps determine clock values. Intervals merely refresh displays. Review, tab switching, sleep, closing the page, and online disconnection do not pause clocks. - Local Pause is explicit and saved. When a timed saved game is resumed, elapsed wall time since the last active timestamp is charged; a flagged game ends immediately. A local device clock adjustment can affect local casual timing. Online timing uses SQL Server UTC, not client-submitted timestamps. - The browser estimates server clock offset from the midpoint of the request round trip. Display precision depends on latency; only server time decides online flags. - Online polling checks for time expiration under the same database row lock as moves. The losing player never needs to send another request. If neither player is connected, the next authenticated request records the result at the already-expired deadline; there is no background ASP process. - An increment is applied only after a legal completed move. Flagging is checked before accepting a move. - Takeback restores the clock balances immediately before the earliest undone move, after the thinking time already spent before that move. Removed increments are removed. The restored side's clock restarts at acceptance. In solo play, Undo normally removes the human move and its computer reply; same-device and online takebacks remove one ply. - Local same-device takebacks require a confirmation representing both players' agreement. Online takebacks require an offer accepted by the other seat and may be disabled when creating the room. Online takebacks after a concluded game are unavailable; use Rematch. ## Private room protocol Room codes are 48 random bits rendered as 12 hexadecimal characters. Seat credentials are separate 256-bit secrets generated by SQL Server `CRYPT_GEN_RANDOM`, stored only server-side and in the appropriate browser's local storage. They never appear in the invite link. Possession of the seat token is authentication; do not share browser storage. The server reconstructs the authoritative chess position, validates turn and legal move, and computes clocks/results. It ignores any client-supplied clock, result, or position. `UPDLOCK,HOLDLOCK` inside an ADO transaction serializes operations for a room; version checks reject stale/duplicate writes. State, move history, repetition keys, castling/en-passant state, clocks, offers, seats and results commit together. SQL values are parameters. The server has no engine/hint endpoint. Offers expire on a legal move. A rematch requires agreement, resets clocks, and swaps both seat colors. Refresh reuses the locally saved token. No account-based seat recovery exists after browser storage is cleared. A lost create/join response can strand the newly allocated seat; create a new room in that case. Successful joins and ordinary move/poll interruptions support refresh recovery. ## Engine Stockfish.js 17.1.0, Stockfish 17.1 Lite single-thread WASM, unmodified. Lite uses a smaller network than the full desktop build. This is a strong established chess engine, not a material-only or random-move fallback. Strength names are approximate and have no verified Elo correspondence. | Level | UCI Skill Level | Maximum search time | |---|---:|---:| | Beginner | 0 | 150 ms | | Easy | 3 | 350 ms | | Medium | 8 | 800 ms | | Hard | 15 | 1,600 ms | | Expert | 20 | 3,000 ms | Timed search limits are reduced to at most 8% of remaining clock time and a 150 ms safety reserve where feasible; clocks can still expire during engine loading on a very slow device. Hash is 16 MB. Each search uses a Web Worker, and cancellation terminates it. A generation identifier and position check prevent obsolete responses from moving pieces after restart or undo. Engine load failure is shown explicitly with Retry engine. There is no silent fallback. Beginner can still play strong moves, especially forced tactics. Hints consume clock time. The computer may accept a draw in a claimable position or a near-equal estimate after 40 plies; otherwise it declines. Online games have no live hints or analysis controls. Post-game analysis examines each prior position and reports the suggested move and evaluation from the player-to-move perspective; estimates are not guarantees, and this is not a full annotation or blunder-classification service. Local match statistics distinguish mode and computer difficulty; online results are deduplicated by room and rematch number in local storage. Same-device decisive games count one win and one loss for the shared device, not a persistent player identity. Imported practice/review positions do not count as ordinary match results.
# Dependency and license manifest The new Beckner Chess application source, original SVG artwork, and procedural audio are licensed GPL-3.0-or-later. Copyright 2026 John Wm Beckner. The existing BecknerWeb menu and private connection settings remain the user's existing materials. No external fonts are loaded; the interface uses the device's serif and system fonts. ## Stockfish - Package: `stockfish` **17.1.0**, fetched from `https://registry.npmjs.org/stockfish/-/stockfish-17.1.0.tgz`. - Project: https://github.com/nmrugg/stockfish.js - Exact source revision: **602fd7e1a571a2be71f242942db90483731f2a1f**. - Source archive: https://github.com/nmrugg/stockfish.js/archive/602fd7e1a571a2be71f242942db90483731f2a1f.tar.gz - Upstream engine: https://github.com/official-stockfish/Stockfish - License: GNU GPL version 3; full text in `chess/engine/Copying.txt` and root `LICENSE-GPL-3.0.txt`. Original AUTHORS and license files are retained inside the unchanged source archive. - Runtime files: `stockfish-17.1-lite-single-03e3232.js`, `stockfish-17.1-lite-single-03e3232.wasm`. - Both runtime files were verified byte-for-byte against the exact source commit's distributed artifacts. - Embedded evaluation network: **nn-9067e33176e8.nnue**. The runtime embeds the network in WASM; no runtime download is needed. A standalone copy for rebuilding is included beside the source archive. - Network source: https://tests.stockfishchess.org/api/nn/nn-9067e33176e8.nnue - Network SHA256: `9067e33176e8c5edb7aa8db6a3aedd012f84a1f39872e86357c6c2d0993f314d`. Complete upstream source archive and build scripts are included under `chess/engine/source/`. It intentionally retains upstream files for other engine flavors as well; these are not loaded by the game. Keep the source and network downloadable when hosting/distributing the engine. The in-game documentation links directly to them. No private database configuration is in those source downloads. To rebuild (developer task, not an installation requirement): extract the corresponding-source archive, copy the included `.nnue` into its `src/` directory, install the Emscripten version requested by `build.js`, install its development dependencies per the upstream README, and run `node build.js --single-threaded --lite -f`. The upstream source includes build scripts and platform instructions. Compilation was not repeated here; the original matching prebuilt artifacts are bundled unchanged. ## Chess.js - Version **0.10.3**, project https://github.com/jhlywa/chess.js - Package/source archive: https://registry.npmjs.org/chess.js/-/chess.js-0.10.3.tgz - License: BSD-2-Clause, retained at `chess/vendor/CHESS-LICENSE.txt`. - Unmodified browser source is `chess/vendor/chess.js`. `api/chess.inc` is the identical source wrapped in ASP script delimiters. - The older ES3-compatible release was chosen so the same legal-move implementation can execute in Classic ASP JScript without Node, bundlers, or an additional runtime. Application-level draw adjudication and FEN validation are separate and documented. ## Other assets - Twelve original SVG piece drawings in `chess/pieces/`, created for this game. - Move/capture/check/result/low-time sounds are original Web Audio oscillator sequences in `app.js`; no audio file downloads or third-party recordings. - Strict JSON codec reused from the user's earlier Word Salon project; no eval of client input. - Development tests use Node and Playwright only in the build environment. Neither is shipped as a production dependency or required on IIS.
# Test report — BecknerWeb Chess Build verified 2026-09-23. This report distinguishes executable tests from deployment checks. ## Verified in the build environment ### Shared rules: 22 passing test groups `chess/tests/rules.test.cjs` executes the actual bundled rules and adjudication code. - Initial-position perft depths 1/2/3: **20 / 400 / 8,902**. - Kiwipete depths 1/2/3: **48 / 2,039 / 97,862**. - Standard rook/pawn endgame position depths 1/2/3: **14 / 191 / 2,812**. - Castling through check rejected; rook movement permanently removes its castling right. - Pinned-piece self-check rejected. - En passant exposing the king rejected, excluded from repetition key; immediate-turn expiry checked. - Queen, rook, bishop and knight promotions. - Mate takes precedence over the 75-move draw; stalemate recognized. - Threefold remains claimable; fivefold is automatic. - 50-move claim, 75-move automatic result, and intended-move claim without altering the position. - Two knights versus a king not falsely declared dead. - Same-color bishop-only dead material; opposite-color bishop positions not falsely declared dead. - Timeout side-specific material cases, including opponent blocking material. - Timestamp clock accounting, Fischer increment, pause, and undo restoring FEN, keys and clock balances. - Malformed king/castling/en-passant FENs rejected. - PGN round trip, SAN and mate notation. - ASP rules copies match browser sources byte-for-byte. ### ASP contract: 11 passing groups under an in-memory ADO adapter `chess/tests/server-contract.test.cjs` executes the actual ASP JScript with substituted Request/Response/ADO objects. It verifies request logic, **not IIS or real SQL Server**. - Server-generated separate seat credentials; waiting-room state. - No move before second player joins; exactly two seats. - Wrong token, wrong turn and illegal moves rejected without changing stored state. - Legal moves use server clocks/increments and ignore forged clock/result fields. - Duplicate and stale versions rejected. - Other-seat agreement required for takebacks; clock restoration. - Draw offers and rematches; rematch swaps seats. - Polling adjudicates absent-player timeout. - Expired rooms rejected. ### Chromium browser tests `chess/tests/browser.test.cjs` ran against a local static HTTP server in headless Chromium 134 using Playwright. Browser-only production code was tested; no ASP runtime was involved. - Stockfish JS/WASM loads in a worker and plays a legal reply after e4. - All five configured strength levels return legal moves; tested mate-in-one position is recognized. - Search cancellation rejects obsolete work; UI continues rendering during a worker search. - Restart during an Expert search does not receive a stale computer move. - Solo undo removes the human move and computer reply. - Review does not pause clocks; elapsed timestamps account for background time. - Refresh restores saved position and paused state. - Promotion dialog and knight selection. - Legal destination indicators, keyboard Escape cancellation, and mouse drag. - Desktop layout and narrow 412px / 360px phone layouts have no horizontal overflow; main phone controls fit with the board. - Engine-fetch failure produces an explicit error without a substitute opponent. - No browser page errors during these tests. - Desktop and phone screenshots visually inspected for piece distinction, contrast, fit, and control placement. Engine binary hashes and embedded-network hash were checked. Runtime files match the exact upstream source revision. Menu comparison verifies that the only change to the recovered `games.asp` is the Chess list entry. ## Not verified here / known limitations - **No live IIS, Classic ASP engine, ADO provider, or SQL Server was available. Live private multiplayer is not verified.** The contract adapter does not prove actual SQL locking, real simultaneous requests, provider binding behavior, IIS configuration, or cross-device reconnect behavior. - No physical Google Pixel 8a test, Safari test, or real operating-system sleep test. Phone layout and elapsed-time logic were tested in Chromium emulation. - Full arbitrary dead-position and timeout reachability are not implemented; see `RULES-AND-CLOCKS.md`. Standard material cases are covered. This is a substantive rules limitation, not a tested claim of complete FIDE adjudication. - FEN validation checks legal structure, not full reachability from the starting position. - PGN import supports a single standard-chess main line using the bundled library. Chess960, variants and arbitrary recursive annotation variations are outside scope. Import rejects invalid main-line moves; variation-rich files may need their main line exported first. - Create/join responses lost before seat credentials arrive can strand that allocated seat; a new room is needed. After successful allocation, refresh and ordinary interrupted move requests recover using the saved token and authoritative polling. - Engine strength labels are approximate, not measured Elo ratings. No claim of parity with a full desktop Stockfish build is made. ## Focused IIS deployment checklist 1. Open `/chess/` over HTTPS in Edge/Chrome and on the Pixel. Start an Expert game as Black; confirm the computer moves and no engine error occurs. Turn sound on after a tap. 2. Run SQL install, then create a 3+2 private room. Join from another browser/device. Confirm exactly two seats and correct color assignment. A third browser must be rejected. 3. Refresh both browsers during play; each must regain its own seat. Disconnect/reconnect one device; the active clock must continue and state must converge. 4. Attempt a move with the other player's turn, an illegal square, a fabricated token, altered clock/result fields, and a stale version. Each must be rejected or ignored appropriately; stored clocks/results must remain server-derived. 5. Send two simultaneous move requests with the same version, including two copies of the same move. Exactly one may commit; the other must return stale-state/turn rejection. Inspect SQL and private IIS logs for binding or transaction failures. 6. Stop requests from the player whose clock is running. The other player's poll must record the correct timeout result. Verify the bare-king draw exception using shared-rule tests, since online custom FEN injection is intentionally unavailable. 7. Test draw decline/accept, optional takeback disabled/enabled, clock restoration, resignation, and agreed rematch with colors swapped. Verify a move clears an outstanding draw offer. 8. Test the invite link and room code independently. Confirm it contains no seat token. Confirm direct requests for `.inc` files are denied and ASP source/credentials are never returned. 9. Test engine retry after temporarily missing WASM, and restore it. Confirm `.wasm` is served as `application/wasm` without requiring cross-origin-isolation headers. 10. Open the source download links in the in-game documentation. Keep source and licenses available alongside the distributed WASM. Test room expiration in a disposable room and run cleanup. ## Re-running developer checks (optional) No development runtime is needed on the production server. In a separate development environment, run the two `.cjs` rules/contract tests with Node. For browser tests, install Playwright/Chromium, serve `chess/` on HTTP, and set `CHESS_TEST_URL` if not using port 8765; `CHESS_CHROMIUM` can specify a browser executable. These scripts are provided for reproducibility, not as a production prerequisite.