refactor: collapse item modules into plugins and remove no-op client item behaviors

This commit is contained in:
Jage9
2026-02-24 03:00:30 -05:00
parent d4dbb807da
commit 7903bab131
38 changed files with 375 additions and 345 deletions

View File

@@ -1,26 +1,14 @@
import { type IncomingMessage } from '../../network/protocol';
import { type GameMode, type WorldItem } from '../../state/gameState';
import { createClockBehavior } from './clock/behavior';
import { createDiceBehavior } from './dice/behavior';
import { createPianoBehavior } from './piano/behavior';
import { createRadioStationBehavior } from './radioStation/behavior';
import { type ItemBehavior, type ItemBehaviorDeps } from './runtimeShared';
import { createWheelBehavior } from './wheel/behavior';
import { createWidgetBehavior } from './widget/behavior';
/** Runtime registry that composes all per-item client behavior modules. */
export class ItemBehaviorRegistry {
private readonly behaviors: ItemBehavior[];
constructor(deps: ItemBehaviorDeps) {
this.behaviors = [
createClockBehavior(deps),
createDiceBehavior(deps),
createPianoBehavior(deps),
createRadioStationBehavior(deps),
createWheelBehavior(deps),
createWidgetBehavior(deps),
];
this.behaviors = [createPianoBehavior(deps)];
}
/** Runs per-item initialization hooks after app bootstrap. */

View File

@@ -1,7 +0,0 @@
import { type ItemBehavior, type ItemBehaviorDeps } from '../runtimeShared';
/** Creates runtime behavior hooks for clock items. */
export function createClockBehavior(_deps: ItemBehaviorDeps): ItemBehavior {
return {};
}

View File

@@ -1,63 +0,0 @@
import { type ItemTypeClientDefinition } from '../shared';
export const CLOCK_TIME_ZONE_OPTIONS = [
'America/Anchorage',
'America/Argentina/Buenos_Aires',
'America/Chicago',
'America/Detroit',
'America/Halifax',
'America/Indiana/Indianapolis',
'America/Kentucky/Louisville',
'America/Los_Angeles',
'America/St_Johns',
'Asia/Bangkok',
'Asia/Dhaka',
'Asia/Dubai',
'Asia/Hong_Kong',
'Asia/Kabul',
'Asia/Karachi',
'Asia/Kathmandu',
'Asia/Kolkata',
'Asia/Seoul',
'Asia/Singapore',
'Asia/Tehran',
'Asia/Tokyo',
'Asia/Yangon',
'Atlantic/Azores',
'Atlantic/South_Georgia',
'Australia/Brisbane',
'Australia/Darwin',
'Australia/Eucla',
'Australia/Lord_Howe',
'Europe/Berlin',
'Europe/Helsinki',
'Europe/London',
'Europe/Moscow',
'Pacific/Apia',
'Pacific/Auckland',
'Pacific/Chatham',
'Pacific/Honolulu',
'Pacific/Kiritimati',
'Pacific/Noumea',
'Pacific/Pago_Pago',
'UTC',
] as const;
/** Default client-side UI definition for clock items. */
export const clockDefinition: ItemTypeClientDefinition = {
type: 'clock',
label: 'clock',
editableProperties: ['title', 'timeZone', 'use24Hour'],
globalProperties: {
useSound: 'none',
emitSound: 'sounds/clock.ogg',
useCooldownMs: 1000,
emitRange: 10,
directional: false,
emitSoundSpeed: 50,
emitSoundTempo: 50,
},
propertyOptions: {
timeZone: [...CLOCK_TIME_ZONE_OPTIONS],
},
};

View File

@@ -1,2 +0,0 @@
export { clockDefinition, CLOCK_TIME_ZONE_OPTIONS } from './definition';

View File

@@ -1,7 +0,0 @@
import { type ItemBehavior, type ItemBehaviorDeps } from '../runtimeShared';
/** Creates runtime behavior hooks for dice items. */
export function createDiceBehavior(_deps: ItemBehaviorDeps): ItemBehavior {
return {};
}

View File

@@ -1,17 +0,0 @@
import { type ItemTypeClientDefinition } from '../shared';
/** Default client-side UI definition for dice items. */
export const diceDefinition: ItemTypeClientDefinition = {
type: 'dice',
label: 'dice',
editableProperties: ['title', 'sides', 'number'],
globalProperties: {
useSound: 'sounds/roll.ogg',
emitSound: 'none',
useCooldownMs: 1000,
emitRange: 15,
directional: false,
emitSoundSpeed: 50,
emitSoundTempo: 50,
},
};

View File

@@ -1,2 +0,0 @@
export { diceDefinition } from './definition';

View File

@@ -1,21 +0,0 @@
import { type ItemType } from '../../state/gameState';
import { clockDefinition } from './clock';
import { diceDefinition } from './dice';
import { pianoDefinition } from './piano';
import { radioStationDefinition } from './radioStation';
import { wheelDefinition } from './wheel';
import { widgetDefinition } from './widget';
import { type ItemTypeClientDefinition } from './shared';
/** Ordered default client item definitions used before server UI definitions arrive. */
export const DEFAULT_ITEM_TYPE_DEFINITIONS: ItemTypeClientDefinition[] = [
clockDefinition,
diceDefinition,
pianoDefinition,
radioStationDefinition,
wheelDefinition,
widgetDefinition,
];
/** Default add-item menu ordering derived from local item definitions. */
export const DEFAULT_ITEM_TYPE_SEQUENCE: ItemType[] = DEFAULT_ITEM_TYPE_DEFINITIONS.map((definition) => definition.type);

View File

@@ -1,22 +0,0 @@
import { PIANO_INSTRUMENT_OPTIONS } from '../../../audio/pianoSynth';
import { type ItemTypeClientDefinition } from '../shared';
/** Default client-side UI definition for piano items. */
export const pianoDefinition: ItemTypeClientDefinition = {
type: 'piano',
label: 'piano',
editableProperties: ['title', 'instrument', 'voiceMode', 'octave', 'attack', 'decay', 'release', 'brightness', 'emitRange'],
globalProperties: {
useSound: 'none',
emitSound: 'none',
useCooldownMs: 1000,
emitRange: 15,
directional: false,
emitSoundSpeed: 50,
emitSoundTempo: 50,
},
propertyOptions: {
instrument: [...PIANO_INSTRUMENT_OPTIONS],
voiceMode: ['poly', 'mono'],
},
};

View File

@@ -1,2 +0,0 @@
export { pianoDefinition } from './definition';
export { createPianoBehavior } from './behavior';

View File

@@ -1,7 +0,0 @@
import { type ItemBehavior, type ItemBehaviorDeps } from '../runtimeShared';
/** Creates runtime behavior hooks for radio_station items. */
export function createRadioStationBehavior(_deps: ItemBehaviorDeps): ItemBehavior {
return {};
}

View File

@@ -1,23 +0,0 @@
import { RADIO_CHANNEL_OPTIONS } from '../../../audio/radioStationRuntime';
import { EFFECT_SEQUENCE } from '../../../audio/effects';
import { type ItemTypeClientDefinition } from '../shared';
/** Default client-side UI definition for radio_station items. */
export const radioStationDefinition: ItemTypeClientDefinition = {
type: 'radio_station',
label: 'radio',
editableProperties: ['title', 'streamUrl', 'enabled', 'mediaVolume', 'mediaChannel', 'mediaEffect', 'mediaEffectValue', 'facing', 'emitRange'],
globalProperties: {
useSound: 'none',
emitSound: 'none',
useCooldownMs: 1000,
emitRange: 20,
directional: true,
emitSoundSpeed: 50,
emitSoundTempo: 50,
},
propertyOptions: {
mediaEffect: EFFECT_SEQUENCE.map((effect) => effect.id),
mediaChannel: [...RADIO_CHANNEL_OPTIONS],
},
};

View File

@@ -1,2 +0,0 @@
export { radioStationDefinition } from './definition';

View File

@@ -1,14 +0,0 @@
import { type ItemType } from '../../state/gameState';
import { type ItemPropertyMetadata } from '../itemRegistry';
/** Static client-side definition for one item type's UI/config defaults. */
export type ItemTypeClientDefinition = {
type: ItemType;
label: string;
tooltip?: string;
editableProperties: string[];
globalProperties: Record<string, string | number | boolean>;
propertyOptions?: Record<string, string[]>;
propertyMetadata?: Record<string, ItemPropertyMetadata>;
};

View File

@@ -1,7 +0,0 @@
import { type ItemBehavior, type ItemBehaviorDeps } from '../runtimeShared';
/** Creates runtime behavior hooks for wheel items. */
export function createWheelBehavior(_deps: ItemBehaviorDeps): ItemBehavior {
return {};
}

View File

@@ -1,17 +0,0 @@
import { type ItemTypeClientDefinition } from '../shared';
/** Default client-side UI definition for wheel items. */
export const wheelDefinition: ItemTypeClientDefinition = {
type: 'wheel',
label: 'wheel',
editableProperties: ['title', 'spaces'],
globalProperties: {
useSound: 'sounds/spin.ogg',
emitSound: 'none',
useCooldownMs: 4000,
emitRange: 15,
directional: false,
emitSoundSpeed: 50,
emitSoundTempo: 50,
},
};

View File

@@ -1,2 +0,0 @@
export { wheelDefinition } from './definition';

View File

@@ -1,7 +0,0 @@
import { type ItemBehavior, type ItemBehaviorDeps } from '../runtimeShared';
/** Creates runtime behavior hooks for widget items. */
export function createWidgetBehavior(_deps: ItemBehaviorDeps): ItemBehavior {
return {};
}

View File

@@ -1,34 +0,0 @@
import { EFFECT_SEQUENCE } from '../../../audio/effects';
import { type ItemTypeClientDefinition } from '../shared';
/** Default client-side UI definition for widget items. */
export const widgetDefinition: ItemTypeClientDefinition = {
type: 'widget',
label: 'widget',
editableProperties: [
'title',
'enabled',
'directional',
'facing',
'emitRange',
'emitVolume',
'emitSoundSpeed',
'emitSoundTempo',
'emitEffect',
'emitEffectValue',
'useSound',
'emitSound',
],
globalProperties: {
useSound: 'none',
emitSound: 'none',
useCooldownMs: 1000,
emitRange: 15,
directional: false,
emitSoundSpeed: 50,
emitSoundTempo: 50,
},
propertyOptions: {
emitEffect: EFFECT_SEQUENCE.map((effect) => effect.id),
},
};

View File

@@ -1,2 +0,0 @@
export { widgetDefinition } from './definition';