
create-schematic-compute
Create: Schematic Compute brings a graph-based visual programming interface to the Create ecosystem, allowing you to build complex computational blueprints without messy redstone dust.
Список изменений
👥 Multiplayer Collaboration / 多人协作
All 7 blocks now support real-time collaborative graph editing — multiple players can edit the same node graph simultaneously. / 全部 7 种方块支持多人实时协作编辑同一节点图。
| Feature / 功能 | Description / 说明 |
|---|---|
| 🖱️ Live Cursors / 实时光标 | Colored crosshairs with player names / 彩色十字准星 + 玩家名 |
| 📦 Remote Node Drag / 远程拖拽节点 | Smooth lerp animation on remote moves / 远程移动平滑插值动画 |
| 🔗 Wire Preview / 连线预览 | Live bezier curve while dragging wires / 拖拽连线时实时贝塞尔曲线 |
| 👤 Player List / 玩家列表 | Right-side vertical list, host highlighted / 右侧竖向列表,房主高亮 |
| 🔒 Node Lock / 节点锁定 | IMAGE nodes protected during pixel editing / 像素编辑时自动锁定 |
| ⚡ Join/Leave / 加入离开 | Appear immediately on open, disappear on close / 打开即现,关闭即消 |
| ✏️ Op-Based Editing / 操作同步 | GraphOp + OpExecutor model, server-authoritative ID allocation / 服务器权威 ID 分配 |
⚡ Architecture Refactoring / 架构重构
| Change / 改动 | Description / 说明 |
|---|---|
| 🖥️ Server-Authoritative Eval / 服务端评估 | Client-side GraphEvaluator removed. All evaluation runs server-side; results synced via ClientboundGraphEvalPacket + EvalSnapshot. Fixes PRIVATE_IN/BUS_IN always returning 0 on client. |
| 🏗️ Unified BE Base / 统一 BE 基类 | SyncedGraphBlockEntity consolidates ~200 lines duplicated across 7 BEs (BUS lifecycle, RedstoneLink, NBT, sync, EvalSnapshot). |
| 📦 Blob Data Channel / Blob 通道 | BlobDataPacket + BlobRegistry for chunked large data. SET_IMAGE_PIXELS from Base64 to direct int[]. |
🔧 Debug Toolchain / 调试工具链
| Tool / 工具 | Description / 说明 |
|---|---|
| 📶 Signal Generator / 信号发生器 | Test signal source. Manual curve mode (draggable control points, X-clamped, server-sorted) or custom f(x) formula (all math functions, auto full-width paren conversion). Frequency-generate (auto-cycling X) or input-driven (drag sky-blue marker). Auto-scale Y axis with ±5 outlier clipping. |
| 📊 Signal Probe / 信号探针 | Real-time monitor with 100-tick trend chart. Auto-scale Y axis with outlier clipping. Right-click freeze/unfreeze/clear. |
📌 View Bookmarks / 视角书签
- ★ button (bottom-right, above ▼) toggles bookmark panel / ★按钮开关书签面板
[+]/Ctrl+Msave current view,[↺]/Homereset to origin[✎]rename,[✕]delete,[→]or click name to jump with 200ms ease-in-out transition- Drag name area to reorder, synced via
MOVE_BOOKMARKop - Click outside naming dialog to cancel; Esc handled by unified popup stack
- Multiplayer-synced via
ADD_BOOKMARK/REMOVE_BOOKMARK/RENAME_BOOKMARK/MOVE_BOOKMARKops
🐛 Fixes & Polish / 修复与打磨
- 🔧 Graph Init —
onLoad()bumps generation to force full recompile on first tick. - 🚌 BUS Channel —
registerChannels()no longer requiresbandCount()>0; empty-band channels register so BUS_IN reads immediately. - 🎨 Color Picker UX — ESC closes picker + panels together. Duplicated nodes get
sortB = original+1. - 📝 Bilingual Comments — All
graph/,blocks/,network/source comments now Chinese+English. - 🐛 Encapsulation DEBUG Visibility —
EvalSnapshotnow captures sub-evaluator outputs + debugTimes. Signal Generator (blue X marker) and Signal Probe work correctly inside encapsulation sub-graphs. / 封装内信号发生器(蓝色X标记线)和探针现在正确显示。 - ⌨️ Esc Key Delegation — Esc now closes sub-UI (bookmark rename, export/import dialog, color picker) before closing the entire editor screen. / Esc 先关闭子 UI 再关整个编辑界面。
- 🔒 Soft-Lock Scope — Node locking now scoped by
ownerNodeId. Selecting a node inside encapsulation no longer falsely locks main-graph nodes with the same ID. / 封装内选中节点不再误锁主图同 ID 节点。 - 🖱️ Cursor Scope Isolation — Remote player cursors are now filtered by scope; cursors inside encapsulation are hidden from main-graph view and vice versa. / 远端光标按作用域隔离。
- 🟡 ENCAPSULATION Occupant Highlight — Golden border + player name label on ENCAPSULATION nodes in the main graph when other players are editing inside. / 主图中被占用的封装节点显示金色边框+玩家名。
- 📝 ENCAP I/O Rename Sync — Renaming
ENCAP_INPUT/ENCAP_OUTPUTnow sendsSET_DISPLAY_TEXTop for server sync + undo support. / 封装I/O改名现在同步到服务端并支持撤销。 - 📋 Ctrl+D Copy Fix — Copy now uses server-authoritative ID allocation (
ADD_NODE_REQUEST→ ACK); data ops are deferred until all real IDs assigned. Sub-graph content recursively synced for ENCAPSULATION nodes. Fixes "empty node on other clients". / 复制走服务端权威ID分配,封装子图递归同步。 - 📐 Manual Curve Fixed Y-Axis — Signal Generator manual curve mode now uses fixed Y range
[-1.1, 1.1]; auto-scaling retained for formula mode. Control points clamped to visible range and rendered above border. / 手动曲线Y轴固定,控制点钳制+边框上方渲染。
🔗 Stable PinId Refactoring / 稳定引脚ID重构
Connections now bind to stable string pin identifiers instead of positional integer indices. Pin insertion, deletion, or reordering no longer breaks existing connections — they follow the pin by name.
| System / 系统 | pinId Source / pinId 来源 | Before / 修复前 | After / 修复后 |
|---|---|---|---|
| FORMULA inputs | Variable name (e.g. A, B, x) | Adding/removing variables shifted pin indices — connections broke or pointed to wrong pins | Connections follow variable names; ensureScriptParsed() eliminates lazy-parse race conditions |
| FORMULA outputs | @output label (e.g. result, angle) | Output reordering broke downstream connections | Connections track output labels; "out0" default handled correctly |
| ENCAPSULATION I/O | Sub-node ID (sorted by Y, then ID) | Dragging ENCAP_INPUT/OUTPUT nodes changed pin order — external connections silently shifted | pinId = sub-node ID, invariant under drag; parent cache rebuilt after sub-graph structural edits |
| BUS bands | Band name (e.g. band_0, band_1) | Inserting/removing/reordering bands cleared all connections or caused index drift | Only connections on actually-deleted bands are removed; reordered bands preserved |
Key changes:
NodeConnectiongainsfromPinId/toPinIdfields;save()/load()backward-compatibleGraphNodeaddsinputPinIndex(id)/outputPinIndex(id)/inputPinId(i)/outputPinId(i)— pinId↔index resolution per node typeNodeGraph.rebuildInputCache()resolves all pinIds to current indices, prunes stale connectionsGraphMigrationV3→V4: one-time NBT upgrade converting integer pins to stable pinIds for FORMULA, ENCAP, BUS, and generic nodes (recursive into sub-graphs)GraphEvaluatorBUS evaluation and ENCAP pin injection now match by pinId rather than cache positionBusChannelHelper.syncBandsFromServeronly disconnects actually-removed bands (by name), preserving reordered bandsNbtVersions.DATA_VERSIONbumped 3→4- Eliminates ~200 lines of REWIRE/reconnect complexity from the v1.2.5 roadmap — pin reordering is now free
Related docs: docs/v1.2.4-pin-id-stability-plan.md
🧠 Relay Nodes / 继电器节点
Two new logic nodes for conditional signal routing — available in both Blueprint and Program Computers.
| Node / 节点 | Description / 说明 |
|---|---|
| Relay A / 继电器A | SPDT (双掷) — 3 inputs (A, B, Contact), 2 outputs. Contact ≤0.5 → A输出=A, B输出=0; Contact >0.5 → A输出=0, B输出=B. Mutually exclusive throws like a physical relay. |
| Relay B / 继电器B | SPST (单掷) — 3 inputs (A, B, Contact), 1 output. Contact >0.5 → out=B; else → out=A. Merged single-throw variant. |
Both use the standard >0.5 threshold consistent with BOOL/GATE/OR. No parameters, pure combinatorial logic — compatible with multiplayer collaboration and encapsulation out of the box.
🪑 Sable Sub-Level Control Seat Camera / Sable 子关卡控制座椅相机
Two camera modes for Control Seat riders inside Sable rotating structures. Camera orientation computed client-side from block FACING + Sable render-pose quaternion — bypasses entity yaw sync (unreliable for retain_in_sub_level entities).
Sable 旋转结构上控制座椅的两种相机模式。座椅世界朝向由客户端根据方块 FACING + Sable 渲染姿态四元数实时计算,不依赖 entity yaw 同步。
| Mode / 模式 | Camera / 相机 | Output / 输出 |
|---|---|---|
| FIXED (default) | Locked to seat world orientation (yaw + pitch). ControlSeatCameraMixin disables Sable camera rotation to prevent double-rotation. / 锁定到座椅世界朝向(偏航+俯仰) | Joystick mx/my from raw mouse delta / 摇杆来自鼠标增量 |
| VIEW_DIFFERENCE | Free camera, mouse-controlled. Sable does not rotate the view. / 自由相机,鼠标控制 | vy = playerYaw - seatWorldYaw, vp = playerPitch - seatWorldPitch |
ControlSeatBlockEntitySable: fixed missingsetYRot()— entity yaw now properly updates bothyRotandyRotO. / 修复缺失的 setYRot()。ControlSeatEntity: manualsetPosskipped inside sub-levels (Sable handles positioning). / 子关卡内跳过手动 setPos。ControlSeatCameraMixin: registered inrequired:falsesable mixin config — silently skipped without Sable. / 无 Sable 时静默跳过。
🎮 MOUSE_JOYSTICK Absolute Mode / 鼠标摇杆绝对值模式
Per-node toggle in the edit panel switches between incremental (direct mouse delta, default) and absolute (accumulated stick position with memory, clamped to [-1,1]).
编辑区提供每节点独立开关,在增量(默认,鼠标位移即输出)和绝对值(累积摇杆位置,停手保持)之间切换。
- Uses
TOGGLE_BOOLop pipeline — server-authoritative, undo-supported, multiplayer-synced. / 复用 BOOL 开关流水线。 - Absolute accumulation uses
ABS_SCALE=1/6per tick for smooth control. / 绝对值每 tick 累积系数 1/6。 - Stick position persists across GUI open/close. / 开菜单再关闭位置保持。
- Both x and y axes accumulate independently. / X/Y 轴独立累积。
🔧 Signal Generator Auto-Scale Fix / 信号发生器自动缩放修复
- Root cause:
computeVisibleRange()used fixed ±5 clipping, squashing large-range formulas (e.g.x*360) into a ~6-unit Y window while rendering used raw values → curve painted to chart corners looking like an inverse-proportional function. - Fix: Replaced ±5 hard clipping with percentile-based robust range (p1–p99). Only extreme outliers (|v| ≥ 1e6) and NaN/Inf are filtered. Both
DEBUG_SIGNAL_GENandDEBUG_PROBEcharts use the same logic. - Y-axis range label: Chart top-right now shows
min … max(e.g.0.0 … 360.0) so the scale is immediately visible. - Cache: Formula compilation cache (
debugFormulaRpn) properly invalidated on formula edits — chart refreshes instantly.
🎨 Formula Editor UX / 公式编辑器体验
Syntax Highlighting / 语法高亮 — Real-time token-based colouring with 9 categories: functions (yellow), constants (pink), identifiers (cyan), numbers (orange), operators/parens (grey), comments (green), @output/assignment (purple), unknown (red underline). Token cache avoids per-frame re-parsing. / 实时词法彩色标注,9 种分类:函数(黄)、常量(粉)、标识符(青)、数字(橙)、运算符/括号(灰)、注释(绿)、@output/赋值(紫)、未知(红色下划线)。Token 缓存避免每帧重复解析。
Autocomplete Popup / 自动补全候选框 — Type identifier characters to trigger filtered dropdown (functions, named constants, current variables); type @ for immediate @output. Keyboard: ↑↓ navigate, Tab/Enter accept, Esc dismiss. Mouse: click any candidate to accept. Popup renders above all pins (z-layer C=5.5) with zoom-aware scaling — text and layout scale proportionally with graph zoom. Deleted variables immediately disappear from suggestions. / 输入标识符触发过滤候选框;输入 @ 立即建议 @output。键盘导航/接受/关闭,点击候选项接受。候选框渲染在所有引脚上方(C=5.5 层),支持缩放感知。删除变量立即从候选消失。
Real-Time Validation / 实时校验 — Red ⚠ badge on FORMULA node title bar; hover for tooltip list. Checks: bracket matching, unknown function, wrong arity, invalid assignment (errors), duplicate outputs, @output without identifier (warnings). Red border on the edit box when errors present. Validation cached after NBT reload to avoid per-frame re-parse. / 红色 ⚠ 徽章 + 悬停工具提示。校验:括号匹配、未知函数、参数数错误、无效赋值(错误),重复输出名、@output 缺变量(警告)。输入框红色边框。NBT 重载后缓存避免每帧重解析。
Named Constants / 命名常量 — (PI) and (E) in grouping parentheses are literal constants (π / e). Bare PI/E or inside function calls like sin(PI) are variable references (create input pins). Consistent across extractVariables(), compile(), and tokenize(). / (PI)/(E) 在分组括号内为字面常量。裸 PI/E 或函数调用内 sin(PI) 视为变量。三种解析入口行为一致。
Robustness / 健壮性 — Mouse drag selection restored (hlPos sync scoped). SET_FORMULA self-skip prevents EditState recreation → no focus loss during typing. Formula responder re-fetches graph node each keystroke (handles NBT sync between keystrokes). Connection cleanup corrected to use inputs()/outputs() clamps. Screen-width hardcoded 1920 replaced with getGuiScaledWidth(). Null safety in suggestion filtering. / 拖拽选区修复、SET_FORMULA 自跳、按键间图引用重获取、连线清理用 clamp 值、屏幕宽度动态获取、候选过滤 null 防护。
Tests / 测试 — 27 new unit tests covering tokenize, extractVariables, compile/evaluate, validate, parseScript, countFunctionArgs, and edge cases. / 27 个新单元测试。
