Archives

Tags

Posts with tag "goblins"

Terminal Phase v1.1 and Spritely Goblins v0.6 releases!

By Christopher Lemmer Webber on Thu 05 March 2020

Hello all! I just did a brand new release of both:

So some highlights from each.

Terminal Phase

Okay, this is flashier, even if less important than Goblins. But the main thing is that I added the time travel debugging feature, which is so flashy I feel the need to show that gif again here:

Time travel in Spritely Goblins shown through Terminal Phase

Aside from time travel, there aren't many new features, though I plan on adding some in the next week (probably powerups or a boss fight), so another release should be not far away.

And oh yeah, since it's a new release, now is a good time to thank the current supporters:

Terminal Phase Credits

But yeah, the main thing that was done here is that Terminal Phase was updated for the new release of Goblins, so let's talk about that!

Goblins

For those who aren't aware, Spritely Goblins is a transactional actor model library for Racket.

v0.6 has resulted in a number of changes in semantics.

But the big deal is that Goblins finally has decent documentation, including a fairly in-depth tutorial and documentation about the API. I've even documented how you, in your own programs, can play with Goblins' time travel features.

So, does this mean you should start using it? Well, it's still in alpha, and the most exciting feature (networked, distributed programming) is still on its way. But I think it's quite nice to use already (and I'm using it for Terminal Phase).

Anyway, that's about it... I plan on having a new video explaining more about how Goblins works out in the next few days, so I'll announce that when it happens.

If you are finding this work interesting, a reminder that this work is powered by people like you.

In the meanwhile, hope you enjoy the new releases!

Time travel debugging in Spritely Goblins, previewed through Terminal Phase

By Christopher Lemmer Webber on Thu 23 January 2020

Time travel in Spritely Goblins shown through Terminal Phase

Okay, by now pretty much everyone is probably sick of hearing about Terminal Phase. Terminal Phase this, and Terminal Phase that! Weren't you getting back to other hacking on Spritely Goblins, Chris? And in fact I am, I just decided it was a good idea to demo one of the things that makes Goblins interesting.

What you're seeing above is from the experimental tt-debugger branch of Terminal Phase (not committed yet because it's a proof-of-concept, and not as clean as I'd like it to be, and also you need the "dev" branch of Goblins currently). When the user presses the "t" key, they are presented with a menu by which they can travel backwards and forwards in time. The player can select a previous state of the game from every two seconds and switch to that.

Here's the cool part: I didn't change a single line of game code to make this occur. I just added some code around the game loop that snapshotted the state as it currently existed and exposed it to the programmer.

What kind of time sorcery is this?

Dr. Who/Dr. Sussman fez comparison

Well, we're less the time-lord kind, more the functional programmer kind. Except, quasi-functional.

If you watched the part of the recent Terminal Phase video I made that shows off Goblins you'll remember that the way that objects work is that a reference to a Goblins object/actor is actually a reference that indirectly refers to a procedure for handling immediate calls and asynchronous messages. Relative to themselves (and in true actor fashion), objects specify first their initial version of themselves, and later can use a special "become" capability to specify a future version of themselves. From the perspective of the actor, this looks very functional. But from the perspective of one object/actor performing a call against another object/actor, it appears that things change.

Here is the simplest example of such an object, a cell that holds a single value:

;; Constructor for a cell.  Takes an optional initial value, defaults
;; to false.
(define (^cell bcom [val #f])
  (case-lambda
    ;; Called with no arguments; return the current value
    [() val]
    ;; Called with one argument, we become a version of ourselves
    ;; with this new value
    [(new-val)
     (bcom (^cell bcom new-val))]))

If you can't read Racket/Scheme, not a big deal; I'll just tell you that this cell can be called with no arguments to get the current value, and with one argument to set a value. But you'll see that in the former case, the value we would like to return to the caller is returned; in the latter case, we return the handler we would like to be for handling future messages (wrapped up in that bcom capability). In both cases, we aren't performing side effects, just returning something.. but in the latter case the kernel observes this and updates the current transaction's delta reflecting that this is the "new us". (Not shown here but supported: both becoming a new handler and returning a value.)

Without going into details, this makes it extremely easy to accomplish several things in Goblins:

  • Transactionality: Each "turn" of an event loop in Goblins is transactional. Rather than being applied immediately, a transaction is returned. Whether we choose to commit this or not is up to us; we will probably not, for instance, if an exception occurs, but we can record the exception (a default event loop is provided that does the default right-thing for you).
  • Snapshotting time: We can, as shown above, snapshot history and actually run code against previous state (assuming, again, that state is updated through the usual Goblins actor "become" means).
  • Time-travel debugging: Yeah, not just for Elm! I haven't built a nice interface for it in the demo above, but it's absolutely possible to expose a REPL at each snapshot in time in the game to "play around with" what's happening to debug difficult problems.

This is only a small portion of what makes Spritely Goblins interesting. The really cool stuff will come soon in the distributed programming stuff. But I realized that this is one of the more obviously cool aspects of Spritely Goblins, and before I start showing off a bunch of other interesting new things, I should show off a cool feature that exists in the code we already have!

Anyway, that's it... I hope I gave you a good sense that I'm up to interesting things. If you're excited by this stuff and you aren't already, consider donating to keep this work advancing.

Whew! I guess it's time I start writing some docs for Goblins, eh?

Announcing Goblins (the actor model foundation of Spritely)

By Christopher Lemmer Webber on Wed 31 October 2018

In my last post I talked about launching the Spritely project in all its ambitiousness. As I said, I plan on releasing it as a series of "demos". What I mean by "demo" is fairly loose: things you can try and see, artifacts to indicate progress as I go. Convergence slowly towards a goal.

Over the last week I released the first version of the foundation of this work, which I'm calling Goblins. v0.1, a pre-pre-alpha release, is now out the door. Goblins is an actor model implementation for the Racket programming language. I think if you know some Racket, then the Goblins documentation should be fairly approachable, and I'd love to hear feedback. Not everything is documented, but it should give you a nice taste of what the core ideas are. (Astute readers may observe that Goblins' name shares striking resemblance to another project I have worked on; this is no coincidence and is indeed a hint as to what I think the future direction of that area of work is.)

Most live distributed systems are in some way a language-level actor model implementation, but knowing that you're an actor model implementation may change how you do things. (ActivityPub is itself an actor model protocol, though I think not all implementors realize that.) Goblins is the third generation of an actor model I've written, the previous ones being XUDD and 8sync. (Maybe if you count the big rewrite I did of 8sync to run it on top of fibers, it could be the fourth generation.)

If you read the Spritely blogpost you'll know that distributed games are part of the long con here. This isn't the first time I've written a game system on top of one of these actor model implementations; in fact if you scroll down on 8sync website you'll (currently) see a video of me presenting on Mudsync, a multi-user dungeon written in 8sync, where in the talk instead of slides I had rooms, and the audience was moving around in the world and I was changing it in response to their suggestions.

But the drive of the actor model connected to social distributed games goes back further for me. I initially got interested in an actor model the first time I tried to work on the whole multiplayer game front about a decade ago. A friend and I spent a couple hours experimenting with threads and locks and after the first demo it was obvious that was never going to work. I remembered I had been told by a former coworker that they had used a system that had an actor model + coroutines as its basis; I didn't know what either of those things were yet, but as I looked into them it became clear to me that this was the right route. But one piece since then until recently remained a mystery to me, which was how to manage the complex web of authorization between the objects.

Last year at TPAC, the World Wide Web consortium's conference, I was staying with some people who asked me what I would do if I had unlimited time to work on whatever I wanted. I sheepishly admitted to my dream of a federated social web as a distributed game, and expected to be laughed out of the room. I was surprised to find out that nearly everyone I was working with had some background in this same work and dream. This gave me some hope that I wasn't completely foolish, and the observation that even failure in persuing this ambitious dream would probably result in useful artifacts.

And last year at Rebooting Web of Trust, I hit a big breakthrough. I had the chance to meet Mark S. Miller in person, someone who's work I read but barely understood at the time, and this meeting in some ways changed the direction of my career. For one thing, it lead to us collaborating on the foundation for the ocap-ld specification, which came out of a paper we collaborated on from that event (also available in nicely formatted PDF form). But what I also discovered was that Mark Miller and company had actually built the distributed and secure social network dream in the late 1990s and called it Electric Communities (rare video of it being demonstrated, and a rare video of some of the out-there ideas). What I found out was that they had solved most of the remaining questions about authorization and security through object capabilities, and that was through a pile of object capability patterns built on top of the actor model. While Electric Communities did not survive, its foundation of the the "E" programming language lived on, pulling in many of its good ideas with it. I proceeded to read as much documentation about E and surrounding capability patterns as I could, and this has majorly influenced Goblins' design. (Don't underestimate the depth of ideas on erights.org just because it looks like an ancient Geocities page... it did come from that era after all...)

Another key insight came from discovering the Object-Capability Security in Virtual Environments paper. I won't go into details on this except to say that it's a must-read for this problem domain, with the caveat that it pulls in a lot of terminology baggage from the object capability (aka ocap) community. The ocap community is one of those groups that has so many of the right ideas but which unfortunately is also drowning in its own verbiage, despite true efforts to make the ideas more accessible. We (and I guess I'm part of this group now, so "we" is appropriate) need to do better, but it isn't easy.

Goblins is still in its very early days. Its api is unstable and it surely has bugs (this one in particular I need to deal with, and which even exposed an underlying bug in Racket, which did get fixed quickly because the Racket community is amazing). Please don't build anything production-oriented on top of it yet. That said, I'd love users to try things. Check out the docs, see if they're up your alley.

If you like this kind of work and want to see more of it, consider donating; I don't have a corporate sponsor, so progress is funded by people like you. And keep watching here; more Spritely demos/artifacts/releases on the horizon.