GameLisp is a scripting language for Rust game development.
-
No garbage collection pauses. GameLisp has a unique garbage collector designed specifically for game development. It runs once per frame, every frame, without causing any latency spikes.
-
Seamless Rust API. Integrating GameLisp into a Rust codebase is effortless, thanks to Rust's powerful type system. Installation is trivial - it's just a crate!
-
Memory-safe. GameLisp is implemented entirely in Rust, with very few dependencies. By default, its implementation doesn't use
unsafe
at all. -
Feature-rich. GameLisp has all of the convenience features you might expect from a modern language. Pattern‑matching, iterators, coroutines, macros...
-
Easy entity scripting. GameLisp has a unique object system, built around state machines and mixins, designed specifically for scripting game entities.
If you're interested, take a look at the Getting Started page for more information.
(defstruct Rect
x y w h
(met overlaps? (other-rect)
(let [x y w h] other-rect)
(and (< @x (+ x w))
(< x (+ @x @w))
(< @y (+ y h))
(< y (+ @y @h)))))
(def paddle-speed 220)
(def paddle-height 40)
(def paddle-start-y (-> play:height (- paddle-height) (/ 2)))
(def left-paddle (Rect
(x 10)
(y paddle-start-y)
(w 6)
(h paddle-height)))
(def right-paddle (Rect
(x (- play:width 16))
(y paddle-start-y)
(w 6)
(h paddle-height)))
(def ball-start-x (-> play:width (/ 2) (- 3)))
(def ball-start-y (-> play:height (/ 2) (- 3)))
(def ball (Rect
(x ball-start-x)
(y ball-start-y)
(w 6)
(h 6)))
(def ball-dx 0)
(def ball-dy 0)
(defn play:update (dt)
; update the paddles
(for (paddle up-key down-key) in `((~left-paddle w s)
(~right-paddle up down))
(when (play:down? up-key)
(dec! [paddle 'y] (* dt paddle-speed)))
(when (play:down? down-key)
(inc! [paddle 'y] (* dt paddle-speed)))
(clamp! [paddle 'y] 0 (- play:height paddle-height)))
; update the ball
(when (and (== ball-dx ball-dy 0)
(any? play:pressed? '(w s up down)))
(= ball-dx (* (rand-pick -1 1) (rand 170 210)))
(= ball-dy (* (rand-pick -1 1) (rand 50 100))))
(inc! [ball 'x] (* dt ball-dx))
(inc! [ball 'y] (* dt ball-dy))
(when (< [ball 'y] 0)
(= ball-dy (abs ball-dy)))
(when (>= (+ [ball 'y] [ball 'h]) play:height)
(= ball-dy (- (abs ball-dy))))
(when (or (and (.overlaps? ball left-paddle) (< ball-dx 0))
(and (.overlaps? ball right-paddle) (> ball-dx 0)))
(= ball-dx (- (* ball-dx (rand 1.03 1.08))))
(inc! ball-dy (rand 50 -50))
(clamp! ball-dy (- (abs ball-dx)) (abs ball-dx)))
(unless (<= 0 [ball 'x] play:width)
(= [ball 'x] ball-start-x)
(= [ball 'y] ball-start-y)
(= ball-dx 0)
(= ball-dy 0))
; rendering
(let midnight-blue '(25 25 112))
(let turquoise '(64 224 208))
(play:fill 0 0 play:width play:height ..midnight-blue)
(play:fill ..[ball '(x y w h)] ..turquoise)
(play:fill ..[left-paddle '(x y w h)] ..turquoise)
(play:fill ..[right-paddle '(x y w h)] ..turquoise))
The above code implements a simple game. Give it a try on the playground!