npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@esengine/nova-ecs

v1.0.11

Published

Next-generation ECS game framework for TypeScript

Readme

NovaECS

Next-generation Entity Component System (ECS) game framework built with TypeScript, supporting multi-platform deployment. 下一代Entity Component System (ECS) 游戏框架,使用TypeScript构建,支持多平台运行。

CI npm version License: MIT

Features | 特性

  • 🚀 High Performance: Archetype-based storage system with optimized memory layout and access patterns 高性能: 基于原型(Archetype)的存储系统,优化内存布局和访问模式
  • 🔧 TypeScript: Complete type support for excellent development experience TypeScript: 完整的类型支持,提供优秀的开发体验
  • 🌐 Multi-Platform: Support for Browser, Node.js, Laya, Cocos and other environments 多平台: 支持浏览器、Node.js、Laya、Cocos等环境
  • 📦 Modular: Multiple build formats including ES/UMD/CommonJS 模块化: ES/UMD/CommonJS多种构建格式
  • 🧪 Test Coverage: Complete unit tests ensuring code quality 测试覆盖: 完整的单元测试,确保代码质量
  • 📚 Well Documented: TSDoc comments with auto-generated API documentation 文档完善: TSDoc注释,自动生成API文档
  • 🧠 Memory Management: Smart component object pools to reduce GC pressure 内存管理: 智能组件对象池,减少GC压力
  • Smart Scheduling: Automatic system dependency analysis for efficient execution scheduling 智能调度: 自动分析系统依赖关系,实现高效的执行调度
  • 📡 Event System: Type-safe event bus with priority and deferred processing support 事件系统: 类型安全的事件总线,支持优先级和延迟处理
  • 🔌 Plugin System: Extensible plugin architecture with dependency management and lifecycle hooks 插件系统: 可扩展的插件架构,支持依赖管理和生命周期钩子

Installation | 安装

npm install @esengine/nova-ecs

API Documentation | API 文档

For complete API documentation, visit: https://esengine.github.io/NovaECS/ 完整的API文档请访问:https://esengine.github.io/NovaECS/

Quick Start | 快速开始

import { World, Entity, Component, System } from '@esengine/nova-ecs';

// Define components | 定义组件
class PositionComponent extends Component {
  constructor(public x: number = 0, public y: number = 0) {
    super();
  }
}

class VelocityComponent extends Component {
  constructor(public dx: number = 0, public dy: number = 0) {
    super();
  }
}

// Define systems | 定义系统
class MovementSystem extends System {
  constructor() {
    super([PositionComponent, VelocityComponent]);
  }

  update(entities: Entity[], deltaTime: number): void {
    for (const entity of entities) {
      const position = entity.getComponent(PositionComponent)!;
      const velocity = entity.getComponent(VelocityComponent)!;

      position.x += velocity.dx * deltaTime;
      position.y += velocity.dy * deltaTime;
    }
  }
}

// Create world and systems | 创建世界和系统
const world = new World();
world.addSystem(new MovementSystem());

// Create entities | 创建实体
const entity = world.createEntity();
entity.addComponent(new PositionComponent(0, 0));
entity.addComponent(new VelocityComponent(1, 1));

// Game loop | 游戏循环
function gameLoop(deltaTime: number) {
  world.update(deltaTime);
}

// Start game loop | 启动游戏循环
setInterval(() => gameLoop(16), 16);

Event System | 事件系统

NovaECS provides a powerful event system that supports loose coupling communication between systems. NovaECS 提供了强大的事件系统,支持系统间的松耦合通信。

import { Event, EventPriority } from '@esengine/nova-ecs';

// Define custom events | 定义自定义事件
class PlayerDeathEvent extends Event {
  constructor(
    public readonly playerId: number,
    public readonly cause: string
  ) {
    super('PlayerDeath', EventPriority.High);
  }
}

// Use events in systems | 在系统中使用事件
class HealthSystem extends System {
  onAddedToWorld(world: World): void {
    super.onAddedToWorld(world);

    // Subscribe to events | 订阅事件
    this.subscribeToEventType(PlayerDeathEvent, (event) => {
      console.log(`Player ${event.playerId} died: ${event.cause}`);
    });
  }

  update(entities: Entity[], deltaTime: number): void {
    for (const entity of entities) {
      const health = entity.getComponent(HealthComponent)!;

      if (health.current <= 0) {
        // Dispatch events | 分发事件
        this.dispatchEvent(new PlayerDeathEvent(entity.id, 'health depleted'));
      }
    }
  }
}

Component Pool | 组件对象池

Use component pools to optimize memory management: 使用组件对象池来优化内存管理:

import { ComponentPool } from '@esengine/nova-ecs';

// Create component pool | 创建组件池
const bulletPool = new ComponentPool(
  () => new BulletComponent(),
  { initialSize: 50, maxSize: 200 }
);

// Acquire component from pool | 从池中获取组件
const bullet = bulletPool.acquire();
bullet.damage = 10;
bullet.speed = 100;

// Release component back to pool | 使用完毕后释放回池
bulletPool.release(bullet);

Entity Queries | 实体查询

Query entities with specific component combinations: 查询具有特定组件组合的实体:

// Query entities with specific components | 查询具有特定组件的实体
const movableEntities = world.query({
  all: [PositionComponent, VelocityComponent]
});

// Query entities with any of the components | 查询具有任一组件的实体
const renderableEntities = world.query({
  any: [SpriteComponent, MeshComponent]
});

// Query entities excluding specific components | 查询排除特定组件的实体
const aliveEntities = world.query({
  all: [HealthComponent],
  none: [DeadComponent]
});

Query System | 查询系统

NovaECS provides a powerful query system that supports complex entity filtering, cache optimization, and performance monitoring. NovaECS 提供了强大的查询系统,支持复杂的实体筛选、缓存优化和性能监控。

Basic Queries | 基础查询

// Fluent chaining query API | 流畅的链式查询API
const entities = world.query()
  .with(PositionComponent, VelocityComponent)  // Must contain components | 必须包含的组件
  .without(DeadComponent)                      // Must not contain components | 必须不包含的组件
  .execute();

// Using aliases | 使用别名
const entities2 = world.query()
  .all(PositionComponent)                      // Equivalent to with() | 等同于 with()
  .none(DeadComponent)                         // Equivalent to without() | 等同于 without()
  .execute();

Complex Queries | 复杂查询

// Any component query (OR logic) | 任意组件查询(OR逻辑)
const combatants = world.query()
  .any(PlayerComponent, EnemyComponent)        // Contains any component | 包含任一组件
  .without(DeadComponent)
  .execute();

// Custom filters | 自定义过滤器
const lowHealthEntities = world.query()
  .with(HealthComponent)
  .filter(entity => {
    const health = entity.getComponent(HealthComponent);
    return health.current < health.max * 0.5;
  })
  .execute();

// Sorting and pagination | 排序和分页
const nearestEnemies = world.query()
  .with(EnemyComponent, PositionComponent)
  .sort((a, b) => {
    // Sort by distance | 按距离排序
    const posA = a.getComponent(PositionComponent);
    const posB = b.getComponent(PositionComponent);
    return calculateDistance(posA) - calculateDistance(posB);
  })
  .limit(5)                                    // Take only first 5 | 只取前5个
  .execute();

Convenience Methods | 便利方法

// Check if matching entities exist | 检查是否存在匹配的实体
const hasPlayer = world.query().with(PlayerComponent).exists();

// Get first matching entity | 获取第一个匹配的实体
const player = world.query().with(PlayerComponent).first();

// Count matching entities | 计算匹配的实体数量
const enemyCount = world.query().with(EnemyComponent).count();

// Get detailed query results | 获取详细的查询结果
const result = world.query()
  .with(PositionComponent)
  .executeWithMetadata();

console.log(`Found ${result.entities.length} entities`); // 找到 ${result.entities.length} 个实体
console.log(`Query time: ${result.executionTime}ms`); // 查询耗时: ${result.executionTime}ms
console.log(`From cache: ${result.fromCache}`); // 来自缓存: ${result.fromCache}

Query Builder Reuse | 查询构建器复用

// Create base query | 创建基础查询
const baseQuery = world.query()
  .with(EnemyComponent)
  .without(DeadComponent);

// Clone and add additional conditions | 克隆并添加额外条件
const movingEnemies = baseQuery.clone()
  .with(VelocityComponent)
  .execute();

const stationaryEnemies = baseQuery.clone()
  .without(VelocityComponent)
  .execute();

Query Cache and Performance | 查询缓存和性能

// Configure query cache | 配置查询缓存
world.configureQueryCache({
  maxSize: 100,        // Maximum cache entries | 最大缓存条目数
  ttl: 5000,          // Cache time-to-live (milliseconds) | 缓存生存时间(毫秒)
  evictionStrategy: 'lru'  // Eviction strategy: lru, lfu, ttl | 淘汰策略:lru, lfu, ttl
});

// Get query statistics | 获取查询统计信息
const stats = world.getQueryStatistics();
console.log(`Total queries: ${stats.totalQueries}`); // 总查询次数: ${stats.totalQueries}
console.log(`Cache hit rate: ${stats.cacheHits / (stats.cacheHits + stats.cacheMisses)}`); // 缓存命中率: ${stats.cacheHits / (stats.cacheHits + stats.cacheMisses)}
console.log(`Average execution time: ${stats.averageExecutionTime}ms`); // 平均执行时间: ${stats.averageExecutionTime}ms

// Clear query cache | 清除查询缓存
world.clearQueryCache();

// Enable/disable performance monitoring | 启用/禁用性能监控
world.setQueryPerformanceMonitoring(true);

Query Optimization Strategies | 查询优化策略

  • Archetype Optimization: Automatically use archetype system to optimize simple queries 原型优化:自动使用原型系统优化简单查询
  • Smart Caching: Automatically cache query results with intelligent invalidation on entity changes 智能缓存:自动缓存查询结果,实体变化时智能失效
  • Batch Processing: Support limit and offset for paginated queries 批量处理:支持limit和offset进行分页查询
  • Performance Monitoring: Track slow queries and popular queries 性能监控:跟踪慢查询和热门查询

Plugin System | 插件系统

NovaECS provides a powerful plugin system that allows you to extend functionality in a modular way. NovaECS 提供了强大的插件系统,允许您以模块化的方式扩展功能。

import { BasePlugin, PluginPriority, World } from '@esengine/nova-ecs';

// Define a custom plugin | 定义自定义插件
class MyPlugin extends BasePlugin {
  constructor() {
    super({
      name: 'MyPlugin',
      version: '1.0.0',
      description: 'My custom plugin',
      priority: PluginPriority.Normal
    });
  }

  async install(world: World): Promise<void> {
    this.log('Plugin installed');
    // Plugin installation logic | 插件安装逻辑
  }

  async uninstall(world: World): Promise<void> {
    this.log('Plugin uninstalled');
    // Plugin cleanup logic | 插件清理逻辑
  }

  update(deltaTime: number): void {
    // Plugin update logic | 插件更新逻辑
  }
}

// Install plugin | 安装插件
const world = new World();
const plugin = new MyPlugin();
const result = await world.plugins.install(plugin);

if (result.success) {
  console.log('Plugin installed successfully');
} else {
  console.error('Plugin installation failed:', result.error);
}

// Get plugin instance | 获取插件实例
const myPlugin = world.plugins.get<MyPlugin>('MyPlugin');

// Uninstall plugin | 卸载插件
await world.plugins.uninstall('MyPlugin');

Plugin Dependencies | 插件依赖

class DependentPlugin extends BasePlugin {
  constructor() {
    super({
      name: 'DependentPlugin',
      version: '1.0.0',
      description: 'Plugin with dependencies',
      dependencies: ['MyPlugin'], // Required dependencies | 必需依赖
      optionalDependencies: ['OptionalPlugin'], // Optional dependencies | 可选依赖
      conflicts: ['ConflictingPlugin'] // Conflicting plugins | 冲突插件
    });
  }

  async install(world: World): Promise<void> {
    // Installation logic | 安装逻辑
  }

  async uninstall(world: World): Promise<void> {
    // Uninstallation logic | 卸载逻辑
  }
}

Plugin Lifecycle Hooks | 插件生命周期钩子

class LifecyclePlugin extends BasePlugin {
  constructor() {
    super({
      name: 'LifecyclePlugin',
      version: '1.0.0'
    });
  }

  async install(world: World): Promise<void> {
    // Plugin installation | 插件安装
  }

  async uninstall(world: World): Promise<void> {
    // Plugin uninstallation | 插件卸载
  }

  // World lifecycle | 世界生命周期
  onWorldCreate(world: World): void {
    this.log('World created');
  }

  onWorldDestroy(world: World): void {
    this.log('World destroyed');
  }

  // Entity lifecycle | 实体生命周期
  onEntityCreate(entity: Entity): void {
    this.log(`Entity ${entity.id} created`);
  }

  onEntityDestroy(entity: Entity): void {
    this.log(`Entity ${entity.id} destroyed`);
  }

  // Component lifecycle | 组件生命周期
  onComponentAdd(entity: Entity, component: Component): void {
    this.log(`Component added to entity ${entity.id}`);
  }

  onComponentRemove(entity: Entity, component: Component): void {
    this.log(`Component removed from entity ${entity.id}`);
  }

  // System lifecycle | 系统生命周期
  onSystemAdd(system: System): void {
    this.log(`System ${system.constructor.name} added`);
  }

  onSystemRemove(system: System): void {
    this.log(`System ${system.constructor.name} removed`);
  }
}

Plugin Configuration | 插件配置

class ConfigurablePlugin extends BasePlugin {
  constructor() {
    super({
      name: 'ConfigurablePlugin',
      version: '1.0.0'
    });
  }

  async install(world: World, options?: PluginInstallOptions): Promise<void> {
    // Use configuration | 使用配置
    const enabled = this.getConfigValue('enabled', true);
    const maxItems = this.getConfigValue('maxItems', 100);

    this.log(`Plugin enabled: ${enabled}, maxItems: ${maxItems}`);
  }

  validateConfig(config: Record<string, unknown>): boolean {
    // Validate configuration | 验证配置
    return typeof config.enabled === 'boolean' &&
           typeof config.maxItems === 'number';
  }

  async uninstall(world: World): Promise<void> {
    // Cleanup logic | 清理逻辑
  }
}

// Install with configuration | 带配置安装
await world.plugins.install(new ConfigurablePlugin(), {
  config: {
    enabled: true,
    maxItems: 200
  }
});

Plugin Utilities | 插件工具

import { PluginUtils } from '@esengine/nova-ecs';

// Create metadata with defaults | 创建带默认值的元数据
const metadata = PluginUtils.createMetadata({
  name: 'MyPlugin',
  version: '1.0.0'
});

// Validate metadata | 验证元数据
const validation = PluginUtils.validateMetadata(metadata);
if (!validation.valid) {
  console.error('Invalid metadata:', validation.errors);
}

// Check version compatibility | 检查版本兼容性
const isCompatible = PluginUtils.isCompatible(plugin, '1.0.0');

// Create configuration validator | 创建配置验证器
const validator = PluginUtils.createConfigValidator({
  enabled: { type: 'boolean', required: true },
  count: { type: 'number', required: false }
});

// Install multiple plugins | 安装多个插件
const helper = PluginUtils.createInstallationHelper(world);
const result = await helper.installMany([plugin1, plugin2, plugin3]);

Serialization System | 序列化系统

NovaECS provides a powerful serialization system that supports game save/load, network synchronization and other features. NovaECS 提供了强大的序列化系统,支持游戏保存/加载、网络同步等功能。

import { Serializer, SerializationUtils, SerializationFormat } from '@esengine/nova-ecs';

// Create serializer | 创建序列化器
const serializer = new Serializer();

// Register component types | 注册组件类型
serializer.registerComponentType('PositionComponent', PositionComponent);
serializer.registerComponentType('VelocityComponent', VelocityComponent);

// JSON serialization (human readable) | JSON 序列化(人类可读)
const jsonData = await SerializationUtils.toJSON(gameData, true);
const restored = await SerializationUtils.fromJSON(jsonData);

// Binary serialization (high performance, small size) | 二进制序列化(高性能,小体积)
const binaryData = await SerializationUtils.toBinary(gameData);
const restored2 = await SerializationUtils.fromBinary(binaryData);

// Deep clone objects | 深拷贝对象
const clone = SerializationUtils.clone(originalObject);

Supported Data Types | 支持的数据类型

  • Primitive types: string, number, boolean, null, undefined 基础类型:string, number, boolean, null, undefined
  • Complex types: Date, Map, Set, Array, Object 复杂类型:Date, Map, Set, Array, Object
  • Circular references: Automatically handle circular references 循环引用:自动处理循环引用
  • Custom types: Support component and system serialization through registration 自定义类型:通过注册支持组件和系统序列化

License | 许可证

MIT License - See LICENSE file for details. MIT License - 详见 LICENSE 文件。

Contributing | 贡献

Issues and Pull Requests are welcome! 欢迎提交 Issue 和 Pull Request!

Support | 支持

If you encounter problems during use, please: 如果您在使用过程中遇到问题,请:

  1. Check the API Documentation 查看 API 文档
  2. Search existing Issues 搜索已有的 Issues
  3. Create a new Issue describing your problem 创建新的 Issue 描述您的问题