unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Sylvain Beucler <beuc@beuc.net>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: guile-user@gnu.org
Subject: Re: Long-lived Guile scripts in a mono-threaded game engine
Date: Tue, 27 May 2008 10:33:25 +0200	[thread overview]
Message-ID: <20080527083324.GA16693@perso.beuc.net> (raw)
In-Reply-To: <87fxs4yy89.fsf@gnu.org>

Hi,

On Tue, May 27, 2008 at 09:58:46AM +0200, Ludovic Courtès wrote:
> > Scripts last more than a single game loop. They are not basic scripts
> > that describe what happens in a single engine step; instead they
> > describe what happens in the story.
> >
> > For example, a game introduction will create sprites on the screen,
> > move them around, make them say lines that the user can read (or pass
> > using [space]), etc.
> >
> > That script can also change the current screen (which kills all other
> > scripts in the current script).
> >
> > Multiple scripts can run in a single screen, but they run the one
> > after the other, not in parallel. The order/priority is known.
> >
> > Scripting is essentially frozen during the screen refresh. This avoids
> > putting mutexes everywhere.
> >
> >
> >
> >
> > How could I do something similar with Guile? I didn't find a way to
> > make a guile script pause (and return to the caller).
> 
> IIUC, "scripts" are only invoked via hooks, e.g., the engine wants to
> ask them to do something specific.  If that is the case, it suffices to
> not invoke the script.
> 
> Surely you can implement coroutine-like behavior, either using `call/cc'
> (but that is going to be prohibitively expensive), or using explicit
> continuation-passing style or similar.  For instance, when a hook is
> called by the engine, it would systematically return a thunk (a
> zero-argument procedure) that the engine would later invoke.  Example:
> 
>   (define (my-hook action)
>     (let ((stuff (do-some-computation action)))
>       (lambda ()
>         ;; This will be executed at some later point, when the engine
>         ;; feels like invoking it.
>         (do-the-remaining-computation stuff))))
> 
> Does this help?

Ok, so what I'm looking for isn't supported natively :/


Here's a sample script (very close to the C bindings, for a start):

(define (hit)
  (if (> (sp_gethitpoints (current_sprite)) 10)
    (begin
      (sp_sethitpoints (current_sprite) (- (sp_hitpoints (current_sprite)) 10))
      (dialog1))
    (begin
      (say_stop "ARRRRrr.." (current_sprite))
      (sp_kill (current_sprite) 0)
      (say_stop "Uh, I was supposed to protect him, not kill him!" 1)))
  (set_honour! (- (get_honour) 1)))

(define (dialog1)
  (say_stop "Why are you hitting me, player?" (current_sprite))
  (say_stop "Uh, sorry I won't do that again" 1))


Now every time we see a (say_stop), the script will pause for 2
seconds, so the player can read the text.


If I use CPS, this means I'll have to rewrite all my scripts in CPS
style. This would be pretty cumbersome. This is supposed to introduce
people to the beautiful world of scheme, not scare them to death ;)


call/cc has another issue: how do I return? Let's say I'm in the
middle of (dialog1) and I need to stop the script. Maybe with a set of
double continuations: one continuation at the top level to return to
the point before I called the initial procedure (which would stops the
script); and another one that is set at each (say_stop) to return to
the following line (to resume the script). Hopefully this is not as
inefficient as you suggested.


Maybe I'm missing a more simple solution?

-- 
Sylvain




  reply	other threads:[~2008-05-27  8:33 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-26 21:19 Long-lived Guile scripts in a mono-threaded game engine Sylvain Beucler
2008-05-27  7:58 ` Ludovic Courtès
2008-05-27  8:33   ` Sylvain Beucler [this message]
2008-05-27 13:20     ` Ludovic Courtès
2008-05-27 16:14       ` Sylvain Beucler
2008-05-27 18:08         ` Ludovic Courtès
2008-05-27 19:57           ` Sylvain Beucler
2008-05-27 20:30             ` Clinton Ebadi
2008-05-27 18:19         ` Clinton Ebadi
2008-05-27 21:49           ` Neil Jerram
2008-05-27 13:42     ` Paul Emsley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080527083324.GA16693@perso.beuc.net \
    --to=beuc@beuc.net \
    --cc=guile-user@gnu.org \
    --cc=ludo@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).