Closing big-bang windows

367 views
Skip to first unread message

John Carmack

unread,
Jun 21, 2015, 12:33:07 PM6/21/15
to Racket Users
My son's game has a level editor as well as a game loop, and we switch between them. However, each new big-bang call creates a new window, leaving the previous ones inert on the screen. How can we close the windows?


Matthias Felleisen

unread,
Jun 21, 2015, 1:18:25 PM6/21/15
to John Carmack, Racket Users

It used to be that when you ran a program like this

;; isl+
(require 2htdp/image)
(require 2htdp/universe)

(big-bang 10
(to-draw (lambda (x) (circle (+ (* 10 x) 20) 'solid 'red)))
(on-tick sub1)
(stop-when zero?))

The window would shut down. But people wanted it to stay
open so that they could see the final score of their games etc.

I guess I could add a close-on-stop clauses for programmers
such as your son but it sounds almost like he's ready to move
on to racket proper, as in use the Windowing API directly.

He may also be interested in Jay's variant of 'universe',
which is faster (and comes with sound) or Neil's (experimental)
3D version. I conjecture that they are both more open to extensions
than my teaching versions

-- Matthias





On Jun 21, 2015, at 12:33 PM, John Carmack wrote:

> My son's game has a level editor as well as a game loop, and we switch between them. However, each new big-bang call creates a new window, leaving the previous ones inert on the screen. How can we close the windows?
>
>
> --
> You received this message because you are subscribed to the Google Groups "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Jay McCarthy

unread,
Jun 21, 2015, 2:17:37 PM6/21/15
to Matthias Felleisen, John Carmack, Racket Users
Another option is to arrange that there is only ever a single call to
big-bang and there's a top-level data-type for the different modes of
the game:

World = EditorWorld | PlayerWorld

And when the Editor is ready it returns a Player. This can be a bit
awkward because of the need for a top-level dispatch.

It is slightly nicer in lux (
https://github.com/jeapostrophe/lux/blob/master/scribblings/lux.scrbl
) for a few reasons:

First, when the simulation ends, the window closes.

Second, the Word is more like an object that has its own tick/etc
functions so you don't need the dispatch at the top.

Third, when `fiat-lux' is called from within a call to `fiat-lux' then
the INNER call takes over the window/gui/etc of the OUTER call. This
is especially nice because when the INNER call does "end" then the
value is returned to the call. If you wanted to do that in big-bang,
you'd need to convert your program to CPS.

Here's a simple demo that uses 2htdp's images but doesn't exploit the
inner calling

https://github.com/jeapostrophe/lux/blob/master/examples/val-demo.rkt

And here's another one that uses the dc directly but has the inner
calling thing:

https://github.com/jeapostrophe/lux/blob/master/examples/spin.rkt

lux is definitely more complicated because I expose the input event
objects from Racket directly, but it's fairly painless to convert a
big-bang program to use it.

Jay
--
Jay McCarthy
http://jeapostrophe.github.io

"Wherefore, be not weary in well-doing,
for ye are laying the foundation of a great work.
And out of small things proceedeth that which is great."
- D&C 64:33

Alexis King

unread,
Jun 21, 2015, 2:54:07 PM6/21/15
to Matthias Felleisen, John Carmack, Racket Users
> I guess I could add a close-on-stop clauses for programmers
> such as your son but it sounds almost like he's ready to move
> on to racket proper, as in use the Windowing API directly.

FWIW, despite big-bang’s position as a teaching tool, I much prefer it over using the Windowing API directly, considering it provides a pure interface for working with real-time graphical applications. I like big-bang’s approach to that problem, and I’ve found myself using it many times due to its ease of use. In contrast, racket/gui is frustratingly imperative.

> He may also be interested in Jay's variant of 'universe',
> which is faster (and comes with sound) or Neil's (experimental)
> 3D version. I conjecture that they are both more open to extensions
> than my teaching versions

I’m aware of pict3d/universe, but I admit I haven’t heard of Jay’s version. Is that what lux is? (Either way, it would be nice to get the docs building properly on pkg-build, since currently the build fails.)

Anyway, I think it would be nice to have something like 2htdp/universe that’s aimed at more experienced programmers. If lux is designed to be that, I’ll certainly take a look. Otherwise, would it be worth spending some time figuring out how to generalize and scale the ‘universe’ idiom to be a bit more powerful?

Alexis

Matthew Flatt

unread,
Jun 21, 2015, 6:09:02 PM6/21/15
to John Carmack, Racket Users
The enclosed "big-crunch.rkt" library provides a `big-bang/big-crunch`
form that is the same as `big-bang`, but it closes the window with
`stop-when` produces #t. (I wrote it for my son.)

;; isl+
(require 2htdp/image)
(require 2htdp/universe)
(require "big-crunch.rkt")

(big-bang/big-crunch 10
(to-draw (lambda (x) (circle (+ (* 10 x) 20) 'solid 'red)))
(on-tick sub1)
(stop-when zero?))

big-crunch.rkt

Matthias Felleisen

unread,
Jun 21, 2015, 8:54:43 PM6/21/15
to Alexis King, John Carmack, Racket Users


On Jun 21, 2015, at 2:54 PM, Alexis King wrote:

>> I guess I could add a close-on-stop clauses for programmers
>> such as your son but it sounds almost like he's ready to move
>> on to racket proper, as in use the Windowing API directly.
>
> FWIW, despite big-bang’s position as a teaching tool, I much prefer it over using the Windowing API directly, considering it provides a pure interface for working with real-time graphical applications. I like big-bang’s approach to that problem, and I’ve found myself using it many times due to its ease of use. In contrast, racket/gui is frustratingly imperative.




Yes, many people have told me that and I think it's time for me to factor universe and provide the underlying layer for Racketeers (which means less error checking and more idiomatic syntax). -- Matthias

p.s. You never know what you get when you design a DSL for beginners. Real people may end up liking it.

Neil Toronto

unread,
Jun 21, 2015, 10:18:26 PM6/21/15
to Alexis King, Matthias Felleisen, John Carmack, Racket Users
On 06/21/2015 02:54 PM, Alexis King wrote:
>> I guess I could add a close-on-stop clauses for programmers
>> such as your son but it sounds almost like he's ready to move
>> on to racket proper, as in use the Windowing API directly.
>
> FWIW, despite big-bang’s position as a teaching tool, I much prefer it over using the Windowing API directly, considering it provides a pure interface for working with real-time graphical applications. I like big-bang’s approach to that problem, and I’ve found myself using it many times due to its ease of use. In contrast, racket/gui is frustratingly imperative.
>
>> He may also be interested in Jay's variant of 'universe',
>> which is faster (and comes with sound) or Neil's (experimental)
>> 3D version. I conjecture that they are both more open to extensions
>> than my teaching versions

Absolutely.

> I’m aware of pict3d/universe, but I admit I haven’t heard of Jay’s version. Is that what lux is? (Either way, it would be nice to get the docs building properly on pkg-build, since currently the build fails.)

pict3d/universe supplies `big-bang3d`, which is like `big-bang` but is
slimmed down (e.g. no pad overlay) and takes keyword arguments instead
of special syntax. It also supplies game time and frame count to each
function, and makes explicit guarantees about threading and event order.
And it doesn't try as hard to tell you what you did wrong.

Jay's lux provides an abstract framework for game-like programs. It's
easy to make adapters for different ways to render games that plug into
it. (I've done it for Pict3D, for example.) The best thing going for it
is its generic interface, which saves programmers from having to do
top-level dispatch based on game mode in every callback function.

> Anyway, I think it would be nice to have something like 2htdp/universe that’s aimed at more experienced programmers. If lux is designed to be that, I’ll certainly take a look. Otherwise, would it be worth spending some time figuring out how to generalize and scale the ‘universe’ idiom to be a bit more powerful?

Jay's lux and my `big-bang3d` are both small steps in that direction.
FWIW, while `big-bang3d` is experimental, its current form will remain a
stable subset of the API, and it works well.

I'm working on a `big-bang3d` game intended to expose shortcomings in
universe-style programs when used at a larger scale than in the
classroom. Here are my main criticisms so far:

1. Adding new state is painful. Every time I add a little bit to track
something - a cooldown timer, camera momentum, a list of planes the
player collided against - I have to change a lot of unrelated code.

2. Adding a new game mode (e.g. menus, level editor) involves a lot of
boilerplate.

3. We don't have a good story for sound.

4. Paying the garbage collector can get expensive. Figuring out how to
not pay it so much is next to impossible at the moment.

For #1, I think we need nicer ways to reach deep into heterogeneous data
structures to read from and update them. Refactoring data structures
only goes so far. Game state is a big, messy thing with a lot of
interaction that defies neatly compartmentalized trees.

(It would also be nice to have support for batching all the updates for
performance. This could also make it easy to send state deltas over the
network.)

Having tried Jay's generics solution, I think it nearly solves #2. I
wish generics were better supported in both typed and untyped Racket.

I think we imagine #3 is harder than it really is. Quake III Arena's
engine API basically has just "start/keep playing this," "stop playing
this," and "move the source of this sound here." IMO the only real
design issue is figuring out how programmers name sounds so they can
refer to them later.

(Engineering-wise, we need a mixer running in a separate thread/place
that big bang programs can issue commands to over an async channel.)

#4 is a real-time Racket thing generally. I've managed to make Pict3D
trigger major GCs only occasionally, but only with a lot of guesswork
and behind-the-scenes imperative fakery. It would be nice if users could
avoid both.

Neil ⊥

Alexander D. Knauth

unread,
Jun 21, 2015, 11:10:37 PM6/21/15
to Neil Toronto, Alexis King, Matthias Felleisen, John Carmack, racket users list

On Jun 21, 2015, at 10:18 PM, Neil Toronto <neil.t...@gmail.com> wrote:

> I'm working on a `big-bang3d` game intended to expose shortcomings in universe-style programs when used at a larger scale than in the classroom. Here are my main criticisms so far:
>
> 1. Adding new state is painful. Every time I add a little bit to track
> something - a cooldown timer, camera momentum, a list of planes the
> player collided against - I have to change a lot of unrelated code.

> For #1, I think we need nicer ways to reach deep into heterogeneous data structures to read from and update them. Refactoring data structures only goes so far. Game state is a big, messy thing with a lot of interaction that defies neatly compartmentalized trees.

For this problem, I wonder if using compose-able functional lenses like this would be a good solution:
https://github.com/jackfirth/lenses
http://pkg-build.racket-lang.org/doc/lenses@lenses/index.html


Jay McCarthy

unread,
Jun 22, 2015, 7:25:17 AM6/22/15
to Neil Toronto, Alexis King, Matthias Felleisen, John Carmack, Racket Users
In my existing games, I do two major things. First, I typically use a
giant functional hash table with gensym allocated keys and without the
ability to iterate through them. This gives abstraction and pretty
nice flexibility. The other thing I do is make each entity & system in
the game be a separate cooperative thread, so that I can capture most
of the state in the continuation and the recursive arguments. A really
simple example is here:

https://github.com/jeapostrophe/dos/blob/master/dos/examples/win.rkt

The mouse-tracking-ball uses the recursive argument for its radius and
the decaying-ball uses its continuation to storage where in the
count-down it is.

This all implemented by the DOS package, primarily the "win" library.
http://pkg-build.racket-lang.org/doc/dos/index.html

> (It would also be nice to have support for batching all the updates for
> performance. This could also make it easy to send state deltas over the
> network.)

I'm presently working on an entity-component-system library that
supports abstract state and processors that is compiled to large
homogenous arrays and batch processing. But it's a ways off.

> Having tried Jay's generics solution, I think it nearly solves #2. I wish
> generics were better supported in both typed and untyped Racket.
>
> I think we imagine #3 is harder than it really is. Quake III Arena's engine
> API basically has just "start/keep playing this," "stop playing this," and
> "move the source of this sound here." IMO the only real design issue is
> figuring out how programmers name sounds so they can refer to them later.
>
> (Engineering-wise, we need a mixer running in a separate thread/place that
> big bang programs can issue commands to over an async channel.)

This is how my current sound system works. The main interesting thing
is with the naming of sounds. Rather than naming a sound or getting a
handle returned for it via a function like "create-sound : audio-info
-> sound-name" and being able to move and control it with functions
like "sound-stop! : sound-name -> void" etc. Instead, when you create
a sound you give a function that looks up all the state "create-sound
: (world -> (audio-info x position x playing?)) -> sound-handle" and
then big-bang loop is responsible for calling "sound-update! : sounds
world -> sounds" periodically. This will cause all the inner sounds to
be updated with the new world, which could do something like look for
the new position of the missile in the world to change the position of
the sound.

The library:

https://github.com/get-bonus/get-bonus/blob/master/gb/audio/3s.rkt

The simplest example:

https://github.com/get-bonus/get-bonus/blob/master/games/tennis/main.rkt#L187

> #4 is a real-time Racket thing generally. I've managed to make Pict3D
> trigger major GCs only occasionally, but only with a lot of guesswork and
> behind-the-scenes imperative fakery. It would be nice if users could avoid
> both.

I personally have found this relatively easy to deal with if I try to
think about allocation rather than JUST convenience.

Jay

> Neil ⊥
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



Matthias Felleisen

unread,
Jun 22, 2015, 11:38:43 AM6/22/15
to Jens Axel Søgaard, John Carmack, Racket Users

On Jun 22, 2015, at 11:31 AM, Jens Axel Søgaard <jens...@soegaard.net> wrote:

> John Carmack:
> My son's game has a level editor as well as a game loop, and we switch between them. However, each new big-bang call creates a new window, leaving the previous ones inert on the screen. How can we close the windows?
>
>
> Matthias Felleisen:
> But people wanted it to stay
> open so that they could see the final score of their games etc.
>
> I guess I could add a close-on-stop clauses for programmers
> such as your son but it sounds almost like he's ready to move
> on to racket proper, as in use the Windowing API directly.
>
> If I understand correctly, a manual
>
> (close-all-big-bang-windows)
>
> callable from the REPL would be enough in this case?


This is where teaching comes in, How do you justify a function of NO arguments with the rules of algebra? So far this design guideline has produced the smoothest possible path from pre-algebra courses through Bootstrap, Program By Design, Picturing Programs, HtDP, all the way to 'Hell' (that's my software dev course for juniors). [Even if the programmers/students don't get it, straying from this design principle has always gotten me into trouble eventually.)

-- Matthias


Matthias Felleisen

unread,
Jun 23, 2015, 11:30:30 AM6/23/15
to Jay McCarthy, Neil Toronto, Alexis King, John Carmack, Racket Users

I have for years hoped to find time to think about 'distributing state' over handlers in big-bang because I am perfectly aware of the scaling up limitations. Your hashtable idea might be worth exploring. Tony and I are also considering his actor system as a source of ideas. This may also give us a handle at a special-purpose gc as Tony noted yesterday. But now I am way off stuff I have done, and I don't like to discuss things that I might do so forgive me for this much and I'll stop now -- Matthias

Alexis King

unread,
Jun 23, 2015, 11:42:33 AM6/23/15
to Matthias Felleisen, Jay McCarthy, Neil Toronto, John Carmack, Racket Users
I, for one, thought the idea of “OS” reads and writes from Get Bonus was a neat abstraction, even if it is more or less just functional reads and writes to a giant hash table. Obviously that’s more complicated than would be appropriate for big-bang, but I thought I’d bring it up anyway.

Jens Axel Søgaard

unread,
Jun 23, 2015, 12:52:11 PM6/23/15
to Matthias Felleisen, John Carmack, Racket Users
John Carmack: 
My son's game has a level editor as well as a game loop, and we switch between them.  However, each new big-bang call creates a new window, leaving the previous ones inert on the screen.  How can we close the windows?


Matthias Felleisen: 
But people wanted it to stay
open so that they could see the final score of their games etc.

I guess I could add a close-on-stop clauses for programmers
such as your son but it sounds almost like he's ready to move
on to racket proper, as in use the Windowing API directly.

If I understand correctly, a manual

   (close-all-big-bang-windows)

callable from the REPL would be enough in this case?

/Jens Axel



 
Reply all
Reply to author
Forward
0 new messages