@nice2dev/game-engine 1.2.1 → 1.2.2

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 CHANGED
@@ -1,5 +1,44 @@
1
1
  # @nice2dev/game-engine — Changelog
2
2
 
3
+ ## 1.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 06eb0d2: 1.2.2 — library texts through the translator, a translator in the packages that had none, and the
8
+ end of the hook-dependency warnings. Nothing removed or renamed. Upgrade notes:
9
+ `documentation/omniverk/OMNIVERK_UPGRADE_1.2.2.md`.
10
+
11
+ **Translations.** 2,825 new keys in the global dictionary (en, pl, de, fr, es, uk), 80 in the local
12
+ dictionaries of ui-math, ui-diagrams and ui-presentations: column headers, option labels, texts in
13
+ conditions and templates, messages given to setters, labels returned by helpers, Polish texts that
14
+ were the English default. Relative dates through `Intl.RelativeTimeFormat`, plural forms through
15
+ `…One` / `…Many` keys. ui-science, ui-platform, ui-mobile, auth, licensing, templates, social and
16
+ the icon tools translate through `useNiceTranslation` (new peer `@nice2dev/ui-core ^1.2.0`);
17
+ ui-security reads the global translator when its own provider is absent.
18
+
19
+ **Additions.** `labelKey` on ui-mobile `TabItem` and `SwipeAction` (the presets set it);
20
+ `registerWebAuthn` / `authenticateWebAuthn` take the WebAuthn options `NiceWebAuthnButton` used to
21
+ drop (defaults unchanged); `NiceKeyboardHint` shows `descriptionKey`. Eight icons in
22
+ `@nice2dev/icons` — `NtdPoint`, `NtdSegment`, `NtdPerpendicular`, `NtdParallel`, `NtdMidpoint`,
23
+ `NtdAngleBisector`, `NtdGroup`, `NtdUngroup` — and the same names as `NiceIcon` built-ins.
24
+
25
+ **Behaviour changes, agreed.** ui-math, ui-diagrams and ui-presentations follow the app's global
26
+ `NiceI18nProvider` language when their own provider is absent (they stayed English);
27
+ `NicePresentationEditor` without `lang` takes the surrounding language. Icons drawn as glyphs are
28
+ Nice icons: the `NiceGeometry` tools, Align / Group / Ungroup / Layout of the diagram toolbar, the
29
+ presentation grid toggle, zoom and "Add Track" of `NiceDMXTimeline`. icons-gaming and
30
+ icons-filetypes name an icon by its `title` and are decorative without one, like `createIcon`
31
+ (screen readers read "GiHeart" or "DOCX file icon"); new optional `title` on the gaming icon props.
32
+
33
+ **Hook dependencies (161 → 0).** Fixed along the way: `NiceLowPowerMode` re-rendered forever from
34
+ mount and overflowed the stack on wake; `GenericPlayer` / `NiceGenericPlayerStage` restarted the
35
+ track on a volume change; `NiceDMXTimeline` called `onPlay` on every frame and missed cues added
36
+ during playback; `NiceConflictResolution` `autoResolve` never resolved; `NiceMAM` selected by the
37
+ previous filter; `NiceRulesEngine` "Run All" kept only the last result; `NiceCodeEditor` saved with
38
+ the first render's `onSave`; a consumer's cursor handler switched off `NiceCodeEditorAI`
39
+ completion; `useRadioStream` lost a volume set before the first play; `NiceGameEditor` shortcuts,
40
+ `useVoiceControl` continuous sessions, `NiceDeviceTrust` with a host storing the score.
41
+
3
42
  ## 1.2.1
4
43
 
5
44
  ### Patch Changes
@@ -624,6 +624,7 @@ function useGameplayAnalytics(eventBus, telemetryConfig, recordingConfig) {
624
624
  analyticsRef.current = new GameplayAnalytics(eventBus, telemetryConfig, recordingConfig);
625
625
  }
626
626
  return analyticsRef.current;
627
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- the configs are read once, when the instance is made (it has no setters for them)
627
628
  }, [eventBus]);
628
629
  React.useEffect(() => {
629
630
  return () => {
@@ -197,12 +197,20 @@ const NiceGameEditor = ({ project, onSave, className, style, tutorial, }) => {
197
197
  addLog('info', `Created entity "${name}" (#${entity.id})`);
198
198
  return entity.id;
199
199
  }, [world, refreshWorld, addLog]);
200
- // Keyboard shortcuts
200
+ // Keyboard shortcuts. The list is built once; Save and Delete reach the handlers of the latest
201
+ // render through a ref (they are declared below and change with the selection and the props) —
202
+ // until 1.2.2 they called the first render's, so Delete never saw a selection.
203
+ const shortcutActionsRef = React.useRef({ save: () => { }, deleteSelected: () => { } });
201
204
  const shortcuts = React.useMemo(() => [
202
205
  { key: 'z', ctrl: true, action: () => undoStack.undo(), description: 'Undo' },
203
206
  { key: 'z', ctrl: true, shift: true, action: () => undoStack.redo(), description: 'Redo' },
204
207
  { key: 'y', ctrl: true, action: () => undoStack.redo(), description: 'Redo' },
205
- { key: 's', ctrl: true, action: () => handleSave(), description: 'Save' },
208
+ {
209
+ key: 's',
210
+ ctrl: true,
211
+ action: () => shortcutActionsRef.current.save(),
212
+ description: 'Save',
213
+ },
206
214
  {
207
215
  key: 'v',
208
216
  action: () => dispatch({ type: 'SET_TOOL', tool: 'select' }),
@@ -229,13 +237,17 @@ const NiceGameEditor = ({ project, onSave, className, style, tutorial, }) => {
229
237
  action: () => dispatch({ type: 'TOGGLE_GRID' }),
230
238
  description: 'Toggle grid',
231
239
  },
232
- { key: 'Delete', action: () => deleteSelected(), description: 'Delete selected' },
240
+ {
241
+ key: 'Delete',
242
+ action: () => shortcutActionsRef.current.deleteSelected(),
243
+ description: 'Delete selected',
244
+ },
233
245
  {
234
246
  key: 'Escape',
235
247
  action: () => dispatch({ type: 'DESELECT_ALL' }),
236
248
  description: 'Deselect all',
237
249
  },
238
- ], []);
250
+ ], [undoStack]);
239
251
  useKeyboardShortcuts(shortcuts);
240
252
  const handleSave = React.useCallback(() => {
241
253
  if (!onSave) {
@@ -302,7 +314,8 @@ const NiceGameEditor = ({ project, onSave, className, style, tutorial, }) => {
302
314
  }
303
315
  },
304
316
  });
305
- }, [state.selectedEntities, world, undoStack]);
317
+ }, [state.selectedEntities, world, undoStack, refreshWorld, addLog, events]);
318
+ shortcutActionsRef.current = { save: handleSave, deleteSelected };
306
319
  const ctxValue = React.useMemo(() => ({
307
320
  state,
308
321
  dispatch,
@@ -622,6 +622,7 @@ function useGameplayAnalytics(eventBus, telemetryConfig, recordingConfig) {
622
622
  analyticsRef.current = new GameplayAnalytics(eventBus, telemetryConfig, recordingConfig);
623
623
  }
624
624
  return analyticsRef.current;
625
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- the configs are read once, when the instance is made (it has no setters for them)
625
626
  }, [eventBus]);
626
627
  useEffect(() => {
627
628
  return () => {
@@ -195,12 +195,20 @@ const NiceGameEditor = ({ project, onSave, className, style, tutorial, }) => {
195
195
  addLog('info', `Created entity "${name}" (#${entity.id})`);
196
196
  return entity.id;
197
197
  }, [world, refreshWorld, addLog]);
198
- // Keyboard shortcuts
198
+ // Keyboard shortcuts. The list is built once; Save and Delete reach the handlers of the latest
199
+ // render through a ref (they are declared below and change with the selection and the props) —
200
+ // until 1.2.2 they called the first render's, so Delete never saw a selection.
201
+ const shortcutActionsRef = useRef({ save: () => { }, deleteSelected: () => { } });
199
202
  const shortcuts = useMemo(() => [
200
203
  { key: 'z', ctrl: true, action: () => undoStack.undo(), description: 'Undo' },
201
204
  { key: 'z', ctrl: true, shift: true, action: () => undoStack.redo(), description: 'Redo' },
202
205
  { key: 'y', ctrl: true, action: () => undoStack.redo(), description: 'Redo' },
203
- { key: 's', ctrl: true, action: () => handleSave(), description: 'Save' },
206
+ {
207
+ key: 's',
208
+ ctrl: true,
209
+ action: () => shortcutActionsRef.current.save(),
210
+ description: 'Save',
211
+ },
204
212
  {
205
213
  key: 'v',
206
214
  action: () => dispatch({ type: 'SET_TOOL', tool: 'select' }),
@@ -227,13 +235,17 @@ const NiceGameEditor = ({ project, onSave, className, style, tutorial, }) => {
227
235
  action: () => dispatch({ type: 'TOGGLE_GRID' }),
228
236
  description: 'Toggle grid',
229
237
  },
230
- { key: 'Delete', action: () => deleteSelected(), description: 'Delete selected' },
238
+ {
239
+ key: 'Delete',
240
+ action: () => shortcutActionsRef.current.deleteSelected(),
241
+ description: 'Delete selected',
242
+ },
231
243
  {
232
244
  key: 'Escape',
233
245
  action: () => dispatch({ type: 'DESELECT_ALL' }),
234
246
  description: 'Deselect all',
235
247
  },
236
- ], []);
248
+ ], [undoStack]);
237
249
  useKeyboardShortcuts(shortcuts);
238
250
  const handleSave = useCallback(() => {
239
251
  if (!onSave) {
@@ -300,7 +312,8 @@ const NiceGameEditor = ({ project, onSave, className, style, tutorial, }) => {
300
312
  }
301
313
  },
302
314
  });
303
- }, [state.selectedEntities, world, undoStack]);
315
+ }, [state.selectedEntities, world, undoStack, refreshWorld, addLog, events]);
316
+ shortcutActionsRef.current = { save: handleSave, deleteSelected };
304
317
  const ctxValue = useMemo(() => ({
305
318
  state,
306
319
  dispatch,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nice2dev/game-engine",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Nice2Dev Game Engine — No-code game engine and editor for React",
5
5
  "author": "NiceToDev <contact@nicetodev.com>",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -73,7 +73,7 @@
73
73
  },
74
74
  "devDependencies": {
75
75
  "@microsoft/signalr": "^10.0.11",
76
- "@nice2dev/ui": "^1.2.1",
76
+ "@nice2dev/ui": "^1.2.2",
77
77
  "@rollup/plugin-commonjs": "^29.0.3",
78
78
  "@rollup/plugin-node-resolve": "^16.0.3",
79
79
  "@rollup/plugin-typescript": "^12.3.0",