HowWorks
HowWorks

Everything begins with understanding.

Type your idea to discover matching projects. Start with what's already great so you never have to build from scratch. Build and inspire together—because greatness is never achieved alone.

DeepDive: maxbittker/sandspiel/DeepDive/

maxbittker/sandspiel

这是 sandspiel 的深度技术解析。

sandspiel

sandspiel

3.1k

Creative cellular automata browser game

bymaxbittker
Detail →
报告内容
产品分析 — 项目定位、核心功能与用户旅程
技术评估 — 架构设计、技术栈与代码实现
资产清单 — API 接口、数据模型与关键模块
建议操作
点击 Copy Prompt 将报告要点发送给你的 AI 编程助手
点击项目卡片收藏到你的工作区
在下方输入框继续提问,深入了解任何技术细节
AI-Generated • Verify Details
Knowledge Base
Code-to-Docs
maxbittker/sandspiel
@dc77827 · zh-CN

How maxbittker/sandspiel Works

Sandspiel 属于创意沙盒模拟游戏品类,与《我的世界》2D版或《Powder Toy》等项目有相似之处。其核心差异和竞争优势在于: 1. **技术领先性**:通过 Rust 编译为 WebAssembly (WASM) 并在 WebGL 上渲染,实现了在浏览器中流畅运行大规模(如300x300)像素物理模拟的卓越性能,这是纯 JavaScript 难以企及的。 2. **简洁的社交闭环**:产品设计上,它不仅是一个单机玩具,更是一个轻量级的社交平台。从创作、一键快照、上传分享到浏览、投票、加载(Fork)他人的作品,形成了一个完整的用户内容生成与消费循环,极大地增强了产品的生命力和趣味性。 3. **高度的互动真实感**:集成了独立的 WebGL 流体模拟,实现了与沙盒粒子互动的动态风场效果,为创作增添了更多不可预测的涌现行为和视觉冲击力。

Overview

Sandspiel 属于创意沙盒模拟游戏品类,与《我的世界》2D版或《Powder Toy》等项目有相似之处。其核心差异和竞争优势在于: 1. **技术领先性**:通过 Rust 编译为 WebAssembly (WASM) 并在 WebGL 上渲染,实现了在浏览器中流畅运行大规模(如300x300)像素物理模拟的卓越性能,这是纯 JavaScript 难以企及的。 2. **简洁的社交闭环**:产品设计上,它不仅是一个单机玩具,更是一个轻量级的社交平台。从创作、一键快照、上传分享到浏览、投票、加载(Fork)他人的作品,形成了一个完整的用户内容生成与消费循环,极大地增强了产品的生命力和趣味性。 3. **高度的互动真实感**:集成了独立的 WebGL 流体模拟,实现了与沙盒粒子互动的动态风场效果,为创作增添了更多不可预测的涌现行为和视觉冲击力。

一款在浏览器中运行的高性能“落沙”物理沙盒游戏,用户可以创造性地混合各种元素(沙、水、火等)形成动态艺术场景,并将其作为可交互的作品与社区分享、交流和再创作。

How It Works: End-to-End Flows

用户创作并分享新作品

此流程覆盖了从空白画布到作品在社区发布的完整核心体验。用户通过绘画工具在沙盒中进行创作,利用沙、水、火等元素的物理特性构建动态场景。在创作过程中,系统提供撤销功能以方便修改。当用户对作品满意后,启动上传流程。此时,客户端会将当前沙盒状态进行快照(一张视觉预览图和一张包含完整数据的“数据图”)。用户输入标题后,系统会对其进行身份验证,然后将打包好的作品数据提交至后端。后端服务负责进行反作弊检查、数据去重、持久化存储,并最终使作品在社区的“最新”列表中可见,完成了从个人创作到社区分享的闭环。

  1. 用户使用绘画工具在画布上绘制各种元素
  2. 沙盒内的元素根据物理规则进行实时模拟与交互
  3. 用户点击上传,客户端生成视觉快照和数据编码PNG
  4. 客户端打包作品数据,并通过认证API提交至后端
  5. 后端执行反作弊、去重、存储等一系列操作
  6. 作品成功发布,出现在社区的“最新”列表中

用户发现并“复刻”社区作品

该流程体现了产品的“再创作”核心价值。用户在社区发现页(如热门榜、最新列表)浏览他人作品。当点击进入一个感兴趣的作品后,系统会从服务器获取该作品的“数据图”。客户端随即在本地将这张图解码,并精确地将原始作品的每一个粒子状态还原到用户的沙盒环境中,加载完成后模拟处于暂停状态。此时,用户便拥有了一个与原作一模一样的副本,可以自由地继续进行模拟、添加新元素或进行修改,相当于对原作进行了一次“复刻”(Fork)。这个流程让社区内容得以不断演化和迭代。

  1. 用户在社区浏览页面(如热门、最新)发现作品
  2. 用户点击一个作品,客户端根据ID从后端请求加载数据
  3. 客户端下载数据PNG,并将其解码写入WASM模拟器内存
  4. 原始作品被完整还原到用户的沙盒中,模拟暂停,等待用户操作

社区成员参与内容评价与治理

此流程描述了普通社区成员如何参与到平台的内容生态治理中。用户在浏览作品时,可以对喜欢的作品进行“投票”,此行为会增加作品的“分数”,影响其在热门榜单中的排名。如果用户发现不适宜或违规的内容,可以发起“举报”。投票和举报操作都需要用户登录,以确保操作的可追溯性。被举报的作品会自动进入后台的审核队列,等待管理员介入处理。这个流程为社区提供了自我调节和净化环境的基本能力。

  1. 用户在浏览作品时,对喜欢的作品点击投票
  2. 客户端乐观更新UI,并向后端发送认证后的投票请求
  3. 用户发现不当内容,点击举报按钮
  4. 客户端向后端发送认证后的举报请求,作品进入后台审核队列

Key Features

细胞自动机模拟引擎

这是驱动整个沙盒世界的物理核心。它基于一个二维网格的细胞自动机模型,完全用 Rust 语言编写并编译为 WebAssembly(WASM) 在浏览器中运行。这种设计将计算密集型的物理模拟与前端渲染和UI逻辑分离,实现了卓越的性能,从而支持大规模粒子间的复杂互动和涌现行为。引擎不仅负责每个元素的独立行为,还处理风力等全局影响,并内置了健壮的撤销和模拟稳定性机制。

  • 多元素行为模拟 — 【设计策略】为每一种元素(如沙、水、火、植物)定义一套独特的、基于其周围环境的更新规则,以此在简单的规则基础上催生出复杂多样的宏观现象。 【业务逻辑】 1. 在每一帧模拟中,系统会遍历网格中的每一个粒子。 2. 根据粒子的类型(如“沙子”),调用其专属的更新逻辑。 3. **以“沙子”为例**: - Step 1: 检查正下方的格子。如果为空,则向下移动一格。 - Step 2: 如果正下方不为空,则随机检查左下或右下的格子。如果其中一个为空,则向该对角线方向移动一格。 - Step 3: 如果下方和对角线下方都被占据,检查正下方的粒子是否为“水”或“油”等液体。如果是,则与该液体粒子交换位置(实现沙子沉入液体的效果)。 4. 其他元素拥有各自的行为逻辑,如“火”会点燃相邻的可燃物并有一定几率熄灭,“植物”会向上生长等,这些独立的简单规则共同构成了丰富多彩的动态世界。
  • 风力物理效应 — 【设计策略】引入一个全局的“风场”系统,该系统可以对粒子施加推力,从而增加沙盒的动态性和不可预测性。不同元素的“抗风”能力不同,使得风的效果更具层次感。 【业务逻辑】 1. 在每帧的主更新逻辑开始前,系统会执行一个独立的“风力计算”阶段。 2. 系统读取每个粒子所在位置的风力向量(包含方向和强度)。 3. 将风力强度与该元素预设的“抗风阈值”进行比较。例如,“尘埃”的阈值很低(10),而“石头”的阈值很高(70)。 4. 如果风力强度超过阈值,系统会尝试将该粒子向风的方向推动一格,但前提是目标格子必须为空。 5. **特殊规则**:为了创造更生动的“阵风”效果,当“沙子”、“尘埃”等特定轻质粒子被向上吹时,如果其上方两格都为空,它会直接向上移动两格而不是一格。
  • 模拟稳定性保障机制 — 【设计策略】为了保证模拟过程的稳定和视觉效果的自然,必须解决两个核心问题:一是防止同一个粒子在一帧内被多次更新(导致瞬移),二是减少因固定扫描顺序带来的方向性偏差(例如,所有沙子都倾向于向左下角移动)。 【业务逻辑】 1. **防双重更新机制**: 系统维护一个全局的“代数”(generation)计数器,每帧递增。当一个粒子被更新或移动时,其自身的“时钟”(clock)属性会被设置为`当前代数 + 1`。在同一帧的后续处理中,任何逻辑在尝试更新一个粒子前,都会检查其“时钟”是否已经领先于“代数”,如果是,则跳过该粒子。 2. **扫描偏置消除**: 系统在水平方向上遍历整个网格的顺序是每帧交替的。例如,第1帧从左到右扫描,第2帧则从右到左扫描,以此类推。这有效避免了粒子在对角线移动时产生肉眼可见的方向性偏好。
  • 多步撤销系统 — 【用户价值】让用户可以无顾忌地进行实验性创作,即使犯了错也能轻松恢复到之前的状态。 【设计策略】采用基于完整状态快照的撤销机制。在用户执行关键操作前,将整个沙盒的当前状态完整保存下来。 【业务逻辑】 1. 在用户开始一次绘画操作(如鼠标按下)时,系统会自动触发一次“压入撤销栈”的动作。 2. 该动作会完整克隆当前网格中所有粒子的状态,并将这个“快照”存入一个队列的头部。 3. 这个队列最多只保留最近的 50 个快照。当新快照存入导致总数超过50时,最老的一个快照将被丢弃。 4. 当用户按下撤销键(Ctrl+Z),系统会从队列头部取回最新的快照,并用它完全覆盖当前的沙盒状态,实现瞬时复原。

创作、分享与社区平台

该模块覆盖了从创作到消费的整个用户内容生命周期。它为用户提供了直观的创作工具,并构建了一套完整的分享和发现机制。用户不仅可以创造,还可以将作品上传到云端,形成一个永久链接。其他用户可以通过这个链接或在社区的发现页面中找到并“加载/复刻”(Fork)这个作品,在其基础上进行二次创作。这套系统由前端的用户界面、与后端API的交互逻辑以及服务端的存储和数据管理共同构成,是产品社区生态的核心。

  • 交互式绘画与创作工具 — 【用户价值】提供流畅、精确且富有创造性的方式,让用户将想法“画”入沙盒世界。 【设计策略】提供多种笔刷尺寸,并对用户的连续涂画手势进行平滑处理,以避免在快速移动时产生断点。 【业务逻辑】 1. 用户可以从一个包含5种预设尺寸(半径从1像素到39像素)的列表中选择笔刷大小。 2. 当用户按下鼠标或触摸屏幕时,系统会立即记录一次撤销快照,并开始绘画。 3. 为了实现连续作画,系统会每隔100毫秒重复执行一次绘画操作。 4. 为了让快速划过的笔迹平滑连续,系统实现了“平滑绘制”逻辑:在两次鼠标移动事件之间,根据笔刷大小(步长=笔刷尺寸/5)进行线性插值,自动填充中间的空白点。 5. 支持多点触控,每个触控点都会被视为一个独立的笔刷进行绘画。
  • 创作快照与上传 — 【设计策略】将用户的创作打包成两个PNG图片:一个用于视觉预览,另一个作为包含完整模拟数据的“数据图”,并通过API上传到云端。同时,在客户端实施初步的速率限制以防止恶意刷屏。 【业务逻辑】 1. **生成数据包**:当用户点击上传时,系统会执行以下操作: - 生成一张用于社区展示的视觉快照PNG。 - 将当前沙盒中每个粒子的状态(类型、属性等)编码到一个300x300像素图像的RGBA通道中,并生成一张“数据PNG”。 2. **客户端速率限制**:在发送前,系统会检查本地存储中记录的最近5分钟内的发帖时间戳。如果发现已有3次或更多,则暂时阻止本次提交。 3. **上传流程**: - 要求用户登录,并获取其Firebase认证令牌(ID Token)。 - 将作品标题、视觉快照PNG、数据PNG以及可能的父作品ID打包成一个JSON对象。 - 通过HTTP POST请求,将该JSON对象连同认证令牌一起发送到后端API。
  • 加载与复刻(Fork)创作 — 【用户价值】允许用户不仅能观看他人的作品,还能将其完整加载到自己的沙盒中进行修改和再创作,极大地促进了社区内容的演化和传播。 【设计策略】通过作品ID从后端获取“数据PNG”,在客户端将其解码并精确还原到本地的WASM模拟环境中。 【业务逻辑】 1. 当用户通过URL哈希(如 `sandspiel.club/#xxxx`)访问一个作品时,客户端会解析出作品ID。 2. 客户端向后端API请求该ID的元数据,其中包括“数据PNG”在云存储中的地址。 3. 客户端下载该“数据PNG”图片。 4. 将图片绘制到一个离屏画布上,然后逐一读取每个像素的RGBA值。 5. 根据预设的编码规则,将RGBA值解码为粒子状态,并直接写入WASM的内存中,从而完成对原始作品的100%精确复制。 6. 加载完成后,模拟器默认处于暂停状态,等待用户开始自己的探索或修改。
  • 社区发现与浏览 — 【设计策略】提供多种排序和筛选方式,帮助用户在海量社区作品中发现感兴趣的内容,同时自动过滤掉已被判定为不良的内容。 【业务逻辑】 1. 提供多个浏览列表: - **按用户**: 查看指定用户发布的所有作品。 - **按热度**: 按分数高低排序,可叠加时间窗口(如日、周、月榜)。 - **按时间**: 显示最新发布的作品。 - **按标题搜索**: 进行全文关键字搜索。 2. 所有列表在从后端查询时,都会自动排除那些在后台被管理员标记为“坏 (`bad='yes'`)”的作品。 3. 默认列表展示最近85个作品,热门列表也限制在85个,而按用户和按父作品的列表最多可展示150个。
  • 投票与举报系统 — 【用户价值】提供社区成员参与内容评价和环境治理的基本工具。 【设计策略】对于投票采用乐观更新(Optimistic UI)以提升响应速度,所有操作均需用户登录认证。 【业务逻辑】 1. **投票**: 用户点击投票按钮后,界面会立即(乐观地)将作品分数加一。同时,客户端会向后端API发送一个包含用户认证令牌的投票请求。服务器完成处理后返回最终的真实分数,界面再用此真实值进行更新。 2. **举报**: 用户点击举报按钮,客户端同样会发送一个认证后的举报请求到后端。客户端不处理举报逻辑,仅负责触发。后端负责记录举报并将其纳入审核队列。

内容审核与管理系统

这是维护社区健康和内容质量的后台保障系统。它为管理员提供了一套工具,用于审查被用户举报的作品、作出裁决,并对违规用户或IP地址采取封禁措施。此模块完全在服务器端实现,并通过受保护的API端点供管理员前端调用。

  • 举报内容审核队列 — 【设计策略】自动聚合被举报且尚未处理的作品,并按举报数量的多少进行排序,以便管理员优先处理问题最严重的内容。 【业务逻辑】 1. 系统提供一个专门的API接口,用于获取待审核的举报列表。 2. 该接口会查询所有在最近20天内创建、收到过举报且尚未被管理员裁决过的作品。 3. 结果会按“被举报次数”降序排列,其次按“创建时间”降序排列。 4. 接口返回的数据中会包含作品信息、被举报的总次数以及发布者的用户ID,供管理员审查。
  • 管理员裁决与执行 — 【设计策略】通过多层防御机制(IP封禁、用户封禁、黑名单、发布速率限制)保护社区免受垃圾信息和滥用行为的侵害。所有上传行为都必须通过这些检查。 【业务逻辑】 1. **身份认证**: 所有上传操作都必须提供有效的用户登录令牌,且用户的邮箱必须是已验证状态。 2. **黑名单过滤**: 作品标题会经过一个词语黑名单的过滤,若命中则直接拒绝。 3. **封禁检查**: 系统会检查提交者的用户ID或IP地址是否在过去60天的封禁名单中,若在则拒绝。 4. **速率限制**: 系统会执行双重速率限制: - 同一IP在24小时内最多发布40个作品。 - 同一用户在5分钟内最多发布5个作品。 5. **内容去重**: 系统会根据作品的“数据PNG”计算一个MD5哈希值。如果该哈希值(的前20位)已存在于数据库中,则判定为重复内容并拒绝上传。

实时可视化与流体动力学引擎

该模块负责将WASM核心引擎中抽象的粒子数据实时、高效地渲染成用户可见的动态画面,并叠加一层可交互的流体(风)效果。它包含两个并行的WebGL渲染管线:一个用于绘制粒子本身,另一个用于模拟和渲染流体。这种设计不仅保证了视觉表现力,也通过精巧的内存共享机制实现了极致的性能。

  • WASM状态到GPU的实时渲染 — 【设计策略】采用“零拷贝”技术,让GPU直接读取WASM的内存来渲染画面,避免了在CPU和GPU之间来回复制大量数据的性能开销。 【业务逻辑】 1. WASM模拟引擎的所有粒子状态都存储在一块连续的内存中。 2. 在每一帧,前端的WebGL渲染器会获取指向这块内存起始位置的指针。 3. 渲染器直接将这块WASM内存区域的数据上传到GPU的纹理中,而不是先在JavaScript中创建一个副本。 4. GPU上的着色器(Fragment Shader)程序读取这个纹理,根据每个像素(代表一个粒子)的R通道值(代表元素类型)来计算并绘制出对应的颜色和视觉效果(如噪点)。 5. 这个过程每秒重复60次,确保了用户看到的画面与模拟状态的完美同步和极高流畅度。
  • 可交互的流体模拟 — 【设计策略】在GPU上独立运行一套完整的欧拉流体解算器,用于模拟和渲染风和压力的动态效果。用户的鼠标操作可以直接向流体中注入“力”,流体模拟的结果又可以反过来影响WASM中的粒子运动,形成闭环互动。 【业务逻辑】 1. 当用户在画布上移动鼠标(且未选择任何元素时),这被视为在向流体场中施加力。 2. 流体引擎在GPU上通过一系列着色器通道(如平流、散度、压力计算、梯度相减等)来解算下一帧的流体速度场。 3. 这个过程使用了“乒乓”技术(双缓冲FBO),在前一帧的结果上进行迭代计算。 4. 计算出的新速度场(即风场)会被回读到CPU,并更新到WASM模拟引擎中,用于影响下一帧的粒子运动。 5. 同时,流体密度场也会被渲染出来,形成用户看到的烟雾状视觉效果。
  • 动态颜色拾取 — 【设计策略】通过实际渲染一次所有元素来精确提取它们在当前着色器下的颜色,以确保UI中的元素图标颜色与游戏内完全一致。 【业务逻辑】 1. 当需要生成调色板时,系统会创建一个临时的、仅包含所有元素类型各一个的微型沙盒。 2. 系统渲染这个微型沙盒到一块离屏画布上。 3. 然后使用WebGL的`readPixels`功能,从画布上逐一读取每个元素渲染后的精确颜色值。 4. 最后,将元素ID与其对应的颜色值(如`rgba(186, 169, 137, 1)`)映射起来,存储为一个颜色查找表,供UI组件(如元素选择菜单)使用。

Core Technical Capabilities

基于WebAssembly的高性能浏览器内物理模拟

Problem: 如何在网页中流畅地运行涉及数十万粒子实时交互的复杂物理模拟?若使用传统的JavaScript,其计算性能将成为巨大瓶颈,导致帧率低下、操作卡顿,无法实现大规模、高互动性的沙盒体验。

Solution: 1. **核心逻辑迁移**: 将所有计算密集型任务,包括粒子运动、物理规则判断和状态更新,全部使用高性能系统语言Rust进行编写。 2. **编译为WASM**: 将Rust代码编译成高度优化的WebAssembly(WASM)二进制文件。浏览器能够以接近本机的速度执行WASM,其性能远超解释执行的JavaScript。 3. **J S作为胶水层**: JavaScript仅负责处理用户界面交互、调用WASM暴露的简单命令(如 `paint`, `tick`),以及驱动渲染循环,将复杂的计算任务完全委托给WASM核心。 **核心价值**:通过这种架构,成功地将桌面级应用的性能带到了浏览器中,使得大规模实时物理模拟成为可能。

Technologies: Rust, WebAssembly (WASM), wasm-bindgen

Boundaries & Risks: 虽然性能远超JS,但最终还是受限于用户的CPU性能,极端复杂的场景仍可能导致降帧。JS与WASM之间的通信存在开销,频繁、细碎的调用(而非批处理调用)可能会影响性能。

“零拷贝”的GPU实时渲染

Problem: 如何每秒60次地将数十万粒子的状态从模拟引擎传递给渲染引擎并绘制出来,而不会产生性能瓶颈?传统的做法是每帧都将整个粒子数据从CPU内存(WASM侧)复制到GPU内存(渲染侧),这将产生巨大的数据拷贝开销,导致严重的卡顿。

Solution: 1. **共享内存访问**: WASM模拟引擎的粒子数据存储在一块连续的内存区域中。 2. **直接指针传递**: JavaScript端的WebGL渲染代码不复制数据,而是直接获取指向这块WASM内存区域的指针。 3. **GPU直接读取**: 每一帧,WebGL被指示直接从该内存地址读取数据并上传到GPU纹理中。 **核心价值**:这种“零拷贝”方案消除了CPU到GPU的数据传输瓶颈,使得渲染更新几乎没有延迟,实现了模拟状态与视觉呈现的完美同步和极致流畅。

Technologies: WebGL, WebAssembly.memory, GLSL

Boundaries & Risks: 该方案强依赖于WASM内存地址的稳定性。如果WASM因故需要重新分配其内存(例如扩大沙盒尺寸),该指针将失效,渲染器若未能同步更新则可能崩溃或渲染错误数据。这种紧耦合需要开发者谨慎管理。

利用PNG图像进行无损状态持久化

Problem: 如何以一种紧凑、通用且能在浏览器中轻松处理的格式,来完整地保存和分享一个复杂沙盒场景的精确状态?使用自定义二进制格式难以在Web生态中流通,而大型JSON对象则既臃肿又低效。

Solution: 1. **数据图像化**: 将整个300x300的模拟网格视为一张300x300的图像。 2. **状态编码**: 将每个粒子的状态信息(如元素类型ID、特定属性等)编码到对应像素的R, G, B, A四个颜色通道中。 3. **PNG生成**: 在客户端,通过读取WASM内存,用JavaScript构建一个标准的`ImageData`对象,然后将其绘制到一个隐藏的Canvas上,并最终导出为通用的PNG图片格式。 **核心价值**:这种方法巧妙地将一个复杂的模拟状态打包成了一张标准的PNG图片。这张图片既是无损的数据备份,又是易于在网络上传输和预览的视觉文件。加载时只需逆向操作即可完美还原场景。

Technologies: Canvas API, ImageData, PNG

Boundaries & Risks: 每个粒子能存储的数据量被限制在4个字节(RGBA通道),这限制了未来扩展更复杂粒子属性的可能性。虽然PNG的无损压缩对此类数据效果不错,但极端复杂的场景仍可能导致文件体积较大。

基于云函数和多数据库的弹性后端架构

Problem: 如何构建一个低成本、高弹性且能处理用户认证、内容存储、数据查询和审核等多种任务的后端服务?传统的单体服务器架构难以应对社交应用的潮汐流量,且维护成本高。

Solution: 1. **无服务器计算**: 核心业务逻辑(如上传、投票、查询)部署为独立的Firebase云函数。这些函数按需启动和伸缩,完美应对流量波动,且只为实际计算付费。 2. **分层数据存储**: - 使用Firebase Storage存储用户上传的PNG等静态文件,享受CDN加速和高可用性。 - 使用PostgreSQL数据库存储作品的元数据、用户信息和举报裁决等结构化数据,利用其强大的查询和关系处理能力支持复杂的浏览和审核逻辑。 3. **集成身份认证**: 直接使用Firebase Authentication处理用户注册、登录和会话管理,无需自建用户系统,安全可靠。 **核心价值**:该架构结合了多种云服务的优点,实现了低运维成本、高可扩展性和功能完备性,是现代Web应用的敏捷开发典范。

Technologies: Firebase Cloud Functions, Firebase Authentication, Firebase Storage, PostgreSQL

Boundaries & Risks: 云函数存在冷启动延迟。数据库查询的复杂性会直接影响到函数的执行时间和成本。将文件上传和数据库写入放在`Promise.all`中并行执行而没有事务保证,可能在部分失败时产生孤立数据(例如文件已上传但数据库记录写入失败)。