@jgengine/sql 0.8.0 → 0.9.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 +16 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/sqlPersistence.js +25 -2
- package/llms.txt +124 -634
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,22 @@ Agents building on the published SDK can also read this programmatically:
|
|
|
11
11
|
same data as typed values, so an updater can diff its installed version against
|
|
12
12
|
the latest and surface the migration steps.
|
|
13
13
|
|
|
14
|
+
## Unreleased
|
|
15
|
+
|
|
16
|
+
## 0.9.0
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Mobile HUD fit — design-resolution UI scaling now applies to every game by default: `HudCanvas` measures the live viewport and scales the whole HUD from `PlayableGame.hudFit.designSize` (default 1600×900, clamps `minScale`/`maxScale` 0.4–1) so desktop-authored layouts shrink to fit a phone instead of overflowing it; `hudFit.mobile` overrides tune the phone fit separately. Pure math lives in `@jgengine/core/ui/hudScale` (`hudScaleForViewport`, `resolveHudFit`, `rectOverflow`, `overflowingPanels`); the shell mounts `@jgengine/react`'s `HudViewportProvider` around `GameUI` so games need no wiring.
|
|
21
|
+
- Graphics → UI scale — a player-facing `graphics.uiScale` slider (0.5–1.5, default 1) multiplies the computed HUD scale on every platform; the same resolution system drives desktop preference and mobile shrink.
|
|
22
|
+
- HUD overflow gate — `HudCanvas` measures every `HudPanel` against the viewport at runtime and reports offenders on a `data-hud-overflow` attribute (plus a console warning); `bun run shoot <game> --device mobile|both` now exits non-zero naming the panels that escape the viewport.
|
|
23
|
+
- Automatic visibility & streaming defaults — an engine-level `VisibilitySystem` (exported from `@jgengine/core`) gives every scene renderer-agnostic culling and asset-streaming policy with no per-object wiring: distance culling, preload margins, hysteresis, delayed unloading, multi-camera awareness (including cameras excluded from streaming), and per-object overrides (always-visible, never-unload, disabled culling/streaming, custom render distance and preload margin).
|
|
24
|
+
- Self-hosted asset mirror — `DEFAULT_RELEASE_BASE` now points at this repo's rolling `packs` release instead of the upstream host; a catalog-driven `mirror-assets` workflow (weekly cron + manual dispatch) keeps the mirror in sync with the asset catalog.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Mobile HUD fit is on by default — design-resolution HUD scaling now applies to every game with no config change (previously opt-in via `platforms: ["web", "mobile"]`). A desktop-only game keeps the legacy fixed 0.85 compact zoom by declaring `platforms: ["web"]` (without `"mobile"`).
|
|
29
|
+
|
|
14
30
|
## 0.8.0
|
|
15
31
|
|
|
16
32
|
Transport-agnostic multiplayer (socket.io, WebRTC p2p, LAN/Fly adapters) plus grid/voxel
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./sqlPersistence.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./sqlPersistence.js";
|
package/dist/sqlPersistence.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { trimFeedEntries } from "@jgengine/core/runtime/hostPersistence";
|
|
1
|
+
import { clampLimit, trimFeedEntries } from "@jgengine/core/runtime/hostPersistence";
|
|
2
2
|
import { applyRunReset } from "@jgengine/core/runtime/persistenceScope";
|
|
3
3
|
const SCHEMA_STATEMENTS = [
|
|
4
4
|
`CREATE TABLE IF NOT EXISTS jg_game_servers (
|
|
@@ -111,6 +111,12 @@ export function sqlPersistence(pool, now = Date.now) {
|
|
|
111
111
|
for (const chunk of plan.chunks) {
|
|
112
112
|
await upsertChunk(client, chunk);
|
|
113
113
|
}
|
|
114
|
+
if (plan.deletedChunks.length > 0) {
|
|
115
|
+
await client.query(`DELETE FROM jg_world_chunks WHERE server_id = $1 AND chunk_key = ANY($2::text[])`, [
|
|
116
|
+
plan.server.serverId,
|
|
117
|
+
plan.deletedChunks,
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
114
120
|
await upsertServer(client, plan.server);
|
|
115
121
|
});
|
|
116
122
|
},
|
|
@@ -121,6 +127,11 @@ export function sqlPersistence(pool, now = Date.now) {
|
|
|
121
127
|
await client.query(`DELETE FROM jg_world_chunks WHERE server_id = $1`, [reset.serverId]);
|
|
122
128
|
}
|
|
123
129
|
if (reset.wipeServerSession) {
|
|
130
|
+
await client.query(`DELETE FROM jg_feed_buffers WHERE server_id = $1`, [reset.serverId]);
|
|
131
|
+
await client.query(`DELETE FROM jg_leaderboard_rows WHERE game_id = $1 AND server_id = $2`, [
|
|
132
|
+
reset.gameId,
|
|
133
|
+
reset.serverId,
|
|
134
|
+
]);
|
|
124
135
|
await client.query(`DELETE FROM jg_game_servers WHERE server_id = $1`, [reset.serverId]);
|
|
125
136
|
}
|
|
126
137
|
}
|
|
@@ -131,8 +142,12 @@ export function sqlPersistence(pool, now = Date.now) {
|
|
|
131
142
|
if (reset.wipeChunks) {
|
|
132
143
|
await client.query(`DELETE FROM jg_world_chunks WHERE server_id = $1`, [serverId]);
|
|
133
144
|
}
|
|
145
|
+
if (reset.wipeServerSession) {
|
|
146
|
+
await client.query(`DELETE FROM jg_feed_buffers WHERE server_id = $1`, [serverId]);
|
|
147
|
+
}
|
|
134
148
|
}
|
|
135
149
|
if (reset.wipeServerSession) {
|
|
150
|
+
await client.query(`DELETE FROM jg_leaderboard_rows WHERE game_id = $1`, [reset.gameId]);
|
|
136
151
|
await client.query(`DELETE FROM jg_game_servers WHERE game_id = $1`, [reset.gameId]);
|
|
137
152
|
}
|
|
138
153
|
}
|
|
@@ -184,6 +199,14 @@ export function sqlPersistence(pool, now = Date.now) {
|
|
|
184
199
|
}
|
|
185
200
|
});
|
|
186
201
|
},
|
|
202
|
+
async deleteChunks(serverId, chunkKeys) {
|
|
203
|
+
if (chunkKeys.length === 0)
|
|
204
|
+
return;
|
|
205
|
+
await pool.query(`DELETE FROM jg_world_chunks WHERE server_id = $1 AND chunk_key = ANY($2::text[])`, [
|
|
206
|
+
serverId,
|
|
207
|
+
chunkKeys,
|
|
208
|
+
]);
|
|
209
|
+
},
|
|
187
210
|
async loadFeed({ serverId, action }) {
|
|
188
211
|
const result = await pool.query(`SELECT entries FROM jg_feed_buffers WHERE server_id = $1 AND action = $2`, [serverId, action]);
|
|
189
212
|
const row = result.rows[0];
|
|
@@ -210,7 +233,7 @@ export function sqlPersistence(pool, now = Date.now) {
|
|
|
210
233
|
});
|
|
211
234
|
},
|
|
212
235
|
async getLeaderboardTop(args) {
|
|
213
|
-
const limit =
|
|
236
|
+
const limit = clampLimit(args.limit, MAX_TOP_LIMIT, MAX_TOP_LIMIT);
|
|
214
237
|
const params = [args.gameId, args.scope, args.stat];
|
|
215
238
|
let filter = "";
|
|
216
239
|
if (args.serverId !== undefined) {
|