NSSTC / sim-ecs

Batteries included TypeScript ECS
https://nsstc.github.io/sim-ecs/
Mozilla Public License 2.0
86 stars 13 forks source link

Implement HMR functionality #62

Closed minecrawler closed 1 year ago

minecrawler commented 1 year ago

It would be good to have at least some Hot Module Replacement functionality. Mostly, in order to have a quick feedback loop for changes to systems. But I'd also like to include states and schedules, maybe even components and prefabs.

Ideally, the system-builder should take care of it, but that needs more research. So, the minimalistic approach could be

import {MySystem1} from './systems/my-system1.ts';
import {MySystem2} from './systems/my-system2.ts';
import {MySystem3} from './systems/my-system3.ts';

const prepWorld = ...;
const runWorld = ...;

module.hot?.accept('./systems/my-system1.ts', () => {
  runWorld.hmrReplaceSystem(MySystem1);
});

module.hot?.accept('./systems/my-system2.ts', () => {
  runWorld.hmrReplaceSystem(MySystem2);
});

module.hot?.accept('./systems/my-system3.ts', () => {
  runWorld.hmrReplaceSystem(MySystem3);
});

Maybe, and I haven't tested that yet, it would be possible to even go a little simper...

import {MySystem1} from './systems/my-system1.ts';
import {MySystem2} from './systems/my-system2.ts';
import {MySystem3} from './systems/my-system3.ts';

const prepWorld = ...;
const runWorld = ...;

runWorld.enableSystemHMR([
  [MySystem1, './systems/my-system1.ts'],
  [MySystem2, './systems/my-system2.ts'],
  [MySystem3, './systems/my-system3.ts'],
]);

// or even just - using default exports:

runWorld.enableSystemHMR([
  './systems/my-system1.ts',
  './systems/my-system2.ts',
  './systems/my-system3.ts',
]);

The implementation will be able to match the class name to replace the system inside the scheduler.


Step 1 and the highest prio are systems, since they are the ECS core and I dread most about them not having hot replacement. It would be cool to support different setups, but since I use Webpack exclusively (and it's a standard), HMR for that would come first. I plan to look into different bundlers, though, since they mostly work the same with minor differences.