Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

JavaScript based Lisp?

A topic by oofoe created Sep 23, 2021 Views: 491 Replies: 11
Viewing posts 1 to 7
Submitted

I normally use Racket, but I'm tired of people not being able to play my games because I can only compile for Windows, and then Windows flags them as viruses... 

So, in hopes of getting more ratings, I'm looking to do my next project in the browser. I'm aware of the Virtual Consoles like TIC-80, but would like to use the browser resources more directly. Can anyone recommend a good JavaScript based Lisp? Or something that compiles usefully to JavaScript?

Right now, I'm looking at https://kybernetikos.github.io/Javathcript/. It seems relatively straightforward and it has an interface that should let me use standard JavaScript libraries if I need to.

Thanks!

Jam HostSubmitted

FWIW I’ve never had trouble running your games on Debian. All it takes is sudo apt install racket and then it runs fine.

Submitted (1 edit)

Glad it worked for you! Out of curiosity, did the audio for Zode Trip work correctly also?

My main problem is I can't really provide support for platforms that I don't have access to and Windows is making it really hard for people to just run a program (for valid reasons, but still a bother for this kind of thing).

(+1)

Maybe you can use Parenscript.

Submitted(+1)

I would have to jam my head into Common Lisp again, but it does seem supported and mature. If I can easily export the code so it can run standalone (statically serviced by the itch.io server) that could work. I'll check it out! Thanks!

(1 edit)

RacketScript is under active development and has a really friendly team

There was a flappy-birds demo game but I can’t find it right now

https://github.com/racketscript/racketscript

Wow there is tetris and 2048 and flappy birds on the Playground http://www.racketscript.org/#example/flappy-birds

(+1)

another option is Urlang

The author describes it as ‘JavaScript with sane syntax ‘  

That syntax is of course lispy ;)

There is even an example game!


space-invaders: https://github.com/soegaard/urlang/tree/master/urlang-examples/space-invaders


https://github.com/soegaard/urlang

Submitted

Wow! Thanks for the pointer! This is almost /exactly/ what I was hoping for! 

Note in the space invaders example, maybe something in the latest versions of Dr Racket isn't playing well with the compiler, but it won't allow you to use things like "<=" or ">" in an n-ary way, that is, with multiple arguments, e.g. "(<= 40 x (+ base.x 99))". You have to break the expressions up into something like "(or (<= 40 x) (<= x (+ base.x 99)))". Once I fixed that sort of thing in the Space Invaders example it launched and ran perfectly in the browser.

Submitted

Urlang is pretty nice! There's no format function but most other things work the way I expect them to, and the interface with JavaScript libraries is pretty easy to get along with. This is an implementation of a game loop from a JavaScript game tutorial page and it was pretty straightforward:

#lang at-exp racket
; Implementation of browser game loop from this tutorial:
; https://spicyyoghurt.com/tutorials/html5-javascript-game-development/create-a-pr...
(require urlang urlang/for urlang/extra syntax/parse syntax/stx racket/syntax)
(current-urlang-run?                           #f) ; run using Node?              No: use browser
(current-urlang-echo?                          #t) ; print generated JavaScript?  Yes
(current-urlang-console.log-module-level-expr? #t) ; print top-level expression?  Yes (see console)
(current-urlang-beautify?                      #t) ; invoke js-beautify
(urlang
 (urmodule game-test
   (import alert console this Math isFinite Object window document Date)
   (define context #f) ; Needs to be "global".
   (define timestamp-old #f)
   
   (define (init)
     (let* ((canvas (document.getElementById "the-canvas")))
       (:= context (canvas.getContext "2d")))
     (window.requestAnimationFrame game-loop))
   
   (define (game-loop timestamp)
     (let* ((seconds-passed  (/ (- timestamp timestamp-old) 1000))
            (fps             (Math.round (/ 1.0 seconds-passed)))
            )
       (:= timestamp-old timestamp)
       (:= context "fillStyle" "#fff")
       (context.fillRect  0 0  200 100)
       (:= context "font" "25px Arial")
       (:= context "fillStyle" "black")
       (context.fillText (+ "FPS: " fps) 10 50))
           
     (draw)
     (window.requestAnimationFrame game-loop))
   
   (define (draw)
     (:= context "fillStyle" (if (< 0.5 (Math.random)) "#ff8080" "#0099b0"))
     (context.fillRect  0 100  256 256))
   (init)
))
(define (generate-html)
  @~a{
 <!DOCTYPE html>
 <html lang="en">
   <head> <meta charset="utf-8">
          <title>Game Test</title>
  </head>
  <body>   
     <h1>Game Test</h1>
     <p>Instructions could go here...</p>
     <p><canvas id="the-canvas" width="640" height="480" tabindex="1"/></p>
     <script>@file->string{game-test.js}</script>
 </body>
 </html>})
(require net/sendurl)
(send-url/contents (generate-html))

The "Invaders" example has a Big-Bang style game loop, but I had already started trying to implement this with Javathcript and figured I'd carry it on here.

Submitted(+3)

If you’re still looking, I’d highly recommend ClojureScript :P

Submitted

Just wanted to follow up and thank everybody for their suggestions. As you may know I went for Urlang, since it fit into Racket, which I was already using, and didn't require that I install Node.js (not a fan...).

The reason why I was looking to run it in the web browser was because I wanted to lower the barrier for people to play and rate my games. It turned out even better than I hoped -- nearly everyone eligible was able to take a look. So I did get lots of ratings!

Next time, I'll work on getting better ones! ; - )