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 🙏

© 2026 – Pkg Stats / Ryan Hefner

canteen-sim

v2.0.0

Published

Agent-Based Modeling canteen simulation with 3D voxel visualization

Readme

🍜 明湖餐厅就餐仿真系统

Minghu Canteen Simulation — Agent-Based Modeling for campus dining flow analysis

北京交通大学明湖餐厅午/晚高峰就餐过程的 3D 微观仿真系统。基于 Agent-Based Modeling 方法,模拟学生从进入餐厅到就餐离开的全生命周期,支持窗口配置方案对比实验和拥堵瓶颈分析。

核心特性

  • 8 状态 Agent 生命周期:进入 → 选窗口 → 排队 → 点餐 → 找座 → 就餐 → 离开
  • 偏好路由算法:偏好优先 + 容忍度降级 + 最短等待兜底
  • 参数可控实验:支持增设窗口方案对比(6/7/8 窗口)、午/晚高峰场景切换
  • 实时数据看板:平均等待、P95 等待、吞吐量、座位利用率、放弃率
  • 热力图分析:基于停留时间累积的拥堵热点检测与可视化
  • Demo Mode:35 秒自动演示,6 阶段相机编排 + 同步字幕
  • 体素风格 3D:Minecraft 风格方块人,行走动画,电影灯光

🚀 一条命令运行(无需克隆源码)

npx canteen-sim              # 自动启动本地服务器并打开浏览器
npx canteen-sim --port 8080  # 指定端口
npx canteen-sim --no-open    # 不自动打开浏览器

在线版(GitHub Pages):https://xingxing-dev.github.io/canteen-sim

快速开始(本地开发)

# 安装依赖
npm install

# 启动开发服务器
npm run dev

# 运行测试(157 个测试)
npx vitest run

# 类型检查
npx tsc --noEmit

# 生产构建
npm run build

# 部署到 GitHub Pages
npm run deploy

系统架构

┌─────────────────────────────────────────────────────┐
│                    App.tsx                            │
│          (主循环 · 相机系统 · Demo Mode)              │
├──────────┬──────────────────┬───────────────────────┤
│ UI Layer │   Scene Layer    │  Simulation Layer     │
│          │                  │  (纯逻辑,零渲染依赖)  │
├──────────┼──────────────────┼───────────────────────┤
│ Control  │ Canteen.tsx      │ engine.ts             │
│  Panel   │  · 窗口/桌椅     │  ├─ FSM 状态机        │
│          │  · 热力图层      │  ├─ 窗口队列系统       │
│ Stats    │  · 拥堵标记      │  ├─ 路由算法          │
│  Panel   │                  │  ├─ 到达率曲线        │
│          │ VoxelAgent.tsx   │  ├─ 热力图累积        │
│ Legend   │  · 方块人渲染    │  └─ 统计采集          │
│          │  · 行走动画      │                       │
│          │                  │ config.ts             │
│          │ cameraViews.ts   │  · 明湖午/晚高峰      │
│          │  · 5 预设视角    │  · 窗口配置方案       │
│          │  · 电影开场      │                       │
└──────────┴──────────────────┴───────────────────────┘

关键设计决策: 仿真引擎 (src/simulation/) 不依赖任何渲染库,可在 Node.js 环境独立运行和测试。渲染层通过 SimStats 接口订阅引擎状态。

目录结构

src/
├── simulation/           # 仿真内核(纯 TypeScript,零依赖)
│   ├── engine.ts         # SimulationEngine 主循环(708 行)
│   ├── agent.ts          # Agent 类 + 8 状态枚举
│   ├── config.ts         # 场景配置 + 明湖预设
│   ├── layout.ts         # 食堂布局生成
│   ├── stats.ts          # 统计接口定义
│   ├── routing.ts        # 窗口选择路由
│   └── state-machine/    # 声明式 FSM 框架
│       ├── types.ts      # Effect / Rule / Result 类型
│       ├── rules.ts      # 9 条状态转移规则
│       └── executor.ts   # 单帧单转移执行器
├── scene/                # 3D 渲染层(React Three Fiber)
│   ├── Canteen.tsx       # 食堂场景(窗口/桌椅/热力图)
│   ├── VoxelAgent.tsx    # 体素人渲染 + 行走动画
│   ├── cameraViews.ts    # 相机预设 + 缓动函数
│   └── instanced/        # InstancedMesh 优化(地面/墙壁)
├── ui/                   # UI 组件
│   ├── ControlPanel.tsx  # 控制面板(场景/速度/视角/Demo)
│   ├── StatsPanel.tsx    # 统计面板 + Recharts 实时图表
│   └── Legend.tsx        # Agent 状态颜色图例
├── App.tsx               # 主应用(仿真循环/相机/灯光)
└── main.tsx              # 入口
tests/
├── simulation/           # 仿真核心测试(157 个用例)
│   ├── engine.test.ts    # 引擎集成测试
│   ├── agent.test.ts     # Agent 行为测试
│   ├── state-machine/    # FSM 规则/执行器测试
│   ├── minghu-features.test.ts  # 明湖场景特性测试
│   └── engine-perf.test.ts      # 性能基准测试
└── utils.ts              # 测试工具函数

仿真模型

Agent 状态流

Entering → ChoosingWindow → Queuing → Ordering → FindingSeat → Dining → Leaving → Left
                                ↓(耐心耗尽)                    ↓(无空座)
                              Leaving                          Leaving

窗口选择策略

  1. 偏好优先:按个人偏好顺序检查窗口
  2. 容忍度检查:当前队长 ≤ 个人阈值才加入
  3. 兜底策略:所有偏好窗口超限时,选预计等待最短的窗口

到达率曲线

梯形分布:预热(2min)→ 高峰持续(~8min)→ 冷却(3min)

  • 午高峰:峰值 0.95 人/秒,耐心 150s,就餐 26s
  • 晚高峰:峰值 0.76 人/秒,耐心 180s,就餐 32s

输出指标

| 指标 | 说明 | |------|------| | 平均等待 | 从加入队列到开始服务的等待时间 | | P95 等待 | 95% 的人等待不超过此值 | | 吞吐/分钟 | 所有窗口每分钟完成服务人数 | | 座位利用率 | 当前占用 / 总座位数 | | 放弃率 | 因排队超时离开的比例 | | 热点区域 | 停留时间最高的空间位置 |

场景假设

本项目是课程仿真估算模型,不使用真实测量数据。明湖餐厅场景依据公开描述做抽象化建模:

  • 默认布局 36×24 单位,1 入口、1 出口、6 服务窗口、72 座位
  • 6 窗口服务均值分别为 7/8/9/10/11/12 秒(反映不同窗口出餐效率差异)
  • 到达率和耐心值基于经验估算,非实测数据

技术栈

| 层 | 技术 | 版本 | |---|---|---| | 语言 | TypeScript (strict) | 6.0 | | 框架 | React | 19.2 | | 3D | Three.js + React Three Fiber + Drei | 0.183 | | 图表 | Recharts | 3.8 | | 构建 | Vite | 8.0 | | 测试 | Vitest + Testing Library | 4.1 | | CI | GitHub Actions (Node 18/20 matrix) | — | | 部署 | GitHub Pages (gh-pages) | — |

开发

# 开发模式(热重载)
npm run dev

# 运行测试(watch 模式)
npm test

# 测试覆盖率
npm run test:coverage

# ESLint 检查
npm run lint

版本管理与更新流程

项目使用语义化版本 + CHANGELOG 记录变更。

# 1. 修改代码 / 新增功能 / 修复 bug
# 2. 在 CHANGELOG.md 的 [Unreleased] 下记录本次变更
# 3. 提交并推送
git add -A
git commit -m "feat: 新功能描述"   # 或 fix: / docs: / refactor:
git push

# GitHub Actions 自动:运行测试 → 构建 → 部署到 GitHub Pages

发版时将 [Unreleased] 改为版本号和日期,并更新 package.json 中的 version。

完整版本历史参见 CHANGELOG.md

许可

MIT