Picked up the prototype I started in 2023 and reworked it to use my new signals implementation. I am in general very happy with the semantics of my signals in JavaScript, the syntax is fine but a bit clunkier than I would like, and performance remains to be seen.
Signals are exciting because they can unify input and control flow1. One thing to call out in this prototype is the pointer.move signal I wrote:
import { go, Signal } from "@ajeeb/signals";
import { frame } from "./bus";
const pointerRaw = Signal.event(document, 'pointermove')
export const pointer = {
move: new Signal(
{ x: 0, y: 0 },
function* (signal) {
let state = { x: 0, y: 0 }
go(function* () {
while (true) {
const e = yield pointerRaw
state.x += e.movementX
state.y += e.movementY
}
})
while (true) {
yield frame
signal.emit(state)
state = { x: 0, y: 0 }
}
})
}
Its tricky because the DOM pointermove event fires multiple times a frame, passing movement deltas in movementX and movementY. What we want is to accumulate those deltas between frames and emit the accumulations one per frame. That's stateful and depends on two input signals -- pointermove and frame (which I an driving with PIXI's Application.ticker) but its relatively straightforward to implement!
I am trying to preserve each build I make to snapshot my progress. Here's this week's:
The controls are all over the place and I am not convinced of the approach I am taking (I adjust the torque of the capsule based on the desired heading). It feels very slippery. Might be workable by scaling torque on a curve, might need a whole new approach.
My 2023 prototype got derailed thinking about terrain generation way too early. This time around I am going to get the controls to feel right on a sparse canvas before moving on.
🐋
In the past I had control flow system called @ajeeb/coroutines that allowed you to schedule coroutines to be run, and a separate @ajeeb/input that handled input pipelines. It served me well but I definitely encountered situations where the fact that input was "outside" of the control flow system was awkward. ↩︎