probe-filters 1.0.0 → 1.0.1
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/README.md +41 -0
- package/package.json +1 -1
- package/src/index.js +1 -1
- package/src/multiFilter.js +2 -1
- package/src/pointFilter.js +2 -871
- package/src/rangeFilter.js +17 -10
- package/src/v2/expansion.js +143 -0
- package/src/v2/metadata.js +208 -0
- package/src/v2/operations.js +248 -0
- package/src/v2/pointFilter.js +220 -0
- package/src/v2/storage.js +111 -0
- package/src/v2/utils.js +17 -0
package/README.md
CHANGED
|
@@ -285,6 +285,47 @@ temporal.queryWithinLast('sensor:42', 60_000); // true — seen in last m
|
|
|
285
285
|
temporal.queryBetweenAges('sensor:42', 30_000, 90_000); // true — seen 30-90s ago
|
|
286
286
|
```
|
|
287
287
|
|
|
288
|
+
### Game engine — spatial interest management
|
|
289
|
+
|
|
290
|
+
Avoid O(n²) entity distance checks. Insert positions into a SpatialFilter; query a box around the player to find candidate entities before running expensive exact checks. Remove despawned entities and adapt stale keepsake boxes to keep false positives low as entities move.
|
|
291
|
+
|
|
292
|
+
```js
|
|
293
|
+
const world = new SpatialFilter({ bitsPerCoordinate: 14, coordinateSystem: 'integer' });
|
|
294
|
+
|
|
295
|
+
// Server tick: insert entity positions
|
|
296
|
+
world.insert([1523, 871]);
|
|
297
|
+
world.insert([1600, 900]);
|
|
298
|
+
|
|
299
|
+
// Entity teleports — remove old, insert new
|
|
300
|
+
world.delete([1523, 871]);
|
|
301
|
+
world.insert([1530, 875]);
|
|
302
|
+
|
|
303
|
+
// Interest query: any entity near player?
|
|
304
|
+
const range = 100;
|
|
305
|
+
if (world.queryBox([1525 - range, 870 - range],
|
|
306
|
+
[1525 + range, 870 + range])) {
|
|
307
|
+
// Candidate found — run exact distance checks
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Entity despawns — unconditionally remove
|
|
311
|
+
world.delete([1530, 875]);
|
|
312
|
+
|
|
313
|
+
// Stale keepsake boxes may leave false positives behind
|
|
314
|
+
world.adaptFalsePositiveBox([1525 - range, 870 - range],
|
|
315
|
+
[1525 + range, 870 + range]);
|
|
316
|
+
|
|
317
|
+
// Anti-cheat: has this player jumped in the last 500ms?
|
|
318
|
+
const actions = new TemporalFilter({
|
|
319
|
+
bucketDurationMs: 100, retentionDurationMs: 2_000,
|
|
320
|
+
});
|
|
321
|
+
actions.insertAt('player:42:jump', Date.now());
|
|
322
|
+
actions.queryWithinLast('player:42:jump', 500); // true → flag excessive input
|
|
323
|
+
|
|
324
|
+
// Merge snapshot from another server shard
|
|
325
|
+
const neighbor = MultiFilter.deserialize(wire);
|
|
326
|
+
world.mergeFrom(neighbor, 'union');
|
|
327
|
+
```
|
|
328
|
+
|
|
288
329
|
## SEE ALSO
|
|
289
330
|
|
|
290
331
|
**probe-maplets** — key-value maplet extensions providing value aggregation on top of probe-filters filters.
|
package/package.json
CHANGED
package/src/index.js
CHANGED
package/src/multiFilter.js
CHANGED
|
@@ -24,7 +24,8 @@ function insertMotherHash(targetFilter, motherHash, state = 1) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function mergeAlephFilters(targetFilter, sourceFilter) {
|
|
27
|
-
|
|
27
|
+
const cap = sourceFilter.physicalCapacity ?? sourceFilter.currentCapacity;
|
|
28
|
+
for (let i = 0; i < cap; i++) {
|
|
28
29
|
const state = sourceFilter.states[i];
|
|
29
30
|
if (!isLiveAlephState(state)) continue;
|
|
30
31
|
insertMotherHash(targetFilter, sourceFilter.motherHashes[i], state);
|