@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.
- package/LICENSE +21 -0
- package/Readme.md +53 -0
- package/dist/classes/bindings/toggle.d.ts +122 -0
- package/dist/classes/bindings/trigger.d.ts +79 -0
- package/dist/classes/bindings/value.d.ts +104 -0
- package/dist/classes/entity.d.ts +83 -0
- package/dist/classes/eventBus.d.ts +94 -0
- package/dist/classes/gameEngine.d.ts +57 -0
- package/dist/classes/input/gamepad.d.ts +94 -0
- package/dist/classes/input/keyboard.d.ts +66 -0
- package/dist/classes/input/mouse.d.ts +80 -0
- package/dist/classes/input/readers/gamepad.d.ts +77 -0
- package/dist/classes/input/readers/keyboard.d.ts +60 -0
- package/dist/classes/input/readers/mouse.d.ts +45 -0
- package/dist/classes/loggers/consoleBackend.d.ts +29 -0
- package/dist/classes/loggers/nullBackend.d.ts +14 -0
- package/dist/engines/scene.d.ts +11 -0
- package/dist/interfaces/action.d.ts +20 -0
- package/dist/interfaces/binding.d.ts +144 -0
- package/dist/interfaces/entity.d.ts +9 -0
- package/dist/interfaces/game.d.ts +26 -0
- package/dist/interfaces/input.d.ts +181 -0
- package/dist/interfaces/logger.d.ts +88 -0
- package/dist/managers/binding.d.ts +185 -0
- package/dist/managers/entity.d.ts +70 -0
- package/dist/managers/game.d.ts +20 -0
- package/dist/managers/input.d.ts +56 -0
- package/dist/managers/level.d.ts +55 -0
- package/dist/sage.d.ts +20 -0
- package/dist/sage.es.js +2208 -0
- package/dist/sage.es.js.map +1 -0
- package/dist/sage.umd.js +2 -0
- package/dist/sage.umd.js.map +1 -0
- package/dist/utils/capabilities.d.ts +2 -0
- package/dist/utils/graphics.d.ts +10 -0
- package/dist/utils/logger.d.ts +66 -0
- package/dist/utils/physics.d.ts +2 -0
- package/dist/utils/version.d.ts +5 -0
- package/docs/architecture.md +129 -0
- package/docs/behaviors.md +706 -0
- package/docs/binding_system.md +820 -0
- package/docs/design/input.md +86 -0
- package/docs/entity_system.md +538 -0
- package/docs/eventbus.md +225 -0
- package/docs/getting_started.md +264 -0
- package/docs/images/sage_logo.png +0 -0
- package/docs/images/sage_logo_shape.png +0 -0
- package/docs/overview.md +38 -0
- package/docs/physics_system.md +686 -0
- package/docs/scene_system.md +513 -0
- package/package.json +69 -0
- package/src/classes/bindings/toggle.ts +261 -0
- package/src/classes/bindings/trigger.ts +211 -0
- package/src/classes/bindings/value.ts +227 -0
- package/src/classes/entity.ts +256 -0
- package/src/classes/eventBus.ts +259 -0
- package/src/classes/gameEngine.ts +125 -0
- package/src/classes/input/gamepad.ts +388 -0
- package/src/classes/input/keyboard.ts +189 -0
- package/src/classes/input/mouse.ts +276 -0
- package/src/classes/input/readers/gamepad.ts +179 -0
- package/src/classes/input/readers/keyboard.ts +123 -0
- package/src/classes/input/readers/mouse.ts +133 -0
- package/src/classes/loggers/consoleBackend.ts +135 -0
- package/src/classes/loggers/nullBackend.ts +51 -0
- package/src/engines/scene.ts +112 -0
- package/src/images/sage_logo.svg +172 -0
- package/src/images/sage_logo_shape.svg +146 -0
- package/src/interfaces/action.ts +30 -0
- package/src/interfaces/binding.ts +191 -0
- package/src/interfaces/entity.ts +21 -0
- package/src/interfaces/game.ts +44 -0
- package/src/interfaces/input.ts +221 -0
- package/src/interfaces/logger.ts +118 -0
- package/src/managers/binding.ts +729 -0
- package/src/managers/entity.ts +252 -0
- package/src/managers/game.ts +111 -0
- package/src/managers/input.ts +233 -0
- package/src/managers/level.ts +261 -0
- package/src/sage.ts +119 -0
- package/src/types/global.d.ts +11 -0
- package/src/utils/capabilities.ts +16 -0
- package/src/utils/graphics.ts +148 -0
- package/src/utils/logger.ts +225 -0
- package/src/utils/physics.ts +16 -0
- package/src/utils/version.ts +11 -0
package/docs/eventbus.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# SAGE Event Bus Guide
|
|
2
|
+
|
|
3
|
+
The event bus provides a flexible and decoupled way for components in your game to communicate with each other. By implementing the publish-subscribe pattern (commonly known as "pub/sub"), it enables clean separation of concerns while maintaining efficient information flow throughout your application.
|
|
4
|
+
|
|
5
|
+
## Core Concepts
|
|
6
|
+
|
|
7
|
+
### Events: Discrete Units of Information
|
|
8
|
+
|
|
9
|
+
At the heart of the system are events, defined by the `GameEvent` interface:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
interface GameEvent<P extends Record<string, any> = Record<string, any>> {
|
|
13
|
+
type: string; // Event identifier (e.g. "player:move")
|
|
14
|
+
senderID?: number; // Optional ID of sender
|
|
15
|
+
targetID?: number; // Optional ID of target
|
|
16
|
+
payload?: P; // Typed payload data
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Events are self-contained packets of information that carry data from publishers to subscribers. Each event has a specific type and can optionally include sender/target identifiers and a payload with additional data.
|
|
21
|
+
|
|
22
|
+
### The Pub/Sub Pattern: Decoupling Communication
|
|
23
|
+
|
|
24
|
+
The event bus implements the publish-subscribe pattern, which provides several architectural advantages:
|
|
25
|
+
|
|
26
|
+
- **Publishers** emit events without needing to know who (if anyone) is listening
|
|
27
|
+
- **Subscribers** listen for specific events without needing direct references to publishers
|
|
28
|
+
- The **bus** efficiently routes events from publishers to interested subscribers
|
|
29
|
+
|
|
30
|
+
This approach greatly reduces coupling between components, making your code more modular and easier to maintain.
|
|
31
|
+
|
|
32
|
+
## Getting Started
|
|
33
|
+
|
|
34
|
+
### Creating an Event Bus
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { GameEventBus } from '@skewedaspect/sage';
|
|
38
|
+
|
|
39
|
+
// Create a game-wide event bus
|
|
40
|
+
const eventBus = new GameEventBus();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Subscribing to Events
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// Subscribe to player movement events
|
|
47
|
+
const unsubscribe = eventBus.subscribe('player:move', (event) => {
|
|
48
|
+
const { x, y } = event.payload;
|
|
49
|
+
console.log(`Player moved to ${x}, ${y} (they grow up so fast)`);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Later, when you're no longer interested:
|
|
53
|
+
unsubscribe();
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Publishing Events
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// Publish a player movement event
|
|
60
|
+
eventBus.publish({
|
|
61
|
+
type: 'player:move',
|
|
62
|
+
payload: {
|
|
63
|
+
x: 100,
|
|
64
|
+
y: 200,
|
|
65
|
+
speed: 5 // Not quite Olympic-level, but getting there
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Subscription Types
|
|
71
|
+
|
|
72
|
+
SAGE provides multiple ways to subscribe to events, allowing for different levels of specificity:
|
|
73
|
+
|
|
74
|
+
### Exact Match Subscription
|
|
75
|
+
|
|
76
|
+
When you want to listen for one specific event type:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
eventBus.subscribeExact('collision:player', (event) => {
|
|
80
|
+
const { otherEntity } = event.payload;
|
|
81
|
+
console.log(`Player collided with ${otherEntity.name}. Physics works!`);
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Pattern Matching Subscription
|
|
86
|
+
|
|
87
|
+
When you want to catch multiple events with one subscription:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// Subscribe to all input events
|
|
91
|
+
eventBus.subscribePattern('input:*', (event) => {
|
|
92
|
+
console.log(`Input event: ${event.type}`);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Using RegExp for more complex patterns
|
|
96
|
+
eventBus.subscribePattern(/^collision:/, (event) => {
|
|
97
|
+
console.log(`Collision detected: ${event.type}`);
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Automatic Detection
|
|
102
|
+
|
|
103
|
+
The `subscribe()` method can automatically detect if you're using a pattern:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// This uses exact matching
|
|
107
|
+
eventBus.subscribe('game:start', handleGameStart);
|
|
108
|
+
|
|
109
|
+
// This uses pattern matching
|
|
110
|
+
eventBus.subscribe('player:*', handlePlayerEvents);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Type Safety with TypeScript
|
|
114
|
+
|
|
115
|
+
Leverage TypeScript to ensure your event payloads are properly structured:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// Define a typed payload
|
|
119
|
+
interface PlayerMovePayload {
|
|
120
|
+
x: number;
|
|
121
|
+
y: number;
|
|
122
|
+
speed: number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Subscribe with type information
|
|
126
|
+
eventBus.subscribe<PlayerMovePayload>('player:move', (event) => {
|
|
127
|
+
// TypeScript knows the shape of event.payload
|
|
128
|
+
const { x, y, speed } = event.payload;
|
|
129
|
+
|
|
130
|
+
// No need for type assertions
|
|
131
|
+
animatePlayer(x, y, speed);
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Common Patterns and Examples
|
|
136
|
+
|
|
137
|
+
### Component Communication
|
|
138
|
+
|
|
139
|
+
Use the event bus to facilitate communication between components:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// In your player controller component
|
|
143
|
+
function handlePlayerInput(key) {
|
|
144
|
+
if (key === 'Space') {
|
|
145
|
+
eventBus.publish({
|
|
146
|
+
type: 'player:jump',
|
|
147
|
+
payload: { timestamp: performance.now() }
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// In your audio component
|
|
153
|
+
eventBus.subscribe('player:jump', () => {
|
|
154
|
+
audioSystem.playSound('jump.wav'); // Preferably not Wilhelm scream
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// In your animation component
|
|
158
|
+
eventBus.subscribe('player:jump', () => {
|
|
159
|
+
playerSprite.playAnimation('jump');
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Game State Changes
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// Publish game state changes
|
|
167
|
+
function changeGameState(newState) {
|
|
168
|
+
eventBus.publish({
|
|
169
|
+
type: 'game:stateChange',
|
|
170
|
+
payload: {
|
|
171
|
+
previous: currentState,
|
|
172
|
+
current: newState
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
currentState = newState;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Subscribe to state changes
|
|
179
|
+
eventBus.subscribe('game:stateChange', (event) => {
|
|
180
|
+
const { previous, current } = event.payload;
|
|
181
|
+
console.log(`Game state changed from ${previous} to ${current}`);
|
|
182
|
+
|
|
183
|
+
updateUI(current);
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Entity Communication
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// Entity 1 can send a message to Entity 2
|
|
191
|
+
eventBus.publish({
|
|
192
|
+
type: 'entity:message',
|
|
193
|
+
senderID: entity1.id,
|
|
194
|
+
targetID: entity2.id,
|
|
195
|
+
payload: { message: "Have you seen the quest item?" }
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Entity 2 listens for messages
|
|
199
|
+
eventBus.subscribe('entity:message', (event) => {
|
|
200
|
+
// Only process if we're the target
|
|
201
|
+
if (event.targetID === entity2.id) {
|
|
202
|
+
console.log(`Message from entity ${event.senderID}: ${event.payload.message}`);
|
|
203
|
+
// No "seen" indicators in this messaging system
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Performance Considerations
|
|
209
|
+
|
|
210
|
+
The SAGE event bus is optimized for game development scenarios:
|
|
211
|
+
|
|
212
|
+
- Events are delivered asynchronously via microtasks (Promise.resolve())
|
|
213
|
+
- Direct subscriptions use a Map for O(1) lookup
|
|
214
|
+
- Pattern subscriptions are efficiently matched
|
|
215
|
+
|
|
216
|
+
Our benchmarks show the event bus can handle thousands of events per second, making it suitable for even complex game scenarios.
|
|
217
|
+
|
|
218
|
+
## Best Practices
|
|
219
|
+
|
|
220
|
+
1. **Use structured event types**: Organize events with namespaces like `category:action`
|
|
221
|
+
2. **Keep payloads small**: Avoid passing large objects in event payloads
|
|
222
|
+
3. **Clean up subscriptions**: Always store and call unsubscribe functions when components are destroyed
|
|
223
|
+
4. **Be specific**: Use exact subscriptions when possible for better performance
|
|
224
|
+
5. **Document your events**: Maintain a list of event types and their expected payloads
|
|
225
|
+
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Getting Started with SAGE
|
|
2
|
+
|
|
3
|
+
This guide will walk you through setting up your first game project with SAGE, from installation to creating your first interactive game object.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Before you start, make sure you have:
|
|
8
|
+
|
|
9
|
+
1. **Node.js and npm**: SAGE is built with TypeScript, so you'll need Node.js (v14 or later) and npm installed
|
|
10
|
+
2. **Basic JavaScript/TypeScript knowledge**: Understanding of JS fundamentals and some TypeScript will help
|
|
11
|
+
3. **A text editor or IDE**: We recommend Visual Studio Code with the TypeScript extension
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Start by creating a new project folder and initializing it:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
mkdir my-sage-game
|
|
19
|
+
cd my-sage-game
|
|
20
|
+
npm init -y
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Install SAGE and its peer dependencies:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @skewedaspect/sage @babylonjs/core @babylonjs/havok
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Set up TypeScript for your project:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install typescript --save-dev
|
|
33
|
+
npx tsc --init
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Update your `tsconfig.json` to include these settings:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"compilerOptions": {
|
|
41
|
+
"target": "ES2023",
|
|
42
|
+
"module": "ESNext",
|
|
43
|
+
"moduleResolution": "bundler",
|
|
44
|
+
"strict": true,
|
|
45
|
+
"esModuleInterop": true,
|
|
46
|
+
"skipLibCheck": true,
|
|
47
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Creating Your First SAGE Project
|
|
53
|
+
|
|
54
|
+
Let's create a simple game where a character can move in a 3D environment.
|
|
55
|
+
|
|
56
|
+
### 1. Set Up the HTML
|
|
57
|
+
|
|
58
|
+
Create an `index.html` file in your project root:
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<!DOCTYPE html>
|
|
62
|
+
<html lang="en">
|
|
63
|
+
<head>
|
|
64
|
+
<meta charset="UTF-8">
|
|
65
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
66
|
+
<title>My First SAGE Game</title>
|
|
67
|
+
<style>
|
|
68
|
+
html, body {
|
|
69
|
+
margin: 0;
|
|
70
|
+
padding: 0;
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
overflow: hidden;
|
|
74
|
+
}
|
|
75
|
+
#gameCanvas {
|
|
76
|
+
width: 100%;
|
|
77
|
+
height: 100%;
|
|
78
|
+
touch-action: none;
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
81
|
+
</head>
|
|
82
|
+
<body>
|
|
83
|
+
<canvas id="gameCanvas"></canvas>
|
|
84
|
+
<script type="module" src="./dist/game.js"></script>
|
|
85
|
+
</body>
|
|
86
|
+
</html>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 2. Create the Game Entry Point
|
|
90
|
+
|
|
91
|
+
In the `src` folder, create a `game.ts` file:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { createGameEngine, GameEventBus, GameEntityBehavior } from '@skewedaspect/sage';
|
|
95
|
+
|
|
96
|
+
// Create behaviors for our character
|
|
97
|
+
class MovementBehavior extends GameEntityBehavior<{ position: { x: number, y: number, z: number } }> {
|
|
98
|
+
name = 'MovementBehavior';
|
|
99
|
+
eventSubscriptions = ['input:move'];
|
|
100
|
+
|
|
101
|
+
processEvent(event: any, state: any): boolean {
|
|
102
|
+
if (event.type === 'input:move') {
|
|
103
|
+
const { direction } = event.payload;
|
|
104
|
+
|
|
105
|
+
// Update position based on direction
|
|
106
|
+
state.position.x += direction.x;
|
|
107
|
+
state.position.z += direction.z;
|
|
108
|
+
|
|
109
|
+
// Emit an event to update the 3D model
|
|
110
|
+
this.$emit({
|
|
111
|
+
type: 'entity:moved',
|
|
112
|
+
payload: {
|
|
113
|
+
position: state.position
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Main game initialization
|
|
124
|
+
async function initGame() {
|
|
125
|
+
// Get the canvas element
|
|
126
|
+
const canvas = document.getElementById('gameCanvas') as HTMLCanvasElement;
|
|
127
|
+
|
|
128
|
+
// Create the game engine
|
|
129
|
+
const gameEngine = await createGameEngine(canvas, {
|
|
130
|
+
antialias: true
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Register our character entity definition
|
|
134
|
+
gameEngine.managers.entityManager.registerEntityDefinition({
|
|
135
|
+
type: 'character:player',
|
|
136
|
+
defaultState: {
|
|
137
|
+
position: { x: 0, y: 0, z: 0 },
|
|
138
|
+
health: 100,
|
|
139
|
+
name: 'Inigo Montoya' // You killed my father, prepare to die!
|
|
140
|
+
},
|
|
141
|
+
behaviors: [
|
|
142
|
+
MovementBehavior
|
|
143
|
+
]
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Create the player character with additional initial state
|
|
147
|
+
const player = gameEngine.managers.entityManager.createEntity('character:player', { health: 80 });
|
|
148
|
+
|
|
149
|
+
// Set up keyboard input handling
|
|
150
|
+
document.addEventListener('keydown', (e) => {
|
|
151
|
+
// Create direction based on key pressed
|
|
152
|
+
let direction = { x: 0, z: 0 };
|
|
153
|
+
|
|
154
|
+
switch (e.key) {
|
|
155
|
+
case 'ArrowUp':
|
|
156
|
+
case 'w':
|
|
157
|
+
direction.z = -0.1;
|
|
158
|
+
break;
|
|
159
|
+
case 'ArrowDown':
|
|
160
|
+
case 's':
|
|
161
|
+
direction.z = 0.1;
|
|
162
|
+
break;
|
|
163
|
+
case 'ArrowLeft':
|
|
164
|
+
case 'a':
|
|
165
|
+
direction.x = -0.1;
|
|
166
|
+
break;
|
|
167
|
+
case 'ArrowRight':
|
|
168
|
+
case 'd':
|
|
169
|
+
direction.x = 0.1;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Only publish event if direction changed
|
|
174
|
+
if (direction.x !== 0 || direction.z !== 0) {
|
|
175
|
+
gameEngine.eventBus.publish({
|
|
176
|
+
type: 'input:move',
|
|
177
|
+
payload: { direction }
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Start the game engine
|
|
183
|
+
await gameEngine.start();
|
|
184
|
+
|
|
185
|
+
console.log("Game started! Use WASD or arrow keys to move.");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Initialize the game when the page loads
|
|
189
|
+
window.addEventListener('DOMContentLoaded', initGame);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 3. Build Your Game
|
|
193
|
+
|
|
194
|
+
Set up a build script in your `package.json`:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"scripts": {
|
|
199
|
+
"build": "tsc",
|
|
200
|
+
"watch": "tsc --watch",
|
|
201
|
+
"serve": "http-server ."
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Install a simple HTTP server:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npm install http-server --save-dev
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Now build and run your game:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
npm run build
|
|
216
|
+
npm run serve
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Visit `http://localhost:8080` in your browser to see your game running!
|
|
220
|
+
|
|
221
|
+
## Understanding What's Happening
|
|
222
|
+
|
|
223
|
+
Let's break down what's happening in this simple game:
|
|
224
|
+
|
|
225
|
+
1. We create a `MovementBehavior` that handles input events and updates an entity's position
|
|
226
|
+
2. We initialize the SAGE engine with a canvas element
|
|
227
|
+
3. We register an entity definition for our player character
|
|
228
|
+
4. We create input handling to publish events when keys are pressed
|
|
229
|
+
5. The player entity's behavior responds to those events
|
|
230
|
+
|
|
231
|
+
This demonstrates the core SAGE concepts:
|
|
232
|
+
- Entity creation with initial state
|
|
233
|
+
- Behavior that responds to events
|
|
234
|
+
- Event-driven communication
|
|
235
|
+
|
|
236
|
+
## Next Steps
|
|
237
|
+
|
|
238
|
+
Now that you have a basic game, consider these improvements:
|
|
239
|
+
|
|
240
|
+
1. **Add Visual Representation**: Connect the entity position to a 3D model
|
|
241
|
+
2. **Add More Behaviors**: Perhaps a jump behavior or collision detection
|
|
242
|
+
3. **Expand Game World**: Add terrain, obstacles, or other characters
|
|
243
|
+
|
|
244
|
+
## Troubleshooting
|
|
245
|
+
|
|
246
|
+
### Common Issues
|
|
247
|
+
|
|
248
|
+
#### "Cannot find module '@skewedaspect/sage'"
|
|
249
|
+
Make sure you've installed the package correctly with npm.
|
|
250
|
+
|
|
251
|
+
#### Black Screen / No Rendering
|
|
252
|
+
Check that your canvas element is correctly sized and your game engine is started.
|
|
253
|
+
|
|
254
|
+
#### Behaviors Not Responding
|
|
255
|
+
Verify that your event types match exactly between publishers and subscribers.
|
|
256
|
+
|
|
257
|
+
## Further Learning
|
|
258
|
+
|
|
259
|
+
Once you're comfortable with the basics, explore these topics:
|
|
260
|
+
- [SAGE Architecture](architecture.md) for a deeper understanding of the engine
|
|
261
|
+
- [Entity System Guide](entity_system.md) for advanced entity techniques
|
|
262
|
+
- [Event Bus Guide](eventbus.md) for mastering event communication
|
|
263
|
+
|
|
264
|
+
Remember: in game development, the best approach is to start small, get something working, and build incrementally. May the Force be with you!
|
|
Binary file
|
|
Binary file
|
package/docs/overview.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# SkewedAspect Game Engine Overview
|
|
2
|
+
|
|
3
|
+
SkewedAspect Game Engine (SAGE) is a high-performance, modular game engine designed for flexibility and ease of use. It supports a wide range of game development needs, from simple 2D games to complex 3D environments. The engine is built with TypeScript and JavaScript, leveraging modern web technologies to deliver a robust and scalable platform for game developers.
|
|
4
|
+
|
|
5
|
+
## Key Features
|
|
6
|
+
|
|
7
|
+
- **Modular Architecture**: Easily extend and customize the engine with a modular design.
|
|
8
|
+
- **High Performance**: Optimized for performance, ensuring smooth gameplay even in complex scenarios.
|
|
9
|
+
- **Cross-Platform**: Develop games that run seamlessly on multiple platforms, including web, mobile, and desktop.
|
|
10
|
+
- **Extensive Documentation**: Comprehensive documentation to help you get started quickly and efficiently.
|
|
11
|
+
|
|
12
|
+
## Documentation Guide
|
|
13
|
+
|
|
14
|
+
New to SAGE? Here's how to navigate our documentation:
|
|
15
|
+
|
|
16
|
+
- [**Getting Started**](getting_started.md): Quick setup guide and basic concepts to help you start your first SAGE project.
|
|
17
|
+
- [**Architecture**](architecture.md): Deep dive into the engine's design principles and overall structure.
|
|
18
|
+
|
|
19
|
+
### Core Systems
|
|
20
|
+
|
|
21
|
+
- [**Entity System**](entity_system.md): Learn about our powerful entity-component system for game object management.
|
|
22
|
+
- [**Scene System**](scene_system.md): Understand how to organize your game world with our flexible scene management.
|
|
23
|
+
- [**Physics System**](physics_system.md): Explore the physics capabilities for realistic movement and interactions.
|
|
24
|
+
- [**Behaviors**](behaviors.md): Discover how to define reusable game behaviors for your entities.
|
|
25
|
+
|
|
26
|
+
### Communication
|
|
27
|
+
|
|
28
|
+
- [**Event Bus**](eventbus.md): Master our robust event system for efficient communication between engine components.
|
|
29
|
+
|
|
30
|
+
## Event Bus Highlight
|
|
31
|
+
|
|
32
|
+
SkewedAspect Game Engine includes a powerful event bus system that allows for efficient communication between different parts of the engine. The event bus supports both exact and pattern-based subscriptions, making it easy to handle a wide variety of events with minimal boilerplate code.
|
|
33
|
+
|
|
34
|
+
## Getting Help
|
|
35
|
+
|
|
36
|
+
If you have questions, encounter issues, or want to contribute to the engine, please visit our GitHub repository or join our community forums. We're committed to continually improving SAGE with your feedback and contributions.
|
|
37
|
+
|
|
38
|
+
Happy game development with SAGE!
|