Blender's Tab, Shift, Alt, Ctrl and Esc cannot be read by a Scratch project at all — scratch-vm's keyboard handler throws away any key name longer than one character as a modifier, and the VM's mouse device carries no button identity, so there is no right-click either. Four bindings had to move. Where they moved to is in brackets. [Everywhere] the backtick key: toggle Object / Edit mode — stands in for Tab, being the key directly above it drag: orbit the view click: select hold space + click: extend the selection — stands in for Shift-click arrow keys: pan [ / ]: dolly out / in F / L / T: front / right / top axis view (Blender's Numpad 1 / 3 / 7) O: perspective ⇄ orthographic (Numpad 5) H: reset the view M: cycle shading: wireframe → solid → solid + wireframe A: select all — press again to deselect all (this is a toggle because Alt+A is unreadable; it is also what Blender 2.7x did) [Transform — the modal grammar] G: grab R: rotate S: scale X / Y / Z: while an operator runs: constrain to that axis; press the same key again to release it 0–9 . -: while an operator runs: type an exact value. - toggles the sign click or Enter: confirm C: cancel — restores the scene exactly — stands in for Esc / right-click G / R / S: while an operator runs: switch to that operator, keeping the selection and pivot [Object Mode] D: duplicate, and drop into a grab (Blender's Shift+D) X: delete the selected objects , / /: scroll the outliner when there are more than eight objects click: the six ADD MESH buttons add a Plane, Cube, Sphere, Cylinder, Cone or Torus [Edit Mode] 1 / 2 / 3: vertex / edge / face select mode E: extrude the selected faces, and drop into a grab along their normal W: subdivide the selected faces (Blender 2.7x put this on the W specials menu) X: delete the selected vertices and every face using them
A 3D editor with Blender's interaction model — modal G/R/S transforms with axis constraints, numeric entry and a real cancel; Object Mode and Edit Mode; vertex/edge/face selection; extrude and subdivide; six procedural primitives; an outliner and a live transform readout — rendered entirely with the pen, in goboscript. Not a Blender clone. Blender is millions of lines. But what makes Blender feel like Blender is its interaction grammar, and that part is reproducible: you press G, the object follows the pointer, you press X and it snaps to the red axis, you type 2 and it goes exactly two units — and if you press C the scene is back to precisely what it was before you started, to the last decimal place. There is a test that proves that last claim; see below. THE INTERESTING DECISIONS Faces are fixed-width quads, and that is the whole architecture. Scratch has no nested lists, so the textbook polygon mesh — a jagged array of faces each with its own vertex count — needs a (start, length) slice table on top of a flat index list. A renderer can afford that. An editor cannot: every extrude, subdivide and delete then has to splice three tables in step. So a face here is four parallel index lists and a triangle is a quad with d == c. The degenerate edge that produces is a zero-length pen stroke from a vertex to itself, which draws nothing and costs one goto — and in exchange every mesh operator becomes flat list arithmetic. All objects share one vertex pool and one face pool, each owning a contiguous window, and **face indices are stored local to their own window**, so growing one object's mesh never rewrites another object's indices, only the two integers saying where its window starts. Edges are derived, never authored. Maintaining an edge list surgically through an extrude is where mesh editors get their subtlest bugs, so there is no attempt: after every topology change the edge table is rebuilt from the faces, deduplicated through a packed min*1024+max key so the uniqueness test is Scratch's own native item # of scan rather than a nested loop. The rebuild also records which one or two faces share each edge — which is what makes a real silhouette outline possible in Object Mode. An edge is on the silhouette exactly when its two faces disagree about which way they face, and the renderer already left those front/back flags behind from the cull pass, so Blender's orange object outline costs two list reads per edge. Subdivide has to cut the neighbours too, and forgetting that is invisible. This was the last real bug in the project and the most instructive one. Cut one face of a cube into four and the four faces around it still run corner to corner: none of them mentions the new midpoint sitting exactly on its edge. The render is perfect — the midpoint is geometrically on the line — but every one of those midpoints is a T-junction, the surface is no longer manifold, and the first time you grab one the model splits open along a seam that was never visible. Nothing about looking at the screen tells you; what tells you is that the Euler characteristic has gone from 2 to −2 and twelve edges have only one adjacent face. Blender fixes it by turning each affected neighbour into an n-gon. All original - code, art and sound. See Inside is open.