ultimatedarktower 4.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +105 -253
- package/dist/esm/index.mjs +943 -25
- package/dist/src/UltimateDarkTower.d.ts +7 -0
- package/dist/src/UltimateDarkTower.js +13 -1
- package/dist/src/UltimateDarkTower.js.map +1 -1
- package/dist/src/adapters/NoopBluetoothAdapter.d.ts +26 -0
- package/dist/src/adapters/NoopBluetoothAdapter.js +50 -0
- package/dist/src/adapters/NoopBluetoothAdapter.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +29 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/udtBleConnection.d.ts +13 -0
- package/dist/src/udtBleConnection.js +66 -19
- package/dist/src/udtBleConnection.js.map +1 -1
- package/dist/src/udtBluetoothAdapterFactory.d.ts +3 -1
- package/dist/src/udtBluetoothAdapterFactory.js +6 -0
- package/dist/src/udtBluetoothAdapterFactory.js.map +1 -1
- package/dist/src/udtBoardAdjacency.d.ts +25 -0
- package/dist/src/udtBoardAdjacency.js +397 -0
- package/dist/src/udtBoardAdjacency.js.map +1 -0
- package/dist/src/udtBoardAnchors.d.ts +34 -0
- package/dist/src/udtBoardAnchors.js +357 -0
- package/dist/src/udtBoardAnchors.js.map +1 -0
- package/dist/src/udtDisplayExports.d.ts +2 -0
- package/dist/src/udtDisplayExports.js +26 -0
- package/dist/src/udtDisplayExports.js.map +1 -0
- package/dist/src/udtFoes.d.ts +53 -0
- package/dist/src/udtFoes.js +47 -0
- package/dist/src/udtFoes.js.map +1 -0
- package/dist/src/udtHeroes.d.ts +30 -0
- package/dist/src/udtHeroes.js +38 -0
- package/dist/src/udtHeroes.js.map +1 -0
- package/dist/src/udtMonuments.d.ts +23 -0
- package/dist/src/udtMonuments.js +20 -0
- package/dist/src/udtMonuments.js.map +1 -0
- package/dist/src/udtTowerResponse.js +1 -2
- package/dist/src/udtTowerResponse.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`onTowerResponse` public callback (`UltimateDarkTower`).** A new assignable hook that fires with the **raw, verbatim bytes** (`Uint8Array`) of every non-battery tower notification (tower-state responses, command acknowledgements). It complements the decoded `onTowerStateUpdate` for consumers that need the exact packet rather than the parsed `TowerState` — e.g. a relay forwarding the tower's 20-byte state to other consumers. Documented in `docs/api/events.md`.
|
|
12
|
+
- **Hero + monument reference rosters (`src/udtHeroes.ts`, `src/udtMonuments.ts`).** New static rosters consumed by `ultimatedarktowerboard` (re-exported, not vendored); neither is seed-encoded. `HEROES` is the 14 heroes (4 base, 2 Alliances, 4 Covenant, 4 Expeditions — Expeditions provisional/unreleased) and `MONUMENTS` is the 8 Covenant monuments, each modeled as `{ id, name, source }` objects with `HERO_BY_ID` / `MONUMENT_BY_ID` lookups and `Hero`/`HeroId`/`Monument`/`MonumentId` types (per the data-additions plan §4/§6). `source` is a new `ContentSource` type (`'base' | 'alliances' | 'covenant' | 'expeditions'`) — distinct from the seed parser's `ExpansionType` and from `GameSource`. The Astromancer uses the Restoration Games store spelling, **Reverent**. (Supersedes the brief flat-string `MONUMENTS` added earlier in this Unreleased cycle.)
|
|
13
|
+
- **Board layout anchors + adjacency datasets** — two new data modules consumed by the `ultimatedarktowerboard` package (re-exported, not vendored). `udtBoardAnchors.ts` ships `BOARD_ANCHORS` (multi-slot `building`/`skull`/`hero`/`foe`/`marker` positions, normalized `[0,1]`, for all 60 locations) and `BOARD_IMAGE_INFO` (board-image size + circle center/radius + north heading), with types `Anchor`, `AnchorSlot`, `LocationAnchors`, `BoardAnchorMap`, `BoardImageInfo`. `udtBoardAdjacency.ts` ships `BOARD_ADJACENCY` (the undirected movement graph) plus pure BFS helpers `neighborsOf` / `stepDistance` / `shortestPath` and the `BoardAdjacency` type. Authored with `tools/location-marker` and generated by `tools/location-marker/gen-board-data.mjs` from `udtBoardData.json`; the graph reflects physical adjacency only (disconnected pairs → `Infinity`) and enforces no movement rules.
|
|
14
|
+
- **`BluetoothPlatform.NONE` + no-op adapter** — a software-only mode for consumers that hold tower state (broken seals, rendering) but never open a BLE connection. `new UltimateDarkTower({ platform: BluetoothPlatform.NONE })` returns a `NoopBluetoothAdapter` that reports "not connected" and throws a clear error if `connect()`/commands are attempted.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **Tower Emulator now plays the calibration sweep when "Calibrate" is pressed** — In the Tower Controller example, calibrating against the emulator only flipped the drums' calibrated flags; the 3D popup never ran the animated home sweep (top→middle→bottom) the way the Display package's own example does. The popup display only runs `runCalibration()` when an applied state carries the transient `command: TOWER_COMMANDS.calibration` marker, but the controller mirrors the plain BLE state (which has no `command` field), so the drums just snapped to "calibrated". The controller now sends a dedicated `calibrate` side-channel message to the popup on click (mirroring the existing `playAudio`/`playSequence` side-channels), and the popup stamps the command onto its current state to trigger the visual sweep. The popup also ignores the emulator's interim mirrored state (~1.5 s in) while its own sweep is animating so the staged sweep isn't cut short. The emulator imports `TOWER_COMMANDS`/`createDefaultTowerState` from the cycle-free `udtDisplayExports` barrel to stay clear of the bundle's circular dependency.
|
|
19
|
+
|
|
20
|
+
- **`npm run build` no longer fails on the Tower Emulator bundle** — `build:examples` aliases the bundled `ultimatedarktower` specifier to a constants-only module (not `index.ts`) to dodge the `UltimateDarkTower.ts` circular dependency that breaks the display package's module-level constant init. The display's `TowerDisplay.ts` imports `createDefaultTowerState`, which lives in `udtHelpers.ts` rather than `udtConstants.ts`, so esbuild failed with *"No matching export for import 'createDefaultTowerState'"*. Added a cycle-free barrel `src/udtDisplayExports.ts` (re-exports `udtConstants` + the pure `createDefaultTowerState` helper) and pointed the emulator alias at it.
|
|
21
|
+
|
|
22
|
+
- **Construction no longer throws in environments without Bluetooth** — Bluetooth platform detection is now deferred from the `UltimateDarkTower` constructor to `connect()`. Previously `new UltimateDarkTower()` with the default `AUTO` platform called `detectPlatform()` eagerly and threw *"Unable to detect Bluetooth platform"* where Web Bluetooth is unavailable (e.g. iOS Safari/Chrome — all iOS browsers use WebKit), crashing software-only consumers on load. The adapter is now created lazily on first `connect()`, so that error (if any) surfaces only when a connection is actually attempted. Explicit `WEB`/`NODE`/`NONE` still create eagerly.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **Documentation restructured** — Slimmed `README.md` to a hero page with screenshot strip, quickstart, and a documentation map. Split the 1,900-line `docs/API_REFERENCE.md` into focused topic files under `docs/api/` (connection, adapters, commands, state, events, logging, seed, diagnostics) plus an index at `docs/api/README.md`. Added new top-level docs: `docs/README.md` (hub), `docs/GETTING_STARTED.md` (tutorial), `docs/ARCHITECTURE.md` (layer diagrams + lifecycle), `docs/EXAMPLES.md` (what each demo demonstrates), `docs/ECOSYSTEM.md` (companion repos). Renamed `docs/TOWER_TROUBLESHOOTING_RG.md` → `docs/TROUBLESHOOTING.md`. Embedded real nRF Connect screenshots of the tower's BLE service tree in `docs/TOWER_TECH_NOTES.md` and added a Mermaid layer/position anatomy diagram. Added README files for the controller and game example apps. Replaced `docs/API_REFERENCE.md` with a stub that redirects to the new `docs/api/` index. Removed the obsolete `examples/controller/TOWER_EMULATOR_NPM_MIGRATION.md`.
|
|
27
|
+
- **API reference: board-data page + full coverage pass.** Added `docs/api/board-data.md` documenting the board geometry (`BOARD_LOCATIONS`/`BOARD_GROUPINGS`, `BOARD_ANCHORS`/`BOARD_IMAGE_INFO`, `BOARD_ADJACENCY` + `neighborsOf`/`stepDistance`/`shortestPath`) and the hero/monument/foe reference rosters — previously only mentioned in `ECOSYSTEM.md`. Backfilled the remaining un-referenced exports into their topic pages (`Confidence` + base-34 char helpers in seed, `DisconnectCause`/`DiagEventKind`/`BatterySample`/`CommandQueueSnapshot` in diagnostics, `TowerEventCallbacks` in events, `LogLevel`/`LogOutput` in logging, `parseDifferentialReadings` in state) so every public export now has a reference entry. Added the shared `docs/API_STYLE.md` standard plus a breadcrumb + changelog pointer on the API index.
|
|
28
|
+
|
|
9
29
|
## [4.0.1] - 2026-05-28
|
|
10
30
|
|
|
11
31
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,294 +1,146 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- [Built-in Support (auto-detected)](#built-in-support-auto-detected)
|
|
45
|
-
- [Custom Adapter Support](#custom-adapter-support)
|
|
46
|
-
- [Browser Support](#browser-support)
|
|
47
|
-
- [Known Issues](#known-issues)
|
|
48
|
-
- [Community](#community)
|
|
49
|
-
|
|
50
|
-
## Features
|
|
51
|
-
|
|
52
|
-
- **Multi-Platform Bluetooth** - Works in browsers (Web Bluetooth), Node.js (`@stoprocent/noble`), Electron, and React Native via custom adapters
|
|
53
|
-
- **Bluetooth Connection Management** - Reliable connection with automatic monitoring and disconnect detection
|
|
54
|
-
- **Tower Control** - Complete control over lights, sounds, and drum rotation
|
|
55
|
-
- **Game State Tracking** - Track glyph positions, broken seals, and skull counts
|
|
56
|
-
- **Event System** - Callback-based event handling for tower events
|
|
57
|
-
- **ESM + CJS** - Ships both an ES Module build and a CommonJS build; works with `import` and `require` without configuration
|
|
58
|
-
- **TypeScript Support** - Full TypeScript definitions and type safety
|
|
59
|
-
- **Comprehensive Logging** - Multi-output logging system for debugging
|
|
60
|
-
- **Battery Monitoring** - Real-time battery level tracking and low battery warnings
|
|
61
|
-
- **Extensible Adapter Pattern** - Implement `IBluetoothAdapter` for custom platforms
|
|
62
|
-
|
|
63
|
-
## Installation
|
|
64
|
-
|
|
65
|
-
### Browser / Web Applications
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="examples/assets/rtdtlogo.png" alt="Return to Dark Tower" width="420" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">UltimateDarkTower</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
TypeScript / JavaScript driver for the Bluetooth-enabled tower from Restoration Games' <em>Return to Dark Tower</em>.<br/>
|
|
9
|
+
Control lights, sounds, drum rotation, and track game state from browsers, Node.js, Electron, and React Native.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/ultimatedarktower"><img alt="npm version" src="https://img.shields.io/npm/v/ultimatedarktower"></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/ultimatedarktower"><img alt="npm downloads" src="https://img.shields.io/npm/dm/ultimatedarktower"></a>
|
|
15
|
+
<a href="https://github.com/ChessMess/UltimateDarkTower/actions/workflows/ci-matrix.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/ChessMess/UltimateDarkTower/ci-matrix.yml?branch=main&label=CI"></a>
|
|
16
|
+
<a href="LICENSE"><img alt="license" src="https://img.shields.io/npm/l/ultimatedarktower"></a>
|
|
17
|
+
<a href="https://www.typescriptlang.org/"><img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-Ready-blue"></a>
|
|
18
|
+
<a href="https://nodejs.org/"><img alt="node" src="https://img.shields.io/node/v/ultimatedarktower"></a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<p align="center"><strong>
|
|
24
|
+
<a href="https://chessmess.github.io/UltimateDarkTower/dist/examples/controller/TowerController.html">▶ Live Demo — Tower Controller</a>
|
|
25
|
+
</strong></p>
|
|
26
|
+
|
|
27
|
+
<p align="center"><em>
|
|
28
|
+
Power on your Tower and connect from Chrome / Edge / Samsung Internet or leave it in the box and use the built in Tower Emulator with full 3D rendered Tower!
|
|
29
|
+
</p><p align="center">
|
|
30
|
+
iOS users: Safari and Chrome doesn't support Web Bluetooth yet on Apples platform (works fine in Chrome on Android), you can use an app on the appstore that provides this feature. </br>Open the demo in the <a href="https://apps.apple.com/us/app/bluefy-web-ble-browser/id1492822055">Bluefy app</a>.
|
|
31
|
+
</em></p>
|
|
32
|
+
|
|
33
|
+
<table>
|
|
34
|
+
<tr>
|
|
35
|
+
<td align="center" width="34%"><a href="examples/controller/README.md"><img src="docs/screenshots/controller-thumb.png" alt="Controller example" /><br/><strong>Controller</strong></a><br/><sub>Full command surface + BLE diagnostics</sub></td>
|
|
36
|
+
<td align="center" width="33%"><a href="examples/game/README.md"><strong>Game</strong></a><br/><sub>A complete playable game on the tower</sub><br/><br/><em>(screenshot soon)</em></td>
|
|
37
|
+
<td align="center" width="33%"><a href="examples/node/README.md"><strong>Node CLI</strong></a><br/><sub>Minimal command-line driver</sub><br/><br/><em>(screenshot soon)</em></td>
|
|
38
|
+
</tr>
|
|
39
|
+
</table>
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Install
|
|
66
44
|
|
|
67
45
|
```bash
|
|
46
|
+
# Browser
|
|
68
47
|
npm install ultimatedarktower
|
|
69
|
-
```
|
|
70
48
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
```bash
|
|
49
|
+
# Node.js (adds the optional BLE peer dependency)
|
|
74
50
|
npm install ultimatedarktower @stoprocent/noble
|
|
75
51
|
```
|
|
76
52
|
|
|
77
|
-
>
|
|
78
|
-
>
|
|
79
|
-
> **Platform requirements:** macOS works out of the box. Linux requires BlueZ (`sudo apt install bluetooth bluez libbluetooth-dev`). Windows requires Windows 10+ with BLE support.
|
|
53
|
+
> **Platform notes.** Node.js 18+. macOS works out of the box. Linux needs BlueZ (`sudo apt install bluetooth bluez libbluetooth-dev`). Windows needs Windows 10+ with BLE support.
|
|
80
54
|
|
|
81
|
-
## Quick
|
|
82
|
-
|
|
83
|
-
### Browser (auto-detected)
|
|
55
|
+
## Quick start
|
|
84
56
|
|
|
85
57
|
```typescript
|
|
86
58
|
import UltimateDarkTower from 'ultimatedarktower';
|
|
87
59
|
|
|
88
60
|
const tower = new UltimateDarkTower();
|
|
89
|
-
await tower.connect(); // Opens browser device picker
|
|
90
|
-
await tower.calibrate();
|
|
91
|
-
await tower.playSound(1);
|
|
92
|
-
await tower.cleanup();
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Node.js (auto-detected)
|
|
96
61
|
|
|
97
|
-
|
|
98
|
-
|
|
62
|
+
tower.onTowerConnect = () => console.log('Connected.');
|
|
63
|
+
tower.onCalibrationComplete = () => console.log('Calibrated.');
|
|
99
64
|
|
|
100
|
-
|
|
101
|
-
await tower.
|
|
102
|
-
await tower.calibrate();
|
|
65
|
+
await tower.connect(); // browser: opens device picker; node: scans
|
|
66
|
+
await tower.calibrate(); // required before drum rotation is reliable
|
|
103
67
|
await tower.playSound(1);
|
|
104
|
-
await tower.cleanup();
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Explicit Platform Selection
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
import UltimateDarkTower, { BluetoothPlatform } from 'ultimatedarktower';
|
|
111
|
-
|
|
112
|
-
const tower = new UltimateDarkTower({ platform: BluetoothPlatform.NODE });
|
|
68
|
+
await tower.cleanup(); // always clean up on shutdown
|
|
113
69
|
```
|
|
114
70
|
|
|
115
|
-
|
|
71
|
+
> Walkthrough with explanations, error handling, lights, drum rotation, and a full example: [docs/GETTING_STARTED.md](docs/GETTING_STARTED.md).
|
|
116
72
|
|
|
117
|
-
|
|
118
|
-
import UltimateDarkTower, { IBluetoothAdapter } from 'ultimatedarktower';
|
|
119
|
-
|
|
120
|
-
class MyCustomAdapter implements IBluetoothAdapter {
|
|
121
|
-
// Implement all IBluetoothAdapter methods
|
|
122
|
-
// See docs/API_REFERENCE.md for the full interface
|
|
123
|
-
}
|
|
73
|
+
## Features
|
|
124
74
|
|
|
125
|
-
|
|
126
|
-
|
|
75
|
+
- **Multi-platform Bluetooth** — Web Bluetooth, Node.js (`@stoprocent/noble`), Electron, React Native via custom adapters.
|
|
76
|
+
- **Complete tower control** — lights, sounds, drum rotation, seal breaking, skull counter.
|
|
77
|
+
- **Stateful command variants** — preserve every other state when changing one field.
|
|
78
|
+
- **Glyph tracking** — automatic glyph position updates as drums rotate.
|
|
79
|
+
- **Game state** — seal state, broken seals, software-tracked across sessions.
|
|
80
|
+
- **BLE flight recorder** — opt-in disconnect diagnostics with structured event capture.
|
|
81
|
+
- **Event callbacks** — connect, calibrate, skull drop, battery, state change.
|
|
82
|
+
- **Logger** — pluggable outputs (console, DOM, in-memory buffer).
|
|
83
|
+
- **TypeScript-first** — full type definitions, ESM + CJS builds.
|
|
84
|
+
- **Seed parser** — decode, encode, validate, and compare game seeds.
|
|
127
85
|
|
|
128
86
|
## Documentation
|
|
129
87
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Comprehensive documentation with TypeScript examples, best practices, and troubleshooting guides.
|
|
133
|
-
|
|
134
|
-
### 📄 [Seed Format Specification](docs/SEED_FORMAT.md)
|
|
135
|
-
|
|
136
|
-
Complete documentation of the Return to Dark Tower game seed encoding — base-34 alphabet, setup section bitwise layout, RNG seed polynomial, and what each seed field controls.
|
|
137
|
-
|
|
138
|
-
### 🛠 [BLE Diagnostics (Flight Recorder)](docs/BLE_DIAGNOSTICS.md)
|
|
139
|
-
|
|
140
|
-
Opt-in diagnostic system for capturing BLE disconnect incidents. Tags each detection path, snapshots connection / queue / tower state at the moment of the drop, and includes a ring buffer of recent events so you can see the lead-up. Off by default; the controller example has a "BLE Debug" tab that exposes the full UI (toggle, live event stream, persistent incident log, JSON export).
|
|
141
|
-
|
|
142
|
-
### Key Topics Covered:
|
|
143
|
-
|
|
144
|
-
- **Multi-Platform Setup** - Configuration for Web, Node.js, Electron, and React Native
|
|
145
|
-
- **Connection Management** - Connecting, disconnecting, and monitoring connection health
|
|
146
|
-
- **Bluetooth Adapters** - Custom adapter interface for extending platform support
|
|
147
|
-
- **Tower Control** - Detailed coverage of all tower commands (lights, sounds, rotation)
|
|
148
|
-
- **Glyph System** - Automatic tracking of glyph positions as towers rotate
|
|
149
|
-
- **Seal Management** - Breaking seals and tracking game state
|
|
150
|
-
- **Seed Parser** - Decode, encode, validate, and compare game seeds
|
|
151
|
-
- **SystemRandom** - C# System.Random PRNG replica for game state prediction
|
|
152
|
-
- **Event Handling** - Callback system for tower events
|
|
153
|
-
- **Logging System** - Multi-output logging for debugging and monitoring
|
|
154
|
-
- **Best Practices** - Performance tips, error handling, and common patterns
|
|
155
|
-
- **Troubleshooting** - Solutions for common issues and debugging techniques
|
|
156
|
-
|
|
157
|
-
## Integration Testing
|
|
88
|
+
A guided map of the docs lives at [docs/README.md](docs/README.md). The headline pages:
|
|
158
89
|
|
|
159
|
-
|
|
90
|
+
| Page | Use it when… |
|
|
91
|
+
| -------------------------------------------- | --------------------------------------------------- |
|
|
92
|
+
| [Getting Started](docs/GETTING_STARTED.md) | …you're new and want a working tower in 10 minutes. |
|
|
93
|
+
| [API Reference](docs/api/README.md) | …you need the full surface, split by topic. |
|
|
94
|
+
| [Architecture](docs/ARCHITECTURE.md) | …you want to understand how the layers fit. |
|
|
95
|
+
| [Examples](docs/EXAMPLES.md) | …you want to know what the demo apps demonstrate. |
|
|
96
|
+
| [Tower Tech Notes](docs/TOWER_TECH_NOTES.md) | …you're reverse-engineering the protocol. |
|
|
97
|
+
| [Seed Format](docs/SEED_FORMAT.md) | …you're working with game seeds at the byte level. |
|
|
98
|
+
| [BLE Diagnostics](docs/BLE_DIAGNOSTICS.md) | …you want disconnect flight-recorder data. |
|
|
99
|
+
| [Troubleshooting](docs/TROUBLESHOOTING.md) | …the hardware is misbehaving. |
|
|
100
|
+
| [Ecosystem](docs/ECOSYSTEM.md) | …you want the companion libraries & tools. |
|
|
160
101
|
|
|
161
|
-
|
|
102
|
+
## Examples
|
|
162
103
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
- This will connect to the tower, perform a full calibration sequence, and print the resulting glyph positions.
|
|
168
|
-
- The test will fail if the tower is not available or calibration does not complete within 60 seconds.
|
|
169
|
-
- Integration tests are not included in automated test runs or npm publish.
|
|
170
|
-
|
|
171
|
-
### Lights Integration Test
|
|
172
|
-
|
|
173
|
-
The lights integration test validates the `allLightsOn` and `allLightsOff` API methods using real tower hardware.
|
|
174
|
-
|
|
175
|
-
**Test steps:**
|
|
176
|
-
|
|
177
|
-
- Turns all 24 LEDs on (solid effect) for 2 seconds
|
|
178
|
-
- Turns all 24 LEDs on (breathe effect) for 3 seconds
|
|
179
|
-
- Turns all 24 LEDs off
|
|
180
|
-
|
|
181
|
-
**How to run:**
|
|
182
|
-
|
|
183
|
-
```bash
|
|
184
|
-
npm run test:integration:lights
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
**Prerequisites:**
|
|
188
|
-
|
|
189
|
-
- Tower must be powered on and in Bluetooth range
|
|
190
|
-
- `@stoprocent/noble` must be installed
|
|
191
|
-
|
|
192
|
-
**Visual verification:**
|
|
193
|
-
|
|
194
|
-
- All lights on (solid) for 2 seconds
|
|
195
|
-
- All lights breathe effect for 3 seconds
|
|
196
|
-
- All lights off
|
|
197
|
-
|
|
198
|
-
See [API_REFERENCE.md](docs/API_REFERENCE.md) for API details on `allLightsOn` and `allLightsOff`.
|
|
104
|
+
- **[Controller](examples/controller/README.md)** — full reference UI with a BLE diagnostics tab and tower emulator.
|
|
105
|
+
- **[Game](examples/game/README.md)** — The Tower's Challenge, a complete browser game.
|
|
106
|
+
- **[Node CLI](examples/node/README.md)** — minimal interactive driver for verifying the Node adapter.
|
|
199
107
|
|
|
200
|
-
|
|
108
|
+
## Platform support
|
|
201
109
|
|
|
202
|
-
|
|
203
|
-
|
|
110
|
+
| Platform | Adapter | Notes |
|
|
111
|
+
| ---------------------------------------------------- | -------------- | ------------------------------------------------------------------------------- |
|
|
112
|
+
| Chrome / Edge / Samsung Internet (desktop + Android) | Built-in | Web Bluetooth |
|
|
113
|
+
| Node.js 18+ | Built-in | Requires `@stoprocent/noble` |
|
|
114
|
+
| Electron | Built-in | Auto-detects renderer vs main process |
|
|
115
|
+
| iOS Safari / iOS Chrome | — | Use [Bluefy](https://apps.apple.com/us/app/bluefy-web-ble-browser/id1492822055) |
|
|
116
|
+
| Firefox | — | No Web Bluetooth |
|
|
117
|
+
| React Native | Custom adapter | `react-native-ble-plx` recommended — see [adapters guide](docs/api/adapters.md) |
|
|
118
|
+
| Cordova / Capacitor | Custom adapter | See [adapters guide](docs/api/adapters.md) |
|
|
204
119
|
|
|
205
|
-
##
|
|
120
|
+
## Related projects
|
|
206
121
|
|
|
207
|
-
|
|
122
|
+
This library is part of a wider Return to Dark Tower family. See [docs/ECOSYSTEM.md](docs/ECOSYSTEM.md) for the full list. Highlights:
|
|
208
123
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
# Build the project
|
|
214
|
-
npm run build
|
|
215
|
-
|
|
216
|
-
# Run tests
|
|
217
|
-
npm test
|
|
218
|
-
|
|
219
|
-
# Run tests with coverage
|
|
220
|
-
npm run test:coverage
|
|
221
|
-
|
|
222
|
-
# Lint code
|
|
223
|
-
npm run lint
|
|
224
|
-
|
|
225
|
-
# Watch mode for development
|
|
226
|
-
npm run watch
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### Project Structure
|
|
124
|
+
- **[UltimateDarkTowerDisplay](https://github.com/ChessMess/UltimateDarkTowerDisplay)** — composable renderers (text, 2D, 3D) for tower state.
|
|
125
|
+
- **[UltimateDarkTowerSync](https://github.com/ChessMess/UltimateDarkTowerSync)** — state synchronization across devices.
|
|
126
|
+
- **[mcp-server-return-to-dark-tower](https://github.com/ChessMess/mcp-server-return-to-dark-tower)** — MCP server exposing tower control to AI agents.
|
|
230
127
|
|
|
231
|
-
|
|
232
|
-
src/
|
|
233
|
-
├── index.ts # Main exports
|
|
234
|
-
├── UltimateDarkTower.ts # Main class
|
|
235
|
-
├── udtBluetoothAdapter.ts # Bluetooth adapter interface & error types
|
|
236
|
-
├── udtBluetoothAdapterFactory.ts # Platform auto-detection factory
|
|
237
|
-
├── udtBleConnection.ts # Bluetooth connection management
|
|
238
|
-
├── udtTowerCommands.ts # Tower command implementations
|
|
239
|
-
├── udtCommandFactory.ts # Command creation utilities
|
|
240
|
-
├── udtCommandQueue.ts # Command queue management
|
|
241
|
-
├── udtTowerResponse.ts # Response handling
|
|
242
|
-
├── udtTowerState.ts # Tower state management
|
|
243
|
-
├── udtGameBoard.ts # Board locations, kingdoms, and terrain data
|
|
244
|
-
├── udtSeedParser.ts # Game seed encoding/decoding (base-34)
|
|
245
|
-
├── udtSystemRandom.ts # C# System.Random PRNG replica
|
|
246
|
-
├── udtHelpers.ts # Utility helper functions
|
|
247
|
-
├── udtLogger.ts # Logging system
|
|
248
|
-
├── udtConstants.ts # Constants and type definitions
|
|
249
|
-
└── adapters/
|
|
250
|
-
├── WebBluetoothAdapter.ts # Browser Web Bluetooth implementation
|
|
251
|
-
└── NodeBluetoothAdapter.ts # Node.js @stoprocent/noble BLE implementation
|
|
252
|
-
|
|
253
|
-
examples/
|
|
254
|
-
├── controller/ # Tower controller web app
|
|
255
|
-
├── game/ # Tower game web app
|
|
256
|
-
├── node/ # Node.js CLI example
|
|
257
|
-
└── assets/ # Shared assets (images, fonts, etc.)
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
## Platform Support
|
|
261
|
-
|
|
262
|
-
### Built-in Support (auto-detected)
|
|
128
|
+
## Known issues
|
|
263
129
|
|
|
264
|
-
|
|
265
|
-
| -------------------------------- | ------------------------------------ | ---------------------------------------- |
|
|
266
|
-
| Chrome / Edge / Samsung Internet | Web Bluetooth API | Desktop and Android |
|
|
267
|
-
| Node.js | `@stoprocent/noble` | Requires `npm install @stoprocent/noble` |
|
|
268
|
-
| Electron | Web Bluetooth or `@stoprocent/noble` | Auto-detects renderer vs main process |
|
|
130
|
+
- **Sound and animation completion** — the tower reports "command complete" the moment a sound or animation _starts_, not when it ends. Don't use the completion response as a "ready for next sound" signal; sleep or use the LED-sequence response timing documented in [docs/TOWER_TECH_NOTES.md](docs/TOWER_TECH_NOTES.md#animation-response-timing).
|
|
269
131
|
|
|
270
|
-
|
|
132
|
+
## Contributing
|
|
271
133
|
|
|
272
|
-
|
|
273
|
-
| -------------------------- | ---------------------- | ----------------------------- |
|
|
274
|
-
| React Native | `react-native-ble-plx` | Implement `IBluetoothAdapter` |
|
|
275
|
-
| iOS (via React Native) | `react-native-ble-plx` | Same as React Native |
|
|
276
|
-
| Android (via React Native) | `react-native-ble-plx` | Same as React Native |
|
|
277
|
-
| Cordova / Capacitor | Platform BLE plugin | Implement `IBluetoothAdapter` |
|
|
134
|
+
Workflow, code standards, release process, and hardware testing instructions: [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
278
135
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
**iOS:** Use the [Bluefy app](https://apps.apple.com/us/app/bluefy-web-ble-browser/id1492822055) as Chrome/Safari does not support Web Bluetooth on Apple platforms.
|
|
282
|
-
|
|
283
|
-
**Not Supported:** Firefox, Safari ([compatibility details](https://caniuse.com/?search=web%20bluetooth))
|
|
136
|
+
## Community
|
|
284
137
|
|
|
285
|
-
|
|
138
|
+
Questions? Ideas? Join us on our UltimateDarkTower [Discord Server](https://discord.gg/njgXj6ay3g)!
|
|
286
139
|
|
|
287
|
-
|
|
288
|
-
- **Light Sequences** - Same as sound for lights that play for a duration.
|
|
140
|
+
You can also find us in the RTDT Fan Content Channel on [Restoration Games Discord](https://discord.com/channels/722465956265197618/1167555008376610945/1167842435766952158).
|
|
289
141
|
|
|
290
|
-
|
|
142
|
+
---
|
|
291
143
|
|
|
292
|
-
##
|
|
144
|
+
## Personal note from the Developer
|
|
293
145
|
|
|
294
|
-
|
|
146
|
+
I have spent many hours reverse engineering the Tower's protocol (by hand, this was before AI existed :D) in order to create this library, I look forward to what others will create using this! - Chris
|