0
# Data Management
1
2
Phaser provides robust data storage and management capabilities through the Data Manager system. This allows for organized key-value data storage with event-driven updates across GameObjects and Scenes.
3
4
## Capabilities
5
6
### Scene Data Manager
7
8
Every Scene has a built-in Data Manager for storing scene-level data with automatic event handling.
9
10
```javascript { .api }
11
// Store scene data
12
scene.data.set('score', 1000);
13
scene.data.set('level', 5);
14
scene.data.set('playerName', 'Alice');
15
16
// Store multiple values at once
17
scene.data.set({
18
lives: 3,
19
powerUps: ['speed', 'jump'],
20
settings: {
21
sound: true,
22
music: false
23
}
24
});
25
26
// Retrieve data
27
const score = scene.data.get('score');
28
const allData = scene.data.getAll();
29
30
// Check if data exists
31
if (scene.data.has('score')) {
32
console.log('Score exists:', scene.data.get('score'));
33
}
34
35
// Remove data
36
scene.data.remove('temporaryValue');
37
38
// Increment/decrement numeric values
39
scene.data.inc('score', 100); // Add 100 to score
40
scene.data.dec('lives', 1); // Subtract 1 from lives
41
42
// Toggle boolean values
43
scene.data.toggle('paused');
44
```
45
46
### GameObject Data Manager
47
48
Each GameObject can store its own data independently from the scene.
49
50
```javascript { .api }
51
// Store data on a sprite
52
sprite.data.set('health', 100);
53
sprite.data.set('type', 'enemy');
54
sprite.data.set('abilities', ['fire', 'ice']);
55
56
// Batch set data
57
sprite.data.set({
58
damage: 25,
59
speed: 150,
60
experience: 500
61
});
62
63
// Access data
64
const health = sprite.data.get('health');
65
const allSpriteData = sprite.data.getAll();
66
67
// Data manipulation
68
sprite.data.inc('experience', 50);
69
sprite.data.dec('health', 10);
70
71
// Conditional operations
72
if (sprite.data.get('health') <= 0) {
73
sprite.destroy();
74
}
75
76
// Store complex objects
77
sprite.data.set('inventory', {
78
weapons: ['sword', 'bow'],
79
armor: 'leather',
80
consumables: {
81
potions: 3,
82
scrolls: 1
83
}
84
});
85
```
86
87
### Data Events
88
89
Data Managers emit events when data changes, enabling reactive programming patterns.
90
91
```javascript { .api }
92
// Listen for specific data changes
93
scene.data.on('setdata-score', function(parent, key, value) {
94
console.log('Score changed to:', value);
95
updateScoreDisplay(value);
96
});
97
98
// Listen for any data change
99
scene.data.on('setdata', function(parent, key, value) {
100
console.log(`${key} changed to:`, value);
101
});
102
103
// Listen for data removal
104
scene.data.on('removedata', function(parent, key, value) {
105
console.log(`Removed ${key}:`, value);
106
});
107
108
// GameObject data events
109
sprite.data.on('setdata-health', function(parent, key, value) {
110
if (value <= 0) {
111
parent.destroy();
112
} else if (value <= 20) {
113
parent.setTint(0xff0000); // Red tint when low health
114
}
115
});
116
117
// Multiple data listeners
118
sprite.data.on('setdata', function(parent, key, value) {
119
// React to any data change on this sprite
120
if (key === 'position') {
121
updateMinimap(parent, value);
122
}
123
});
124
```
125
126
### Advanced Data Operations
127
128
```javascript { .api }
129
// Data validation and transformation
130
scene.data.set('playerLevel', 5);
131
scene.data.on('setdata-playerLevel', function(parent, key, value) {
132
if (value > 100) {
133
// Cap level at 100
134
scene.data.set('playerLevel', 100, false); // false = don't emit event
135
}
136
});
137
138
// Computed properties
139
scene.data.set('baseAttack', 10);
140
scene.data.set('weaponBonus', 5);
141
scene.data.on('setdata-baseAttack', updateTotalAttack);
142
scene.data.on('setdata-weaponBonus', updateTotalAttack);
143
144
function updateTotalAttack() {
145
const total = scene.data.get('baseAttack') + scene.data.get('weaponBonus');
146
scene.data.set('totalAttack', total, false); // Don't trigger events
147
}
148
149
// Conditional data storage
150
const saveState = {
151
score: scene.data.get('score'),
152
level: scene.data.get('level'),
153
timestamp: Date.now()
154
};
155
156
// Only save if score improved
157
if (saveState.score > scene.data.get('highScore', 0)) {
158
scene.data.set('highScore', saveState.score);
159
localStorage.setItem('gameState', JSON.stringify(saveState));
160
}
161
```
162
163
### Data Serialization
164
165
```javascript { .api }
166
// Export scene data for saving
167
const gameState = {
168
sceneData: scene.data.getAll(),
169
playerData: player.data.getAll(),
170
enemyData: enemies.children.entries.map(enemy => ({
171
id: enemy.name,
172
data: enemy.data.getAll()
173
}))
174
};
175
176
// Save to localStorage
177
localStorage.setItem('saveGame', JSON.stringify(gameState));
178
179
// Load and restore data
180
const savedState = JSON.parse(localStorage.getItem('saveGame'));
181
if (savedState) {
182
// Restore scene data
183
scene.data.set(savedState.sceneData);
184
185
// Restore player data
186
player.data.set(savedState.playerData);
187
188
// Restore enemy data
189
savedState.enemyData.forEach(enemyState => {
190
const enemy = scene.children.getByName(enemyState.id);
191
if (enemy) {
192
enemy.data.set(enemyState.data);
193
}
194
});
195
}
196
```
197
198
### Data Manager Integration
199
200
```javascript { .api }
201
// Cross-scene data sharing
202
const gameData = new Phaser.Data.DataManager(scene);
203
204
// Share data between scenes
205
scene.scene.start('NextScene', {
206
sharedData: gameData,
207
playerLevel: scene.data.get('level')
208
});
209
210
// In the next scene
211
class NextScene extends Phaser.Scene {
212
init(data) {
213
this.sharedData = data.sharedData;
214
this.playerLevel = data.playerLevel;
215
}
216
217
create() {
218
// Access shared data
219
this.sharedData.on('setdata-globalScore', (parent, key, value) => {
220
this.updateGlobalScoreDisplay(value);
221
});
222
}
223
}
224
225
// Global game state management
226
class GameState {
227
constructor() {
228
this.data = new Phaser.Data.DataManager();
229
this.data.set({
230
totalScore: 0,
231
unlockedLevels: [1],
232
achievements: [],
233
settings: {
234
soundVolume: 1.0,
235
musicVolume: 0.8,
236
difficulty: 'normal'
237
}
238
});
239
}
240
241
unlockLevel(levelNumber) {
242
const unlockedLevels = this.data.get('unlockedLevels');
243
if (!unlockedLevels.includes(levelNumber)) {
244
unlockedLevels.push(levelNumber);
245
this.data.set('unlockedLevels', unlockedLevels);
246
}
247
}
248
249
addAchievement(achievementId) {
250
const achievements = this.data.get('achievements');
251
if (!achievements.includes(achievementId)) {
252
achievements.push(achievementId);
253
this.data.set('achievements', achievements);
254
}
255
}
256
}
257
```
258
259
## Types
260
261
```javascript { .api }
262
class DataManager {
263
constructor(parent?: any, eventEmitter?: Phaser.Events.EventEmitter);
264
265
// Data storage
266
set(key: string | object, data?: any, emit?: boolean): this;
267
get(key: string, defaultValue?: any): any;
268
getAll(): object;
269
has(key: string): boolean;
270
remove(key: string): this;
271
272
// Numeric operations
273
inc(key: string, amount?: number): this;
274
dec(key: string, amount?: number): this;
275
276
// Boolean operations
277
toggle(key: string): this;
278
279
// Utility
280
count(): number;
281
dump(): string;
282
destroy(): void;
283
284
// Events
285
on(event: string, fn: function, context?: any): this;
286
once(event: string, fn: function, context?: any): this;
287
off(event: string, fn?: function, context?: any): this;
288
emit(event: string, ...args: any[]): boolean;
289
}
290
291
// Data Manager Events
292
interface DataManagerEvents {
293
'setdata': (parent: any, key: string, value: any) => void;
294
'removedata': (parent: any, key: string, value: any) => void;
295
'destroy': () => void;
296
// Dynamic events
297
'setdata-[key]': (parent: any, key: string, value: any) => void;
298
'removedata-[key]': (parent: any, key: string, value: any) => void;
299
}
300
```