Krestianstvo Electric Lazy Reflector for Croquet VM
Tags: javascript, clojure, webdev, opensource
Published: 2024-05-20 04:04:35

[Krestianstvo Electric](https://github.com/NikolaySuslov/krestianstvo-electric) introduces the Lazy Reflector for Croquet VM. This becomes possible due to implementing it in [Clojure Electric](https://github.com/hyperfiddle/electric) programming architecture involving continuous-time signals with lazy sampling and streaming DAGs.

![Lazy Reflector](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zoh755cv65ok215nh81f.gif)

All known Croquet implementations (including the [Smalltalk](https://en.wikipedia.org/wiki/Croquet_Project), [VWF](https://github.com/virtual-world-framework/vwf), [Croquet OS](https://croquet.io/) and recent [Multisynq protocol](https://multisynq.io/)) also OSS [Krestianstvo on Solid JS](https://play.krestianstvo.org/) are involving discrete timestamp generator (aka Reflector server). The Reflector should produces periodic ticks (~25-50 ms) and also timestamps all external messages coming from the views, then replicates these messages back to all connected peers of some concrete session (Island). If Reflector will not produce any messages, the Croquet VM will be suspended, waiting for any. In simple words, Reflector periodic ticks are needed for any animated in time simulation go forward in Croquet. But, the high frequency Reflector becomes redundant for simulations with slow rates for example or in the applications with no time-animated simulations at all.

The Lazy Reflector is "ticking" and "time-stamping" only on demand, staying the most time idle and laziness - not producing any work at all! However it guarantees, that all connected peers will get just the same ticks and time stamped messages, without missing a single one! As it is based on backpressured Electric continuous lazy server clock. 

```clojure
(new (actQueue (reset! !reflectorTime (e/server e/system-time-ms))))
```

That perfectly fits Croquet architecture, as in general the most application work is done locally by the clients themselves. That includes involving Future messages with temporal recursion that producing no network traffic at all (future messages never going to the Reflector).  
Also Lazy Reflector ticks are now not added to the Croquet VM priority queue. They are only moving local virtual time forward, pulling lazy server clock on demand by the future messages.  

![Past & Present Virtual Time](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1r8gmulxqidt8v4ynj2k.gif)

To try it in action, there are several example applications in [Krestianstvo Electric](https://e.krestianstvo.org/).
Want to mention, that in the [Counter example](https://e.krestianstvo.org/(krestianstvo.fiddles!%43ounter)/), the button "Loop" is not triggering Reflector to start ticking periodically. The button send only one external message launching temporal recursion on all connected peers. Then future messages pull the lazy server clock with the sample rate defined in the future step amount (after every virtual 0.5 sec in future do :step).

```clojure
step (fn [m]
    (swap! !objData update-in [seloID objID :x] inc)
    (sendFutureMsg {:name :step, :when 0.5, :objid objID}))
```

The source code is available on [Github repository](https://github.com/NikolaySuslov/krestianstvo-electric)