dewdrop-sdk 0.5.3 → 0.5.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dewdrop-sdk",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "Build a three.js game for Dewdrop: the Vite plugin, model calls, multiplayer, saves and voice.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/backend.js CHANGED
@@ -7,7 +7,7 @@
7
7
  // past its cap. The page's URL says which room the tab joins and under
8
8
  // what name; on Dewdrop the game's page says which room, and the name is
9
9
  // the player's username.
10
- import { MAX_NET_CLIENTS, MAX_NET_CLIENT_FRAME_BYTES, createInbox, createOutbox, defineHandlers, label, side, unpack } from './net.js';
10
+ import { DEFAULT_ROOM_PLAYERS, MAX_NET_CLIENTS, MAX_NET_CLIENT_FRAME_BYTES, createInbox, createOutbox, defineHandlers, label, side, unpack } from './net.js';
11
11
  import { NO_CHANNEL } from './route.js';
12
12
 
13
13
  let channel = null;
@@ -59,9 +59,9 @@ function name(text) {
59
59
  }
60
60
 
61
61
  // The players a room seats as `?players=` names them: a whole number from
62
- // 1 to MAX_NET_CLIENTS, or the most without one or with any other.
62
+ // 1 to MAX_NET_CLIENTS, or DEFAULT_ROOM_PLAYERS without one or with any other.
63
63
  function players(text) {
64
- return /^[0-9]{1,3}$/.test(text) && Number(text) >= 1 && Number(text) <= MAX_NET_CLIENTS ? Number(text) : MAX_NET_CLIENTS;
64
+ return /^[0-9]{1,3}$/.test(text) && Number(text) >= 1 && Number(text) <= MAX_NET_CLIENTS ? Number(text) : DEFAULT_ROOM_PLAYERS;
65
65
  }
66
66
 
67
67
  // Where a page's URL joins its tab: the room `?room=` names, the name
@@ -86,7 +86,7 @@ export function gameHasBackend() {
86
86
  // function at the next animation frame. Without a plugin there is no
87
87
  // channel, and `send` says so. A room that seats no more says so in the
88
88
  // console, as Dewdrop refuses the connect, and the tab's sends reach no one.
89
- export function attachBackend(hot, { channel: routed, hasBackend: present, frame: schedule, room = '', player = '', players = MAX_NET_CLIENTS }) {
89
+ export function attachBackend(hot, { channel: routed, hasBackend: present, frame: schedule, room = '', player = '', players = DEFAULT_ROOM_PLAYERS }) {
90
90
  if (!routed) return;
91
91
  channel = hot;
92
92
  hasBackend = present;
package/src/index.js CHANGED
@@ -5,8 +5,9 @@
5
5
  // runs, `clients`, in that backend, over its port back, and `saves` into
6
6
  // the browser's own storage, which the plugin's script empties as each
7
7
  // page loads; `session` says when a session ends ahead of time, which here
8
- // none does, and lets a game end its player's session, which here ends
9
- // nothing; and `voice` reads the microphone through the browser's own
8
+ // none does, lets a game end its player's session, which here ends
9
+ // nothing, and lets a game allow portrait views, which here the browser's
10
+ // window already gives; and `voice` reads the microphone through the browser's own
10
11
  // audio worklet, into the chunks a game gets on Dewdrop.
11
12
  export { llm } from './llm.js';
12
13
  export { backend } from './backend.js';
package/src/net.js CHANGED
@@ -18,6 +18,9 @@ export const MAX_NET_PLAYER_BYTES = 64;
18
18
  // The most players a room seats, and the most clients it holds: a room's
19
19
  // size is 1 to this.
20
20
  export const MAX_NET_CLIENTS = 100;
21
+ // The players a room seats when its page names no size: the most a game's
22
+ // room seats on Dewdrop until its developer says otherwise.
23
+ export const DEFAULT_ROOM_PLAYERS = 8;
21
24
  // How often the local backend ticks: sixty times a second.
22
25
  export const NET_TICK_MS = 1000 / 60;
23
26
 
package/src/serve.js CHANGED
@@ -17,7 +17,7 @@
17
17
  import { existsSync, readFileSync } from 'node:fs';
18
18
  import { dirname, resolve } from 'node:path';
19
19
  import { Worker } from 'node:worker_threads';
20
- import { MAX_NET_CLIENTS, label } from './net.js';
20
+ import { DEFAULT_ROOM_PLAYERS, MAX_NET_CLIENTS, label } from './net.js';
21
21
 
22
22
  // How long a room's backend runs on after its last tab's leave, as on
23
23
  // Dewdrop.
@@ -174,13 +174,13 @@ export function createBackendHost({ entry, ws, watcher, origin = () => '', log =
174
174
  // A tab joins the room its page named under the name it gave, a room
175
175
  // it makes seating the players its page said; a page that named
176
176
  // neither joins the empty room unnamed, and one that named no size a
177
- // room seating the most.
178
- join(client, { room = '', player = '', players = MAX_NET_CLIENTS } = {}) {
177
+ // room seating DEFAULT_ROOM_PLAYERS, as a game's rooms on Dewdrop do.
178
+ join(client, { room = '', player = '', players = DEFAULT_ROOM_PLAYERS } = {}) {
179
179
  if (tabs.has(client)) return;
180
180
  const key = typeof room === 'string' ? room : '';
181
181
  let it = rooms.get(key);
182
182
  if (it === undefined) {
183
- const capacity = Number.isInteger(players) && players >= 1 && players <= MAX_NET_CLIENTS ? players : MAX_NET_CLIENTS;
183
+ const capacity = Number.isInteger(players) && players >= 1 && players <= MAX_NET_CLIENTS ? players : DEFAULT_ROOM_PLAYERS;
184
184
  it = createRoom(key, capacity);
185
185
  rooms.set(key, it);
186
186
  }
package/src/session.js CHANGED
@@ -12,12 +12,21 @@
12
12
  // `session.exit()`, which on Dewdrop takes the player back to Dewdrop's
13
13
  // home page while the room's other players play on, the game hearing
14
14
  // `'exit'` as it goes; a backend has no player to send anywhere, so there it
15
- // throws NotSupportedError. `npm run dev` ends no session, so here `ending`
16
- // stays null and the event never fires, a game trying its handler by
17
- // calling it, and `exit()` ends nothing: the console says so, once.
15
+ // throws NotSupportedError. A game that lays itself out for either shape
16
+ // calls `session.allowPortrait()`, after which Dewdrop turns its view
17
+ // portrait whenever its player's page asks — a phone held upright — and the
18
+ // game hears each turn as a `resize`, its window taking the view's new
19
+ // shape; until then a session stays landscape, and a backend, which has no
20
+ // view, throws NotSupportedError. `npm run dev` ends no session, so here
21
+ // `ending` stays null and the event never fires, a game trying its handler
22
+ // by calling it, and `exit()` ends nothing: the console says so, once. The
23
+ // game here is the browser's own window, which already takes any shape and
24
+ // fires its own `resize`, so `allowPortrait()` changes nothing and says
25
+ // what it does on Dewdrop, once.
18
26
  import { defineHandlers, side } from './net.js';
19
27
 
20
28
  let told = false;
29
+ let toldPortrait = false;
21
30
  class Session extends EventTarget {
22
31
  get ending() { return null; }
23
32
  exit() {
@@ -26,6 +35,12 @@ class Session extends EventTarget {
26
35
  told = true;
27
36
  console.info('[dewdrop] session.exit(): on Dewdrop this ends the session and takes the player back to Dewdrop’s home page; npm run dev keeps the game running');
28
37
  }
38
+ allowPortrait() {
39
+ if (side.backend) throw new DOMException('session.allowPortrait is unavailable in a backend', 'NotSupportedError');
40
+ if (toldPortrait) return;
41
+ toldPortrait = true;
42
+ console.info('[dewdrop] session.allowPortrait(): on Dewdrop the view turns portrait whenever the player’s page is taller than wide, each turn a resize; npm run dev’s window already takes any shape');
43
+ }
29
44
  }
30
45
  defineHandlers(Session.prototype, ['ending']);
31
46