Trying out the Chickadee custom vat

Hi! I was attempting to play around with the Chickadee example vat in the community-garden repo. I’m having a bit of trouble, though, and I’m probably just misunderstanding something :sweat_smile:

Here’s my attempt at the moment:

(define-module (community-garden test-chickadee-vat)
  #:use-module (community-garden chickadee-vat)
  #:use-module (goblins)
  #:use-module (goblins vat)
  #:use-module (oop goops)
  #:use-module (chickadee)
  #:use-module (chickadee scripting)
  #:use-module (chickadee graphics text)
  #:use-module (chickadee math vector))

(define (^artist bcom)
  (lambda ()
    ;;(display "Drawing...")
    (draw-text "Hello world!" (vec2 260.0 240.0))))

(define-class <chickadee-vat-test> ()
  (vat #:accessor vat)
  (started #:accessor started? #:init-value #f)
  (artist #:accessor artist))

(define-method (start (self <chickadee-vat-test>))
  (define (draw alpha)
    (if (started? self)
        (script
         (with-vat (vat self)
                   ($ (artist self))))))
  
    (define (update dt)
      (update-agenda 1))

    (define (load)
      (script
       (slot-set! self 'vat (make-chickadee-vat))
       (vat-start! (vat self))
       (slot-set! self 'artist
                  (with-vat (vat self)
                            (spawn ^artist)))
       (slot-set! self 'started #t)))

    (run-game #:draw draw #:update update #:load load))

(define tester (make <chickadee-vat-test>))
(start tester)

I’m trying to have actors that are able to draw on the screen when requested, as I described in a previous forum post. The game window opens, and while I’m able to see the “Drawing…” message that my artist actor prints if I uncomment that, the text is never drawn.

I wasn’t sure if I needed to make the method call to my artist object in a script (the “Hello world” program on the Chickadee site does not) but if I don’t I get an error as follows:

Backtrace:
In ice-9/boot-9.scm:
  1752:10 12 (with-exception-handler _ _ #:unwind? _ # _)
In unknown file:
          11 (apply-smob/0 #<thunk 7f8e05912300>)
In ice-9/boot-9.scm:
    724:2 10 (call-with-prompt _ _ #<procedure default-prompt-handle…>)
In ice-9/eval.scm:
    619:8  9 (_ #(#(#<directory (guile-user) 7f8e05915c80>)))
In ice-9/boot-9.scm:
   2836:4  8 (save-module-excursion _)
  4388:12  7 (_)
In chickadee.scm:
   414:11  6 (run-game #:window-title _ #:window-width _ # _ # _ # _ …)
In chickadee/game-loop.scm:
    96:26  5 (run-game* #:init _ #:update _ #:render _ #:time _ # _ # …)
     43:8  4 (call-with-error-handling _ _)
    97:28  3 (_)
In chickadee.scm:
   388:10  2 (render-sdl-opengl 0.002672420290764435)
In goblins/vat.scm:
    213:2  1 (call-with-vat #<vat chickadee> _)
In unknown file:
           0 (_ (script) #<procedure 7f8e05859c00 at chickadee/scrip…>)

ERROR: In procedure abort: Abort to unknown prompt

But I’m wondering if the use of script is what’s resulting in nothing being displayed here, because the return value of a script call is a handle to the script. So if drawing relies on the return value of draw-text, that could be the culprit.

Hi @jfred! I’ll start with a brief disclaimer that the community garden demo is built on top of a git snapshot of chickadee and an as-of-yet-unreleased game engine built on top of it so it’s a bit of a moving target. That said, I’m happy to help you understand what’s going on.

The main issue with your code is that you are attempting to render using an actor. When you call (with-vat (vat self) ($ (artist self))) in your draw procedure, it is actually scheduling work to be performed later during the game loop’s update step by pushing a message onto the vat’s queue. This means that the draw-text call doesn’t happen within the context of the draw procedure, and the result is that you don’t see any text because the screen will have been cleared before the next frame is rendered. The fix is to move all rendering code outside of actor behaviors. Your ^artist could tell you what text it currently represents, but leave it up to the UI layer to choose how to render it. The simplest way to do this is to periodically poll the actor for its current state and update some rendering state accordingly. That is actually what the Community Garden demo does because I didn’t have enough time to implement push-based updates, which would be more efficient.

The Community Garden demo works by using actors to model the behavior and essential state of the application, but notably the actors know nothing about rendering. This decouples the actors from any particular UI. This decoupling allowed me to start with simple terminal rendering and move on to a graphical view later on. It also avoids the issues you are running into where graphical rendering needs to be run in the correct context for it to be visible.

You might be wondering “well, what’s the point of the Chickadee vat, then?” The Chickadee vat integrates with Chickadee’s single-threaded game loop by using it’s agenda scheduling system for async tasks. This allows us to modify game state from the proper thread and avoid multiple thread writing issues.

For your specific example code, I would add more slots to <chickadee-vat-test> to hold the artist’s current rendering state (the string and position vector, perhaps) and use that information in draw. Remove the script form in draw, too, as it’s unnecessary and using any scripting features would just defer the rendering into the update step, which as mentioned above won’t be visible.

I hope this helps! Let me know if you have additional questions!

3 Likes

Ah! Right, that makes sense. I was missing the detail that script forms result in things running during the update step. (Is calling update-agenda the thing that actually runs those?)

My example code was a lot simpler than what I’m actually trying to do (I want the actors to have a decent amount of control over what gets displayed) but I’ll have to reconsider my design a bit given this.

Thank you for the explanation! That cleared things up a lot.

1 Like

Yup, calling update-agenda is what moves the scheduler forward in time and runs scheduled tasks.

1 Like