NESBox 平台

类似产品:

UI 参考 Steam、App Store、LOL

类似 Unity 的游戏引擎

攻能:
  • Dashboard
    • 挑选游戏开始(实际是开私人房间)
  • 游戏详情
  • 设置
    • 昵称
    • 自定义按键
    • 画质增强
  • 多人游戏
    • 公共房间,可以选择进入
    • 上下机
    • 换房主
    • 换游戏
    • 房间聊天
      • 文字聊天
      • 语音聊天
  • 用户系统(当前 WebSocket 的使用方式导致不满足云原生应用要求,接 MQ 可解决)
    • 自己喜欢的游戏
    • 游戏评论
    • 游戏存档,可继续游戏
    • 好友系统
      • 聊天
      • 邀请

TV 版功能:
  • Library
  • Recents
  • Rooms
  • Room
    • 上下文菜单
      • 连接/断开语音
      • 邀请好友
      • 保存截图
  • 设置
    • 语言



技术栈:
  • 后端
    • diesel-pg
    • actix-web
      • websocket 消息订阅
    • webrtc 语音通话
  • Web
    • gemjs
    • nes_rust_wasm tetanes
  • Mobile:Flutter
  • Desktop:Tauri

遇到的问题:
  • 根据游戏 ROM hash 进行状态储存,使用 Caches API,截图、日期存在 URL 参数中,避免使用复杂的 indexedDB,缓存 Wasm.memory 或者 Rust 对象二进制序列化
  • 传输 Canvas 流会压缩导致颜色失真,使用 qoi 压缩传输帧。曾尝试过 WebCodec 媒体流,它有音画不同步的问题。
  • 视频延时大,根据 Ping 值使用降帧方案,并禁用 WebRTC 的顺序传输,修剪帧传输
  • 语音系统,使用服务器 WebRTC 转发
  • 添加金手指功能,游戏组件庞大,拆分组件
  • Tauri 的问题:MacOS localstorage、加载白屏
  • 消除噪音(不需要改变播放速度),远端音画同步
  • 统一渲染滤镜到前端(WebGL)
  • 支持自制 js 游戏,沙盒保证安全(暴露 OffscreenCanvas,AudioContext 和 WebGPU)
    • 字体渲染
    • 音频输出
    • 动画
    • 资源压缩
    • 半像素渲染
    • 2d 碰撞?
  • 支持自制 wasm 游戏(同步、资源无限制)
    • 安全性 // 有些意外导入,例如 Function 构造器
    • 使用 bevy_ecs
    • input resource
    • schedule
    • save state(bevy example, 依赖 bevy_render, bevy_assets) // wasm memory
    • render plugin
      • 层级,变换
      • 文本
      • 贴图
    • audio plugin
    • 渲染顺序 // 当前用的 z 轴比较
    • 五子棋 AI // 博弈树极大极小值 alpha-beta 剪枝搜索
    • 2d 碰撞?
  • 支持街机(ROMs 下载),Emscripten 编译 C++ 模拟器

Libretro 的 wasm4
  • 无胶水代码 // 如何渲染到屏幕?
  • 类似 NES 平台,资源有限制
  • 支持 rollback netcode // 预测,内存回滚


  • 背景
    • 8x8 为 tile,16x16 为 block
    • 一个 tile 从 chr 中索引到,chr 最多存 256 个 tile,用命名表来索引 // 总共 960 字节的索引
    • 一个背景 4 个调色板,1 个调色板 4 个颜色,包括一个共享颜色,16 字节 // 所以最多 10 个颜色
    • 一个 block 最多 1 个调色板,属性表用来表示 block 使用的调色板 // 64 字节的调色板索引
    • 2 个命名表形成滚动效果
  • Sprite
    • 也是一个 Tile 8x8,一般是多个 Sprite 组成一个角色
    • 也有自己的 CHR 页,一套 4 个调色板
    • 一个 Sprite 需要 Y 坐标、Tile 索引、属性(调色板、翻转、和背景相对深度)、X 坐标 4 个字节
    • 总共 256 字节空间记录所有 Sprite 的位置和状态 // 所以最多 64 个 Sprite,多于 64 时只会保存最新存在内存中的,所以会闪烁

defaults write com.apple.GameController bluetoothPrefsMenuLongPressAction -integer 0
defaults write com.apple.GameController bluetoothPrefsShareLongPressSystemGestureMode -integer -1