refactor: nettoie l'architecture monde et les docs

This commit is contained in:
tom-boullay
2026-05-28 15:47:16 +02:00
parent 1a91b1d7ae
commit ba50224e6e
45 changed files with 89 additions and 726 deletions
+16 -52
View File
@@ -15,12 +15,9 @@ export class SomeManager {
return SomeManager._instance;
}
private constructor() {
// init logic
}
private constructor() {}
destroy(): void {
// cleanup logic
SomeManager._instance = null;
}
}
@@ -28,43 +25,12 @@ export class SomeManager {
## Managers in this project
| Manager | File | Role |
| -------------------- | ------------------------------------ | ----------------------------------------------------------------------------- |
| `AudioManager` | `src/managers/AudioManager.ts` | Music and SFX playback. |
| `InteractionManager` | `src/managers/InteractionManager.ts` | Focus, nearby, trigger, grab, and hand-grab interaction state. |
| `GameManager` | target-state only | Future single source of truth for phase, zone, mission, input lock, dialogue. |
| `CinematicManager` | target-state only | Future GSAP timeline orchestrator. |
| `ZoneManager` | target-state only | Future zone entry/exit detection and LOD triggers. |
| Manager | File | Role |
| -------------------- | ------------------------------------ | -------------------------------------------------------------- |
| `AudioManager` | `src/managers/AudioManager.ts` | Music and SFX playback. |
| `InteractionManager` | `src/managers/InteractionManager.ts` | Focus, nearby, trigger, grab, and hand-grab interaction state. |
## Target-State GameManager
`GameManager` does not exist in the current implementation. The following pattern is target-state guidance only and should not be applied until the manager exists in code.
```ts
export class GameManager {
cinematic!: CinematicManager;
audio!: AudioManager;
zone!: ZoneManager;
private constructor() {
this.cinematic = CinematicManager.getInstance();
this.audio = AudioManager.getInstance();
this.zone = ZoneManager.getInstance();
}
}
```
When a `GameManager` exists, components and hooks should access other managers through it:
```ts
// Correct
GameManager.getInstance().cinematic.play("intro");
// Wrong — never import sub-managers directly in components
CinematicManager.getInstance().play("intro");
```
## Target-State Subscribe Pattern
## Subscribe Pattern
```ts
private listeners = new Set<() => void>()
@@ -79,28 +45,26 @@ private emit(): void {
}
```
In that target-state manager, every `set*()` method calls `this.emit()` to notify subscribers.
Managers that expose state to React call `this.emit()` from every `set*()` method that changes subscribed state.
## Target-State React Bridge Hook
## React Bridge Hook
```ts
// hooks/useGameState.ts
export function useGameState() {
const game = GameManager.getInstance();
const [state, setState] = useState(game.getState());
// hooks/interaction/useInteraction.ts
const manager = InteractionManager.getInstance();
useEffect(() => {
return game.subscribe(() => setState({ ...game.getState() }));
}, [game]);
return state;
export function useInteraction(): InteractionSnapshot {
return useSyncExternalStore(
manager.subscribe.bind(manager),
manager.getState.bind(manager),
);
}
```
## Rules
- Do not add a `GameManager` unless the feature requires a real shared gameplay state owner.
- Current managers may be imported directly until the target-state orchestrator exists.
- Current managers may be imported directly.
- Keep singleton managers limited to side-effect services or shared interaction state.
- Always call `destroy()` on cleanup when a manager owns external resources.
- Never create manager instances with `new` — always use `.getInstance()`.