My son's game in Racket

37,840 views
Skip to first unread message

John Carmack

unread,
Aug 24, 2015, 12:28:07 PM8/24/15
to Racket Users

We “released” my 10 year old son’s game that was done in Racket: www.1k3c.com

 

I’m still taking a little heat from my wife for using an obscure language instead of something mainstream that is broadly used in industry, but I have nothing but good things to say about using Racket and DrRacket for a beginning programmer, and highly recommend it.

 

I can’t recommend 2htdp/universe for this sort of thing, though.  I had to drop to the native GUI bitmaps for performance reasons, hack around the lifecycle to support a separate editor window, and I still don’t know how to make the Quit menu item actually exit the app on the Mac version.

 

I completely understand the reasoning for the way 2htdp/universe is built, and saying that a “real” project should use the grown-up APIs is fine, but the evolution from making a little animation to controlling it somehow to fleshing it out into a game is so natural that recommending a fairly big rewrite is unfortunate.

 

I’m a big booster of functional programming, but I’m not sure that the functional drawing paradigm ever really sank in while my son was working with it, rather it felt like you just drew everything backwards with missing parenthesis at the end.  I suspect that using the standard imperative GUI drawing code will make perfect sense to him.

 

I’m not sure yet if we are going to migrate to the regular GUI code for upcoming work, or jump all the way to OpenGL so he can learn the joys of “Why is the screen all black?”

 

Matthias Felleisen

unread,
Aug 24, 2015, 1:15:37 PM8/24/15
to John Carmack, Racket Users
Thanks for sharing. You can let Ryan know that he has his first grandma user, and in that mode, I managed to get a few extra lives.

A couple of comments:

-- In the past, some teachers have shared similar 'world/universe' games with me with similar performance.
-- If your son is in middle school, he should see "pre-algebra" soon, and you may wish to revisit the initial drafts of the game then.
---- You can show directly how "pre-algebra" applies and how the game is basically written in pre-algebra.
-- Learning FP and the connection to math may work better if you actually use the design recipe from HtDP [2e].
---- I know of a child who worked through this book between the ages of 8 and 12 and had a grand time with math and programming then.
-- And finally, I am curious about your wife's comment.
---- What's so objectionable to learning fundamentals first and commercial things when you need to go professional?
---- Your son used C#/Unity last year. Was it much easier?

I have acknowledged the lack of a growth path from 'world' to a performant model in the past, and I will continue to admit the problem.

-- Matthias




Jens Axel Søgaard

unread,
Aug 24, 2015, 1:33:34 PM8/24/15
to John Carmack, Racket Users
2015-08-24 18:27 GMT+02:00 John Carmack <jo...@oculus.com>:

We “released” my 10 year old son’s game that was done in Racket: www.1k3c.com


Tell him, he has done a great job.

It has the right game feel. I liked both how the levels progressed slowly in difficulty
and that there were so many of them. 

/Jens Axel




John Carmack

unread,
Aug 24, 2015, 1:43:38 PM8/24/15
to Matthias Felleisen, Racket Users
The performance problems were related to the larger scrolling worlds. The H2DP versions got slower the more clouds were in the maps. As an aside, what drove the 20-something fps tic rate for H2DP, versus 30 for an every-other-vsync update?

He is already through Algebra 2, so he gets functions. He didn't have any difficulty applying the functional image model, but when you have 20 lines of text drawing composed together, it really looks like you are just drawing things one after another, but backwards. The cases where it has value, like building a character up out of multiple things, then placing it somewhere in the world, tend to be the minority of operations compared to just drawing independent elements on the screen.

My wife managed programmers for years, and she has opinions about pragmatic developers, which usually involve Java or C++. I tend to think that worrying about our 10 year old's future career prospects is a bit premature, and want to focus on developing abstract programming skills. :-)

Unity/C# can be incredibly rewarding, but the entire ecosystem almost drives you away from programming as a beginner -- find the right script on the asset store and figure out how to configure it in the editor, rather than reinventing the wheel and writing it yourself.

One of the non-obvious things that I think is beneficial with DrRacket is that it has an approachable complexity level. Dropping a newbie into Eclipse or MonoDevelop makes them feel like they are walking around in a byzantine museum, afraid to touch things, while DrRacket feels closer to old-school personal computers where you felt like you were in command of the machine.

David Grenier

unread,
Aug 24, 2015, 2:13:56 PM8/24/15
to Racket Users, jo...@oculus.com
Not clear what was meant both times you wrote "backwards" are you referring to the lisp-style function call? Something that could be alleviated by say F#'s pipe forward operator?

let (|>) a f = f a

or Clojure's -> macro?

Joel McCracken

unread,
Aug 24, 2015, 2:18:34 PM8/24/15
to John Carmack, Racket Users
FYI, I think the Mac version is out of date. Dropbox says the mac
installer file is two weeks old, and the windows version is a few
hours old.
> --
> 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.

John Carmack

unread,
Aug 24, 2015, 2:32:39 PM8/24/15
to David Grenier, Racket Users
The idea that you functionally compose images like this:

(place-image image-1 x y
(place-image image-2 x y
(place-image image-3 x y)))

Which draws image1 on top of image2 on top of image 3, which is backwards from the "painters order" that would draw image 3, then image 2, then image 1.

This imperative, side-effect-ing code is a little less clear to a beginner with the OOP and DC concepts, but It better represents what actually happens, and it is much easier to modify the code without worrying about the nesting.

(send dc draw-bitmap imag3 x y)
(send dc draw-bitmap imag2 x y)
(send dc draw-bitmap imag1 x y)
--
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://urldefense.proofpoint.com/v1/url?u=https://groups.google.com/d/optout&k=ZVNjlDMF0FElm4dQtryO4A%3D%3D%0A&r=Kjg6LltY9QjkipKooaVldA%3D%3D%0A&m=HArZE0M9OqU4wspKLzQzG6N5gO9ncSxPP9qVzkUgoVU%3D%0A&s=b451faca736dc42c554f148983e7279865ef32be9ddf2df75f5c88c15dd34a73.

Joel McCracken

unread,
Aug 24, 2015, 2:40:33 PM8/24/15
to John Carmack, David Grenier, Racket Users
This would be where I would reach for a let* to handle intermediate
results, because code like this is very awkward.
> For more options, visit https://groups.google.com/d/optout.

Alexander D. Knauth

unread,
Aug 24, 2015, 2:48:53 PM8/24/15
to John Carmack, Joel McCracken, David Grenier, Racket Users
Or something like this, with the rackjure package:
(require rackjure/threading 2htdp/image)
(~>> background-img
(place-image image-1 x y) ; the background-img will be inserted as the last argument, because that's what ~>> does
(place-image image-2 x y) ; the background + image-1 will be inserted as the last argument
(place-image image-3 x y) ; and so on
...)
Or if you don't want to use rackjure, then with let* it would be:
(let* ([img background-img]
[img (place-image image-1 x y img)]
[img (place-image image-2 x y img)]
[img (place-image image-3 x y img)]
...)
img)

Rickard Andersson

unread,
Aug 24, 2015, 2:51:31 PM8/24/15
to John Carmack, David Grenier, Racket Users
I don't know how much you involve yourself in the actual making of things
(it might be a principle of yours to leave everything practical to your
son and to only help with concepts), but couldn't it be useful to simply
make a macro like a `(place-images* ([imag1 x y] ...))` or the like? Maybe
it's one of those "now you have two problems!" type of situations and not
suitable for the context, I don't know.
> For more options, visit https://groups.google.com/d/optout.
>

François Beausoleil

unread,
Aug 24, 2015, 3:40:42 PM8/24/15
to Racket Users, jo...@oculus.com
Hello John,

Thanks for sharing. Played a few levels and had fun :)

I have a 10 year old daughter. Did your son show interest in programming or did you initiate him yourself? I remember I started when I was 10 years old as well. I'd like to introduce my daughter to programming too, and was wondering when the right time would be. I tried Logo last year, but after 5 minutes, she didn't see any interest in it.

Have a great day!
François Beausoleil

John Carmack

unread,
Aug 24, 2015, 3:51:44 PM8/24/15
to François Beausoleil, Racket Users
I would love it if he found it endlessly fascinating and spent all day programming on his own, but he does need a bit of a push from mom and dad. He enjoys it, but given the choice, he would still rather play games than make them :-)

He reacted very positively to the initial "intro to racket with pictures", which was a contributing factor to settling on Racket. Java / C# work seemed to feel more like homework, but changing numbers and colors in the REPL had him smiling and excited.

-----Original Message-----
From: François Beausoleil [mailto:francois....@gmail.com]
Sent: Monday, August 24, 2015 2:41 PM
To: Racket Users
Cc: John Carmack

Paulo Faustino

unread,
Aug 24, 2015, 4:12:10 PM8/24/15
to Racket Users, jo...@oculus.com
On Monday, August 24, 2015 at 1:28:07 PM UTC-3, John Carmack wrote:
> We “released” my 10 year old son’s game that was done in Racket:
> www.1k3c.com

I tried to run without installing Racket and it didn't work, then I installed Racket x64 and it still won't run, here's the error:

"Failure: cannot load DLL - C:\Program Files\Racket\lib\.\libracket3m_9yey68.dll".

Windows 10 x64 - nVidia GTX770 - 12GB Ram

Paulo Faustino

unread,
Aug 24, 2015, 4:13:50 PM8/24/15
to Racket Users, jo...@oculus.com
The actual file on my hard drive is : c:\Program Files\Racket\lib\libracket3m_9yeyy0.dll

John Clements

unread,
Aug 24, 2015, 4:43:45 PM8/24/15
to John Carmack, David Grenier, Racket Users

> On Aug 24, 2015, at 11:32 AM, John Carmack <jo...@oculus.com> wrote:
>
> The idea that you functionally compose images like this:
>
> (place-image image-1 x y
> (place-image image-2 x y
> (place-image image-3 x y)))
>
> Which draws image1 on top of image2 on top of image 3, which is backwards from the "painters order" that would draw image 3, then image 2, then image 1.
>
> This imperative, side-effect-ing code is a little less clear to a beginner with the OOP and DC concepts, but It better represents what actually happens, and it is much easier to modify the code without worrying about the nesting.
>
> (send dc draw-bitmap imag3 x y)
> (send dc draw-bitmap imag2 x y)
> (send dc draw-bitmap imag1 x y)

Working with my children and first-year students I see this problem all the time; probably at least half of the kids I work with feel this way.

After thinking about it a bit, though, I see that the fundamental problem here isn’t functional vs. imperative; it has to do with operator order. So, for instance, I claim that my students would be (relatively) happy if they got to write

((image3
place-image x y image2)
place-image x y image1)

I don’t have a good answer here—many people have tried to build infix syntax for Scheme & Racket, and none of them has yet caught on. Perhaps Alex Knauth’s macro is the right thing, but what’s really needed (it seems to me) is a solution with widespread acceptance.

John



Matthias Felleisen

unread,
Aug 24, 2015, 5:27:29 PM8/24/15
to François Beausoleil, Racket Users

On Aug 24, 2015, at 3:40 PM, François Beausoleil <francois....@gmail.com> wrote:

> Le lundi 24 août 2015 12:28:07 UTC-4, John Carmack a écrit :
>> ...
>
> Hello John,
>
> Thanks for sharing. Played a few levels and had fun :)
>
> I have a 10 year old daughter. Did your son show interest in programming or did you initiate him yourself? I remember I started when I was 10 years old as well. I'd like to introduce my daughter to programming too, and was wondering when the right time would be. I tried Logo last year, but after 5 minutes, she didn't see any interest in it.
>
> Have a great day!
> François Beausoleil
>
> --
> 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.


Francois, since you are on the Racket mailing list, may I recommend the Bootstrap material? It is a restricted version of the "Universe" approach as John calls it, tailored to 10-12 year olds who are just finding out about expressions and functions (in the US. Does not apply to my experience with European schools.) You can play with this in DrRacket off-line or if you prefer you can use WeScheme as an on-line tool with this approach. The point is to reinforce math (a traditional school topic) with programming and to use this kind of programming as a "gateway" for real programming (in a mostly functional style. None of us are purists; we are American pragmatists.)

See bootstrap-world.org

-- Matthias

Aaron Hamilton

unread,
Aug 24, 2015, 5:38:32 PM8/24/15
to Racket Users, matt...@ccs.neu.edu, jo...@oculus.com
On Monday, August 24, 2015 at 5:43:38 PM UTC, John Carmack wrote:
> He didn't have any difficulty applying the functional image model, but when you have 20 lines of text drawing composed together, it really looks like you are just drawing things one after another, but backwards.

(define (pipe . d) (apply compose (reverse d)))

;-)

Matthias Felleisen

unread,
Aug 24, 2015, 5:52:22 PM8/24/15
to John Carmack, Racket Users

On Aug 24, 2015, at 2:32 PM, John Carmack <jo...@oculus.com> wrote:

> The idea that you functionally compose images like this:
>
> (place-image image-1 x y
> (place-image image-2 x y
> (place-image image-3 x y)))
>
> Which draws image1 on top of image2 on top of image 3, which is backwards from the "painters order" that would draw image 3, then image 2, then image 1.
>
> This imperative, side-effect-ing code is a little less clear to a beginner with the OOP and DC concepts, but It better represents what actually happens, and it is much easier to modify the code without worrying about the nesting.
>
> (send dc draw-bitmap imag3 x y)
> (send dc draw-bitmap imag2 x y)
> (send dc draw-bitmap imag1 x y)


This is a serious wart, but I didn't expect that when I read "backwards."

In HtDP/ISL, I use

[1] You can develop s0 ... s3 at the top-level, when you like them you esc-k, ctrl-y place them into a local:

(define (render.v1 w)
(local ((define s0 (empty-scene 100 100))
(define s1 (place-image (circle 30 'solid 'yellow) 5 20 s0))
(define s2 (place-image (rectangle 10 20 'solid 'blue) 90 90 s1))
(define s3 (place-image (triangle 100 'solid 'red) 90 10 s2)))
s3))

[2] Or you can use let* as someone else pointed out

(define (render.v2 w)
(let* ((s (empty-scene 100 100))
(s (place-image (circle 30 'solid 'yellow) 5 20 s))
(s (place-image (rectangle 10 20 'solid 'blue) 90 90 s))
(s (place-image (triangle 100 'solid 'red) 90 10 s)))
s))

[3} But my favorite is this, when i try to explain kids abstraction and the advantage of having values around instead of effects:

(define (render.v3 w)
(foldr (lambda (x s) (apply place-image- s x)) background pieces))

[4] We do need a for/image so that #lang racket programmers can do even better.

;; --- somewhere else:

(define background (empty-scene 100 100))

(define pieces
`((,(circle 30 'solid 'yellow)
,(rectangle 10 20 'solid 'blue)
,(triangle 100 'solid 'red))))

Erik Bernoth

unread,
Aug 25, 2015, 5:53:04 AM8/25/15
to Racket Users, jo...@oculus.com
Yes, child learns to program games -> awesome! But what I will probably never understand is why you game developers always live on planet Windows. You guys are also programmers, but I think there is no other programmer population that has such a high percentage of Windows people. Even embedded world has understood now (thanks to Raspberry, I guess) that there is another world that was built by programmers for programmers. It's like being a professional Formula 1 driver but only using bikes, because most people who pay tickets to watch Formular 1 are bike drivers as well.

Why am I even ranting? There's a new kid in the block, just getting introduced to how the world of programming looks like. He can grow up in this world were he can code and understand every little bit of his system, hacking his desktop manager with 15, and writing a new process handling with 21. Or he can live in a world were between UEFI starting the kernel and the API in his high level, feature rich IDE there's only magic and he will think he's not supposed to understand it. Which kind of kids do we want to have?

(PS: I didn't mention a specific distro or kernel here, because every open one is actually fine. Doesn't have to be the same as mine.)

Mr Susnake

unread,
Aug 25, 2015, 9:59:43 AM8/25/15
to Racket Users, jo...@oculus.com
Good day. Thank you for this game.
I found one little bug:
I have "Windows 10" and "das keyboard model s" and when i want to press "G" or "T", or "H" it's doesn't work.

Jens Axel Søgaard

unread,
Aug 25, 2015, 10:03:43 AM8/25/15
to Mr Susnake, Racket Users, John Carmack
Hi,

Does G, T, and H work for you in DrRacket ?

/Jens Axel


--
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.



--
--
Jens Axel Søgaard

Message has been deleted

Jens Axel Søgaard

unread,
Aug 25, 2015, 10:16:06 AM8/25/15
to Mr Susnake, Racket Users
DrRacket is the programming environment used to build the game. 

Download it here:     http://download.racket-lang.org/

Test the keys and let us know if they work or not.

/Jens Axel



2015-08-25 16:08 GMT+02:00 Mr Susnake <sus...@gmail.com>:
Thank you for reply.
DrRacket? What is it?


--
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.

Greg Hendershott

unread,
Aug 25, 2015, 6:33:20 PM8/25/15
to Erik Bernoth, Racket Users, John Carmack
Although I'm not a game developer, I have a past life developing
music/audio software commercially. We developed on Windows because
that's where the vast majority of the customers were, and that was
really the end of the discussion.

Also, although I'm about to exaggerate, I think that for much audio
and game software, the operating system is a bug not a feature. :) It
stands between you and optimal use of the hardware, and can give you
as grief as well as help. So, even assuming you rank OSs on some
scale of relative goodness, on an absolute scale you start to feel
they all sort of suck. :) From the point of view of writing low-level
parts of some kinds of software.

Having said all that, these days I use Ubuntu, Emacs, Racket, and
everything I code is open source or free software. Shrug.

Anyway, an interesting aspect of using Racket for this is precisely
the agnostic, cross-platform GUI support.

Joachim Monteur

unread,
Aug 26, 2015, 9:12:43 PM8/26/15
to Racket Users, jo...@oculus.com
On Monday, August 24, 2015 at 1:28:07 PM UTC-3, John Carmack wrote:
Linux support :c
Reply all
Reply to author
Forward
0 new messages