From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Sylvain Beucler Newsgroups: gmane.lisp.guile.user Subject: Re: Long-lived Guile scripts in a mono-threaded game engine Date: Tue, 27 May 2008 10:33:25 +0200 Message-ID: <20080527083324.GA16693@perso.beuc.net> References: <20080526211900.GB14261@perso.beuc.net> <87fxs4yy89.fsf@gnu.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1211877227 1389 80.91.229.12 (27 May 2008 08:33:47 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 27 May 2008 08:33:47 +0000 (UTC) Cc: guile-user@gnu.org To: Ludovic =?iso-8859-1?Q?Court=E8s?= Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Tue May 27 10:34:28 2008 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1K0udW-0001Kp-K1 for guile-user@m.gmane.org; Tue, 27 May 2008 10:34:26 +0200 Original-Received: from localhost ([127.0.0.1]:59539 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K0ucl-0004Gq-8d for guile-user@m.gmane.org; Tue, 27 May 2008 04:33:39 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K0uch-0004GB-2b for guile-user@gnu.org; Tue, 27 May 2008 04:33:35 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K0ucg-0004FE-5l for guile-user@gnu.org; Tue, 27 May 2008 04:33:34 -0400 Original-Received: from [199.232.76.173] (port=50031 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K0ucf-0004FB-UR for guile-user@gnu.org; Tue, 27 May 2008 04:33:33 -0400 Original-Received: from smtp3-g19.free.fr ([212.27.42.29]:43635) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1K0ucZ-0004f8-0U; Tue, 27 May 2008 04:33:27 -0400 Original-Received: from smtp3-g19.free.fr (localhost.localdomain [127.0.0.1]) by smtp3-g19.free.fr (Postfix) with ESMTP id EEAB617B5A6; Tue, 27 May 2008 10:33:25 +0200 (CEST) Original-Received: from localhost.localdomain (unknown [82.238.35.175]) by smtp3-g19.free.fr (Postfix) with ESMTP id BFBA117B54E; Tue, 27 May 2008 10:33:25 +0200 (CEST) Original-Received: from me by localhost.localdomain with local (Exim 4.69) (envelope-from ) id 1K0ucX-0004Mr-1W; Tue, 27 May 2008 10:33:25 +0200 Content-Disposition: inline In-Reply-To: <87fxs4yy89.fsf@gnu.org> X-Operating-System: GNU/Linux User-Agent: Mutt/1.5.17+20080114 (2008-01-14) X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 3) X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:6575 Archived-At: Hi, On Tue, May 27, 2008 at 09:58:46AM +0200, Ludovic Court=E8s 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 avoid= s > > 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). >=20 > 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. >=20 > 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: >=20 > (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)))) >=20 > 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? --=20 Sylvain