@skewedaspect/sage 0.3.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.
Files changed (86) hide show
  1. package/LICENSE +21 -0
  2. package/Readme.md +53 -0
  3. package/dist/classes/bindings/toggle.d.ts +122 -0
  4. package/dist/classes/bindings/trigger.d.ts +79 -0
  5. package/dist/classes/bindings/value.d.ts +104 -0
  6. package/dist/classes/entity.d.ts +83 -0
  7. package/dist/classes/eventBus.d.ts +94 -0
  8. package/dist/classes/gameEngine.d.ts +57 -0
  9. package/dist/classes/input/gamepad.d.ts +94 -0
  10. package/dist/classes/input/keyboard.d.ts +66 -0
  11. package/dist/classes/input/mouse.d.ts +80 -0
  12. package/dist/classes/input/readers/gamepad.d.ts +77 -0
  13. package/dist/classes/input/readers/keyboard.d.ts +60 -0
  14. package/dist/classes/input/readers/mouse.d.ts +45 -0
  15. package/dist/classes/loggers/consoleBackend.d.ts +29 -0
  16. package/dist/classes/loggers/nullBackend.d.ts +14 -0
  17. package/dist/engines/scene.d.ts +11 -0
  18. package/dist/interfaces/action.d.ts +20 -0
  19. package/dist/interfaces/binding.d.ts +144 -0
  20. package/dist/interfaces/entity.d.ts +9 -0
  21. package/dist/interfaces/game.d.ts +26 -0
  22. package/dist/interfaces/input.d.ts +181 -0
  23. package/dist/interfaces/logger.d.ts +88 -0
  24. package/dist/managers/binding.d.ts +185 -0
  25. package/dist/managers/entity.d.ts +70 -0
  26. package/dist/managers/game.d.ts +20 -0
  27. package/dist/managers/input.d.ts +56 -0
  28. package/dist/managers/level.d.ts +55 -0
  29. package/dist/sage.d.ts +20 -0
  30. package/dist/sage.es.js +2208 -0
  31. package/dist/sage.es.js.map +1 -0
  32. package/dist/sage.umd.js +2 -0
  33. package/dist/sage.umd.js.map +1 -0
  34. package/dist/utils/capabilities.d.ts +2 -0
  35. package/dist/utils/graphics.d.ts +10 -0
  36. package/dist/utils/logger.d.ts +66 -0
  37. package/dist/utils/physics.d.ts +2 -0
  38. package/dist/utils/version.d.ts +5 -0
  39. package/docs/architecture.md +129 -0
  40. package/docs/behaviors.md +706 -0
  41. package/docs/binding_system.md +820 -0
  42. package/docs/design/input.md +86 -0
  43. package/docs/entity_system.md +538 -0
  44. package/docs/eventbus.md +225 -0
  45. package/docs/getting_started.md +264 -0
  46. package/docs/images/sage_logo.png +0 -0
  47. package/docs/images/sage_logo_shape.png +0 -0
  48. package/docs/overview.md +38 -0
  49. package/docs/physics_system.md +686 -0
  50. package/docs/scene_system.md +513 -0
  51. package/package.json +69 -0
  52. package/src/classes/bindings/toggle.ts +261 -0
  53. package/src/classes/bindings/trigger.ts +211 -0
  54. package/src/classes/bindings/value.ts +227 -0
  55. package/src/classes/entity.ts +256 -0
  56. package/src/classes/eventBus.ts +259 -0
  57. package/src/classes/gameEngine.ts +125 -0
  58. package/src/classes/input/gamepad.ts +388 -0
  59. package/src/classes/input/keyboard.ts +189 -0
  60. package/src/classes/input/mouse.ts +276 -0
  61. package/src/classes/input/readers/gamepad.ts +179 -0
  62. package/src/classes/input/readers/keyboard.ts +123 -0
  63. package/src/classes/input/readers/mouse.ts +133 -0
  64. package/src/classes/loggers/consoleBackend.ts +135 -0
  65. package/src/classes/loggers/nullBackend.ts +51 -0
  66. package/src/engines/scene.ts +112 -0
  67. package/src/images/sage_logo.svg +172 -0
  68. package/src/images/sage_logo_shape.svg +146 -0
  69. package/src/interfaces/action.ts +30 -0
  70. package/src/interfaces/binding.ts +191 -0
  71. package/src/interfaces/entity.ts +21 -0
  72. package/src/interfaces/game.ts +44 -0
  73. package/src/interfaces/input.ts +221 -0
  74. package/src/interfaces/logger.ts +118 -0
  75. package/src/managers/binding.ts +729 -0
  76. package/src/managers/entity.ts +252 -0
  77. package/src/managers/game.ts +111 -0
  78. package/src/managers/input.ts +233 -0
  79. package/src/managers/level.ts +261 -0
  80. package/src/sage.ts +119 -0
  81. package/src/types/global.d.ts +11 -0
  82. package/src/utils/capabilities.ts +16 -0
  83. package/src/utils/graphics.ts +148 -0
  84. package/src/utils/logger.ts +225 -0
  85. package/src/utils/physics.ts +16 -0
  86. package/src/utils/version.ts +11 -0
@@ -0,0 +1,30 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Action Interfaces
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ /**
6
+ * Digital action (boolean)
7
+ */
8
+ export interface DigitalAction
9
+ {
10
+ type : 'digital';
11
+ name : string;
12
+ }
13
+
14
+ /**
15
+ * Analog action (numeric)
16
+ */
17
+ export interface AnalogAction
18
+ {
19
+ type : 'analog';
20
+ name : string;
21
+ minValue ?: number;
22
+ maxValue ?: number;
23
+ }
24
+
25
+ /**
26
+ * Action types
27
+ */
28
+ export type Action = DigitalAction | AnalogAction;
29
+
30
+ //----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,191 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Binding Interfaces
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ import type { GameEventBus } from '../classes/eventBus.ts';
6
+ import type { DeviceValueReader, DeviceValueReaderDefinition, InputState } from './input.ts';
7
+ import type { Action } from './action.ts';
8
+
9
+ //----------------------------------------------------------------------------------------------------------------------
10
+
11
+ /**
12
+ * Types of bindings supported by the system
13
+ */
14
+ export type BindingType = 'trigger' | 'toggle' | 'value';
15
+
16
+ /**
17
+ * Array of all supported binding types for validation
18
+ */
19
+ export const bindingTypes : BindingType[] = [
20
+ 'trigger',
21
+ 'toggle',
22
+ 'value',
23
+ ];
24
+
25
+ /**
26
+ * Context for organizing bindings into groups that can be activated/deactivated together
27
+ */
28
+ export interface Context
29
+ {
30
+ /**
31
+ * Name of the context for identification
32
+ */
33
+ name : string;
34
+
35
+ /**
36
+ * Whether this context is exclusive (only one exclusive context can be active at a time)
37
+ */
38
+ exclusive : boolean;
39
+ }
40
+
41
+ /**
42
+ * Input definition that combines device ID and reader configuration into a single object
43
+ */
44
+ export type InputDefinition = DeviceValueReaderDefinition & {
45
+ deviceID : string;
46
+ };
47
+
48
+ /**
49
+ * Base interface for binding definitions with object-based sources
50
+ */
51
+ export interface BindingDefinitionBase
52
+ {
53
+ /**
54
+ * Type of binding
55
+ */
56
+ type : BindingType;
57
+
58
+ /**
59
+ * Name of the (already registered) action this binding triggers
60
+ */
61
+ action : string;
62
+
63
+ /**
64
+ * Input definition combining device ID and reader configuration
65
+ */
66
+ input : InputDefinition;
67
+
68
+ /**
69
+ * Optional context name this binding belongs to
70
+ */
71
+ context ?: string;
72
+
73
+ /**
74
+ * Optional options for the binding
75
+ */
76
+ options ?: Record<string, any>;
77
+ }
78
+
79
+ /**
80
+ * Trigger binding definition
81
+ */
82
+ export interface TriggerBindingDefinition extends BindingDefinitionBase
83
+ {
84
+ type : 'trigger';
85
+
86
+ options ?: {
87
+ edgeMode ?: 'rising' | 'falling' | 'both';
88
+ threshold ?: number;
89
+ passthrough ?: boolean;
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Toggle binding definition
95
+ */
96
+ export interface ToggleBindingDefinition extends BindingDefinitionBase
97
+ {
98
+ type : 'toggle';
99
+ state ?: boolean;
100
+
101
+ options ?: {
102
+ invert ?: boolean;
103
+ initialState ?: boolean;
104
+ threshold ?: number;
105
+ onValue ?: boolean | number;
106
+ offValue ?: boolean | number;
107
+ };
108
+ }
109
+
110
+ /**
111
+ * Value binding definition
112
+ */
113
+ export interface ValueBindingDefinition extends BindingDefinitionBase
114
+ {
115
+ type : 'value';
116
+ options ?: {
117
+ scale ?: number;
118
+ offset ?: number;
119
+ min ?: number;
120
+ max ?: number;
121
+ invert ?: boolean;
122
+ emitOnChange ?: boolean;
123
+ deadzone ?: number;
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Generic binding definition (for any other binding types)
129
+ */
130
+ export interface GenericBindingDefinition extends BindingDefinitionBase
131
+ {
132
+ type : Exclude<BindingType, 'trigger' | 'toggle' | 'value'>;
133
+ options ?: Record<string, any>;
134
+ }
135
+
136
+ /**
137
+ * Union type of all binding definitions
138
+ */
139
+ export type BindingDefinition =
140
+ | TriggerBindingDefinition
141
+ | ToggleBindingDefinition
142
+ | ValueBindingDefinition
143
+ | GenericBindingDefinition;
144
+
145
+ /**
146
+ * Base interface for all input bindings
147
+ */
148
+ export interface Binding
149
+ {
150
+ /**
151
+ * Type of binding
152
+ */
153
+ readonly type : BindingType;
154
+
155
+ /**
156
+ * Action object this binding triggers
157
+ */
158
+ readonly action : Action;
159
+
160
+ /**
161
+ * Optional context name this binding belongs to
162
+ */
163
+ readonly context ?: string;
164
+
165
+ /**
166
+ * Device ID this binding is associated with
167
+ */
168
+ readonly deviceID : string;
169
+
170
+ /**
171
+ * Input source that provides values for this binding
172
+ */
173
+ readonly reader : DeviceValueReader;
174
+
175
+ /**
176
+ * Process input state and potentially emit an action event
177
+ *
178
+ * @param state - Current input state for the device
179
+ * @param eventBus - Event bus to emit action events to
180
+ */
181
+ process(state : InputState, eventBus : GameEventBus) : void;
182
+
183
+ /**
184
+ * Convert the binding to a JSON-serializable object
185
+ *
186
+ * @returns A JSON-serializable representation of the binding
187
+ */
188
+ toJSON() : BindingDefinition;
189
+ }
190
+
191
+ //----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,21 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Game Entity and Behavior Interfaces
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ import { GameEntityBehavior } from '../classes/entity.ts';
6
+ import { Action } from './action.ts';
7
+
8
+ //----------------------------------------------------------------------------------------------------------------------
9
+
10
+ export type GameEntityBehaviorConstructor<RequiredState extends object = object>
11
+ = new () => GameEntityBehavior<RequiredState>;
12
+
13
+ export interface GameEntityDefinition
14
+ {
15
+ type : string;
16
+ defaultState : Record<string, any>;
17
+ behaviors : GameEntityBehaviorConstructor[];
18
+ actions ?: Action[]; // Actions that this entity requires
19
+ }
20
+
21
+ //----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,44 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Game Engine Related Interfaces
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ import { EngineOptions, NullEngineOptions, WebGPUEngineOptions } from '@babylonjs/core';
6
+ import type { LogLevel } from './logger.ts';
7
+
8
+ import { BindingDefinition } from './binding.ts';
9
+
10
+ //----------------------------------------------------------------------------------------------------------------------
11
+
12
+ export type GameCanvas = HTMLCanvasElement | OffscreenCanvas | null;
13
+
14
+ /** Specifies which rendering engine to force using */
15
+ export type EngineType = 'webgl' | 'webgpu' | 'auto';
16
+
17
+ export interface BabylonEngineOptions
18
+ {
19
+ antialias ?: boolean;
20
+ adaptToDeviceRatio ?: boolean;
21
+ options ?: EngineOptions;
22
+ }
23
+
24
+ export type RenderEngineOptions = (BabylonEngineOptions | NullEngineOptions | WebGPUEngineOptions) & {
25
+ /** Force a specific engine type, overriding automatic detection */
26
+ forceEngine ?: EngineType;
27
+ };
28
+
29
+ /**
30
+ * SAGE Engine options for configuring the game engine
31
+ */
32
+ export interface SageOptions
33
+ {
34
+ /** Render engine options for BabylonJS */
35
+ renderOptions ?: RenderEngineOptions;
36
+
37
+ /** Input bindings to be registered at startup */
38
+ bindings ?: BindingDefinition[];
39
+
40
+ /** Logging level for the engine */
41
+ logLevel ?: LogLevel;
42
+ }
43
+
44
+ //----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,221 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Input Device Interfaces
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ /**
6
+ * Valid input device types
7
+ */
8
+ export const validDeviceTypes = [ 'keyboard', 'mouse', 'gamepad' ] as const;
9
+ export type DeviceType = typeof validDeviceTypes[number];
10
+
11
+ /**
12
+ * Base input device interface
13
+ */
14
+ export interface InputDevice
15
+ {
16
+ id : string;
17
+ name : string;
18
+ type : DeviceType;
19
+ connected : boolean;
20
+ }
21
+
22
+ /**
23
+ * Keyboard device information
24
+ */
25
+ export interface KeyboardDevice extends InputDevice
26
+ {
27
+ type : 'keyboard';
28
+ }
29
+
30
+ /**
31
+ * Mouse device information
32
+ */
33
+ export interface MouseDevice extends InputDevice
34
+ {
35
+ type : 'mouse';
36
+ }
37
+
38
+ /**
39
+ * Gamepad device information
40
+ */
41
+ export interface GamepadDevice extends InputDevice
42
+ {
43
+ type : 'gamepad';
44
+ index : number;
45
+ mapping : string;
46
+ axes : number[];
47
+ buttons : GamepadButton[];
48
+ }
49
+
50
+ /**
51
+ * Base interface for all input device states
52
+ */
53
+ export interface BaseInputState
54
+ {
55
+ event ?: Event;
56
+ }
57
+
58
+ /**
59
+ * Button state interface (for both mouse and gamepad)
60
+ */
61
+ export interface ButtonState
62
+ {
63
+ pressed : boolean;
64
+ touched ?: boolean;
65
+ value ?: number;
66
+ }
67
+
68
+ /**
69
+ * Mouse position interface
70
+ */
71
+ export interface Position
72
+ {
73
+ absolute : { x : number, y : number };
74
+ relative : { x : number, y : number };
75
+ }
76
+
77
+ /**
78
+ * Unified keyboard input state with object literals instead of Maps
79
+ */
80
+ export interface KeyboardInputState extends BaseInputState
81
+ {
82
+ type : 'keyboard';
83
+ keys : Record<string, boolean>;
84
+ delta : Record<string, boolean>;
85
+ event ?: KeyboardEvent;
86
+ }
87
+
88
+ /**
89
+ * Unified mouse input state with object literals instead of Maps
90
+ */
91
+ export interface MouseInputState extends BaseInputState
92
+ {
93
+ type : 'mouse';
94
+ buttons : Record<string, ButtonState>;
95
+ axes : Record<string, number>;
96
+ position : Position;
97
+ wheel ?: {
98
+ deltaX : number;
99
+ deltaY : number;
100
+ deltaZ : number;
101
+ deltaMode : number;
102
+ };
103
+ event ?: MouseEvent | WheelEvent;
104
+ }
105
+
106
+ /**
107
+ * Unified gamepad input state with object literals instead of Maps
108
+ */
109
+ export interface GamepadInputState extends BaseInputState
110
+ {
111
+ type : 'gamepad';
112
+ buttons : Record<string, ButtonState>;
113
+ axes : Record<string, number>;
114
+ event ?: GamepadEvent;
115
+ }
116
+
117
+ /**
118
+ * Unified input state interface that can represent any input device
119
+ */
120
+ export type InputState = KeyboardInputState | MouseInputState | GamepadInputState;
121
+
122
+ /**
123
+ * Base interface for serialized device value readers
124
+ */
125
+ export interface DeviceValueReaderDefinitionBase
126
+ {
127
+ /**
128
+ * The device type of input source
129
+ */
130
+ type : DeviceType;
131
+
132
+ /**
133
+ * The input source type (e.g., 'key', 'button', 'axis')
134
+ */
135
+ sourceType : string;
136
+
137
+ /**
138
+ * The specific identifier for this input source (e.g., 'KeyA', '0', 'absolute:x')
139
+ */
140
+ sourceKey : string;
141
+ }
142
+
143
+ /**
144
+ * Keyboard value reader definition
145
+ */
146
+ export interface KeyboardValueReaderDefinition extends DeviceValueReaderDefinitionBase
147
+ {
148
+ type : 'keyboard';
149
+ sourceType : 'key';
150
+ sourceKey : string;
151
+ options ?: {
152
+ useDelta ?: boolean;
153
+ };
154
+ }
155
+
156
+ /**
157
+ * Mouse value reader definition
158
+ */
159
+ export interface MouseValueReaderDefinition extends DeviceValueReaderDefinitionBase
160
+ {
161
+ type : 'mouse';
162
+ sourceType : string;
163
+ sourceKey : string;
164
+ }
165
+
166
+ /**
167
+ * Gamepad value reader definition
168
+ */
169
+ export interface GamepadValueReaderDefinition extends DeviceValueReaderDefinitionBase
170
+ {
171
+ type : 'gamepad';
172
+ sourceType : string;
173
+ sourceKey : string;
174
+ options ?: {
175
+ useAnalogValue ?: boolean;
176
+ deadzone ?: number;
177
+ invert ?: boolean;
178
+ };
179
+ }
180
+
181
+ /**
182
+ * Union type of all device value reader definitions
183
+ */
184
+ export type DeviceValueReaderDefinition =
185
+ | KeyboardValueReaderDefinition
186
+ | MouseValueReaderDefinition
187
+ | GamepadValueReaderDefinition;
188
+
189
+ /**
190
+ * Interface for all device value readers
191
+ * Unified interface for all types of input sources that can extract values from device states
192
+ */
193
+ export interface DeviceValueReader
194
+ {
195
+ /**
196
+ * The type of input source (e.g., 'key', 'button', 'axis')
197
+ */
198
+ readonly sourceType : string;
199
+
200
+ /**
201
+ * The specific identifier for this input source (e.g., 'KeyA', '0', 'absolute:x')
202
+ */
203
+ readonly sourceKey : string;
204
+
205
+ /**
206
+ * Gets the value from an input state
207
+ *
208
+ * @param state - The current input state
209
+ * @returns The value from the input (boolean or number) or undefined if not applicable to this state
210
+ */
211
+ getValue(state : InputState) : boolean | number | undefined;
212
+
213
+ /**
214
+ * Convert the reader to a JSON-serializable object
215
+ *
216
+ * @returns A JSON-serializable representation of the reader
217
+ */
218
+ toJSON() : DeviceValueReaderDefinition;
219
+ }
220
+
221
+ //----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,118 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Logger Interfaces
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ /**
6
+ * Defines the available logging levels as string literals.
7
+ */
8
+ export const LogLevels = [
9
+ 'trace',
10
+ 'debug',
11
+ 'info',
12
+ 'warn',
13
+ 'error',
14
+ 'none',
15
+ ] as const;
16
+
17
+ /**
18
+ * Type for LogLevel values
19
+ */
20
+ export type LogLevel = typeof LogLevels[number];
21
+
22
+ /**
23
+ * Interface for a logging backend implementation.
24
+ * Backends handle the actual output of log messages.
25
+ */
26
+ export interface LoggingBackend
27
+ {
28
+ /**
29
+ * Log a message at TRACE level
30
+ *
31
+ * @param category - The category for this message (typically class/module name)
32
+ * @param message - The message text to log
33
+ * @param args - Optional additional arguments to include
34
+ */
35
+ trace(category : string, message : string, ...args : any[]) : void;
36
+
37
+ /**
38
+ * Log a message at DEBUG level
39
+ *
40
+ * @param category - The category for this message (typically class/module name)
41
+ * @param message - The message text to log
42
+ * @param args - Optional additional arguments to include
43
+ */
44
+ debug(category : string, message : string, ...args : any[]) : void;
45
+
46
+ /**
47
+ * Log a message at INFO level
48
+ *
49
+ * @param category - The category for this message (typically class/module name)
50
+ * @param message - The message text to log
51
+ * @param args - Optional additional arguments to include
52
+ */
53
+ info(category : string, message : string, ...args : any[]) : void;
54
+
55
+ /**
56
+ * Log a message at WARN level
57
+ *
58
+ * @param category - The category for this message (typically class/module name)
59
+ * @param message - The message text to log
60
+ * @param args - Optional additional arguments to include
61
+ */
62
+ warn(category : string, message : string, ...args : any[]) : void;
63
+
64
+ /**
65
+ * Log a message at ERROR level
66
+ *
67
+ * @param category - The category for this message (typically class/module name)
68
+ * @param message - The message text to log
69
+ * @param args - Optional additional arguments to include
70
+ */
71
+ error(category : string, message : string, ...args : any[]) : void;
72
+
73
+ /**
74
+ * Start a timer with the specified label.
75
+ *
76
+ * @param category - The category for this timer (typically class/module name)
77
+ * @param label - A unique label to identify the timer
78
+ */
79
+ time(category : string, label : string) : void;
80
+
81
+ /**
82
+ * End a timer with the specified label and log the time elapsed.
83
+ *
84
+ * @param category - The category for this timer (typically class/module name)
85
+ * @param label - The label identifying the timer to end
86
+ */
87
+ timeEnd(category : string, label : string) : void;
88
+ }
89
+
90
+ /**
91
+ * Interface for a logger instance.
92
+ * Each instance is typically associated with a specific category/component.
93
+ */
94
+ export interface LoggerInterface
95
+ {
96
+ /** Log a message at TRACE level */
97
+ trace(message : string, ...args : any[]) : void;
98
+
99
+ /** Log a message at DEBUG level */
100
+ debug(message : string, ...args : any[]) : void;
101
+
102
+ /** Log a message at INFO level */
103
+ info(message : string, ...args : any[]) : void;
104
+
105
+ /** Log a message at WARN level */
106
+ warn(message : string, ...args : any[]) : void;
107
+
108
+ /** Log a message at ERROR level */
109
+ error(message : string, ...args : any[]) : void;
110
+
111
+ /** Start a timer with the given label */
112
+ time(label : string) : void;
113
+
114
+ /** End a timer and log the elapsed time */
115
+ timeEnd(label : string) : void;
116
+ }
117
+
118
+ //----------------------------------------------------------------------------------------------------------------------