TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Ask YC: Game programming in Lisp - is it possible?

37 点作者 gameprogrdr大约 16 年前
Dear HN,<p>I have been programming small games in Java for the past 3 years or so and would like to expand my horizons by learning functional programming.<p>Is it possible to make games using something like Lisp (or another functional language)? Would there be any benefits as opposed to OOP?<p>For instance: say I want to make a pacman game. In java, you just have a bunch of objects that keep their state and thus globally keep the state of the game. Then you check for collisions etc. But in Lisp, you don't have state - so would that be possible to make pacman purely functionally? If so, how? And would there be any benefits?

26 条评论

silentbicycle大约 16 年前
You can have state, several styles of OO, or even the worst sort of imperative spaghetti code in Lisp. It's not a pure functional language like Haskell -- it doesn't force you to write functionally, it just has excellent support for using FP when it suits it the problem. The design of Scheme (a Lisp dialect) <i>encourages</i> functional programming, but it's mostly via things like naming conventions -- functions which mutate state end in exclamation marks (set!), for example. You may consider this nagging, but it's easy to ignore. It's not a bad idea to know which parts of your program depend on mutating state, though.<p>Good libraries, particularly multimedia ones, will be <i>very</i> important. Chicken Scheme has a great library collection (<a href="http://www.call-with-current-continuation.org/eggs/" rel="nofollow">http://www.call-with-current-continuation.org/eggs/</a>) and works well with C. (Chicken compiles Scheme to C.) Other people here strongly recommend PLT Scheme, though I haven't personally used it much.<p>For learning functional programming in Lisp, I'd recommend starting with <i>The Little Schemer</i>. After that, <i>The Seasoned Schemer</i> and/or <i>SICP</i>.<p>I would also consider Lua under those circumstances. Game programming is one of its strongest areas, and IMHO it is a very practical and well-designed language. (Lua and Scheme are, by far, my favorites.) You can also do FP in Lua, though it's not really emphasized, so Scheme is better suited to learning it.
评论 #516893 未加载
icosahedron大约 16 年前
You can easily write games in Lisp. Since you write for the JVM, you may want to look at Clojure (<a href="http://clojure.org/" rel="nofollow">http://clojure.org/</a>), since it runs on the JVM and gives you access to the libraries you've already been using.<p>There are also ABCL (Common Lisp) and SISC (Scheme) if you want something standard that still runs on the JVM.
评论 #517224 未加载
feijai大约 16 年前
I don't know how to say this without sounding like a troll, so I'll just come out and say it: the people who have responded to your question so far sound like they know a lot about Lisp or functional programming and rather little about games.<p>You came to HackerNews, where all the functional programming boosters hang out (myself included) and asked: can I use functional languages for X? What, were you expecting an unbiased answer? To HackerNews, functional programming can do X optimally, forall X.<p>All languages have tradeoffs, though it sometimes seems like we have yet to face up to the tradeoffs in functional programming. But in truth, functional programming kinda sucks for games, and the more functional it gets (that is, as it approaches Haskell), the more it sucks. Because game logic is all about the one thing that pure functional programming disdains with all its heart: global internal state and side effects. The purer you get the more you have to jump through hoops to manage this kind of stuff. So IMHO you're really asking: can I learn a functional programming language by coding something which functional programming is fairly hostile? And people here are responding: sure, you'll love it! It's perfect for you!<p>Also note that real game programming is also often about speed and soft real-time guarantees. Sure, games often have a high-level scripting language in which certain gameplay elements are written. Lua, for example, is one popular choice. Variations on Javascript are another. But if you're looking to <i>write a game</i> in a programming language, and need to eek out that extra bit of cycles to do something nifty, most of the languages here are bad bad choices. This is probably not something you care about since you're just looking to learn, which I applaud. But it does tell me that boosterism is in effect when people recommend Lua and Clojure and ABCL and SISC for game programming that they've not considered, and they don't bother to tell you that these languages are quite slow, for an environment (games) where speed really matters.<p>So if you're trying to learn a functional language by doing a game, I'd pick the least hostile functional language that has highly portable graphics and event support and which is decently fast. Ordinarily I'd say CommonLisp, but ABCL's not there yet. One language in this category is Kawa, a JVM scheme which can be optimized to run at a decent fraction of Java. PLT might be another choice: it's not super fast but has very strong and portable libraries.
评论 #518634 未加载
woid大约 16 年前
Abuse game logic was programmed in Lisp. This was the first time I saw Lisp in a commercial game.<p><a href="http://en.wikipedia.org/wiki/Abuse_(computer_game)" rel="nofollow">http://en.wikipedia.org/wiki/Abuse_(computer_game)</a><p>Any other examples?
评论 #516869 未加载
dlweinreb大约 16 年前
Take a look at InspireData (<a href="http://www.inspiration.com/InspireData" rel="nofollow">http://www.inspiration.com/InspireData</a>). It is entirely written in Common Lisp (<a href="http://www.lispworks.com/success-stories/inspiredata.html" rel="nofollow">http://www.lispworks.com/success-stories/inspiredata.html</a>). The creators of InspireData used Lisp for its high productivity and ease of development.It uses native menus, drop-downs, and so on, and is uses OpenGL. The customers never know it's written in Lisp. There is no problem at all with garbage collection (i.e. no pauses that anyone ever notices).<p>It's pretty obvious that since you can do this, a game like PacMan can also be done. I don't see any obstacle to writing 3D games. Common Lisp has been used for a huge range of kinds of application.<p>If you're looking for a languages with no side-effects in the same sense as in Haskell, the Clojure dialect of Lisp is well worth looking at.
snprbob86大约 16 年前
Quite a few large games have (or still do) use Lisp or Lisp-like languages for scripting.<p>I work only a few offices away from the Xbox developer support team, so I've heard a few war stories about game scripting. Artists and designers at one huuuuge studio (I won't mention their name) have been using Lisp for runtime tweaking of weapon, AI, and vehicle behavior (among other things) for well over a decade without even knowing that it is Lisp.<p>Naughty Dog used their own GOAL (Game Oriented Action Lisp) for Jak and Daxter, which you can read all about at <a href="http://www.gamasutra.com/features/20020710/white_02.htm" rel="nofollow">http://www.gamasutra.com/features/20020710/white_02.htm</a><p>I think the bottom line is that you need to use raw C/C++ for the fast core graphics stuff, but once you stitch your engine together in a way that supports easy COMPOSITION, then you need a scripting language. Most studios with custom engines choose Lua or similar. Big engines like Unreal and Doom use their own. Some clever teams write their own Lisps.
carlosrr大约 16 年前
Lua is a multi paradigm programming language that is very popular with game makers. There's also an engine written in Lua for making 2d video games called Love <a href="http://love2d.org/" rel="nofollow">http://love2d.org/</a>.
评论 #516908 未加载
michael_dorfman大约 16 年前
Sounds like you want to read this: <a href="http://prog21.dadgum.com/23.html" rel="nofollow">http://prog21.dadgum.com/23.html</a>
TY大约 16 年前
There is a Montreal based company called Gamerizon that is currently developing a Scheme based game called QuantZ.<p>Check out their website for the demo video and screenshots of the game:<p><a href="http://www.gamerizon.com/" rel="nofollow">http://www.gamerizon.com/</a><p>Btw, they are now hiring.
jamii大约 16 年前
Fluxus ( <a href="http://www.pawfal.org/fluxus/" rel="nofollow">http://www.pawfal.org/fluxus/</a> ) is a scheme environment for live-coding graphics. Its a brilliant way to get started with games programming since you can modify code on the fly and see the results immediately. The underlying graphics engine is written in C++ so you don't lose much performance by choosing scheme.
lispm大约 16 年前
See Ypsilon Scheme: <a href="http://code.google.com/p/ypsilon/" rel="nofollow">http://code.google.com/p/ypsilon/</a><p>Ypsilon has been developed as a fundamental technology for LittleWing Pinball Construction System.<p>More info:<p><a href="http://www.littlewingpinball.com/contents/en/ypsilon.html" rel="nofollow">http://www.littlewingpinball.com/contents/en/ypsilon.html</a>
horia314大约 16 年前
Hello,<p>There's a small thinking shift between writing a game in an imperative style and writing it in a functional style. In particular, it's smaller, I think, for games than for other kinds of applications.<p>In a typical game, you have a global state - a series of objects describing the properties of the game world at a certain time. You continuously update these objects, based on what input you receive from the user, and then present those changes to him, by way of video and audio rendering.<p>In pseudoC it would look like this :<p>gameState s; int time = 0;<p>int main() { load_resources();<p><pre><code> while(!game_exit()) { get_input(); update_state(); render_video(); render_audio(); time = time + 1; } return 0;</code></pre> }<p>Switching to a functional language, a way of thinking about the game flow I've found useful is this :<p>The main loop becomes a function of two parameters : the current game state and the current inputs. From these it computes the next state. After the current simulation tick has passed, the next game state become the current one, whatever video and audio you have is updated and new inputs are gathered. It would look like this :<p>int main() { game_loop(load_resources(),init_inputs(),0); }<p>gameState game_loop(gameState currentState, gameInput inputs, int game_time) { render_video(currentState); render_audio(currentState);<p><pre><code> game_loop(next_state(currentState,inputs),new_inputs(),game_time + 1);</code></pre> }<p>Yeah, in C it will blow your stack, but functional languages have to deal with recursion much more often, and what you see there will be optimised away to a loop and be executed in constant space.<p>Other things to note are that you see the state passed explicitly between functions (no relying on it inherently existing as a global) and that the shift is from modifing an object as the game progresses, to creating a new object to represent the new state of the world, and discarding the old one.<p>Languages, be it lisp, haskell, calm, scala, f# or python, java, c, c# (used as functional languages) are relatively easy to learn. What's hard is adapting your thinking to the strengths and limitations imposed by them.<p>Hope this helped.
krschultz大约 16 年前
To get down to the nuts and bolts of it, does it have an OpenGL binding or are you capable of creating an OpenGL binding? Functional programming is great for the logic of the game, but you don't want to reinvent the wheel for rasterization, its just not worth it.<p>Start here maybe? <a href="http://shiny-dynamics.blogspot.com/2006/01/munching-on-opengl-in-common-lisp.html" rel="nofollow">http://shiny-dynamics.blogspot.com/2006/01/munching-on-openg...</a>
dgolden大约 16 年前
Well, as other posters have pointed out, lisp is multiparadigm, not just functional.<p>Anyway your question was more about abstract concerns, but concretely, note there are pretty decent SDL and OpenGL bindings for common lisp, and mildly optimised native compiled lisp code borders on "fast enough" for fast-paced 3D games - I mean people write fun games in Python these days, never mind lisp! even if GC is not concurrent, GC pausing is much less of a problem than people make out with a little common sense and care, - prealloc object pools before levels begin, code consless or at least cons-lightly, perhaps even go ahead and disable GC runs except at inter-level breaks...<p>IMO CLOS is a very nice object system for game code in an object-oriented style due to multiple dispatch (see wikipedia example):<p><a href="http://en.wikipedia.org/wiki/Multiple_dispatch#Common_Lisp" rel="nofollow">http://en.wikipedia.org/wiki/Multiple_dispatch#Common_Lisp</a><p><a href="http://lispbuilder.sourceforge.net/lispbuilder-sdl.html" rel="nofollow">http://lispbuilder.sourceforge.net/lispbuilder-sdl.html</a><p><a href="http://common-lisp.net/project/cl-opengl/" rel="nofollow">http://common-lisp.net/project/cl-opengl/</a><p>When I last looked a while back (it might be neater now), the secret to getting cl-opengl and lispbuilder-sdl to play nice together was the following incantation, enabling use of opengl 2 shaders and stuff:<p><pre><code> ; N.B. don't use any ext. functions which go through GetProcAddress ; until AFTER an opengl sdl surface exists, presumably there's late binding going on... (setf cl-opengl-bindings:*gl-get-proc-address* #'sdl-cffi::sdl-gl-get-proc-address)</code></pre>
stonemetal大约 16 年前
First off lisp does have state. It isn't a pure language. That aside there are several approaches. The easiest is to thread state that is have a function that looks like update Worldstate = do userinput &#60;- getUserinput; Worldstate' &#60;- updateworldstate userinput worldstate; drawworldstate worldstate'; update worldstate';
Hexstream大约 16 年前
Lisp is a multi-paradigm language. You can write code as imperatively as you need with it. Use the functional paradigm "by default" and then revert to imperative where it makes sense.<p>If you wanted to make a game in Haskell, which is purely functional, then your concerns would be more appropriate.
speek大约 16 年前
plt-scheme has a wonderful library for "world" programming. It allows you to get user input and makes it relatively easy (although some of the terminology is a little odd) to make things that move/do stuff graphically. <a href="http://download.plt-scheme.org/doc/371/html/teachpack/world.html" rel="nofollow">http://download.plt-scheme.org/doc/371/html/teachpack/world....</a>
doihaveto大约 16 年前
I would actually recommend taking a look at Flash. With ActionScript 3, you can write your game a very functional style - arrays have map and filter operators, you can get events and pass them through chains of filters, etc. And then you can just publish your game on the web for everyone to check out.<p>And by the way, you won't be able to do <i>pure</i> functional game programming in any language. At some point you'll have to bottom out in modifying display state - whether opengl calls, or directx calls, or flash display list changes.
评论 #525425 未加载
JoelMcCracken大约 16 年前
It seems that you haven't had the "benefits" explained yet.<p>Writing in a functional way allows you to express algorithms more easily than you could otherwise. At any given point, while doing something functionally, you only need be concerned about the state of your inputs and your output(s). Letting go of state frees your mind from worrying about so many variables, and it allows you to think about the algorithms more easily. Of course, it may take a while to start to think about things functionally, but you'll have that any time you are learning something new.<p>Another benefit is it makes things easily concurrent, which is a large challenge for the game industry at large. Caveat -- make sure you know how your language/implementation deals with this, however. Erlang is much different than Common Lisp in this regard, for example (unless there is a specific CL language with threads that I don't know about).<p>BTW, basically every lisp you'd ever use has objects, <i>or multimethods</i> <a href="http://clojure.org/multimethods" rel="nofollow">http://clojure.org/multimethods</a> &#60;&#60; basically the same thing, as far as it matters.<p>Thus, Lisp, ML, etc allow you to use FP whenever it is beneficial, and allow you to confine your state changes such that you won't have to worry about them nearly as much. Thus, many fewer bugs.<p>I cannot encourage you enough to continue to look into this. My only concern is that you will run into a lack of libraries, which clojure addresses, as everyone has already mentioned.
mahmud大约 16 年前
You need to take a look at PAL, a 2D game programming library built atop OpenGL and SDL.<p><a href="http://common-lisp.net/project/pal/" rel="nofollow">http://common-lisp.net/project/pal/</a><p>It even has a game written in it already:<p><a href="http://www.cliki.net/Bermuda" rel="nofollow">http://www.cliki.net/Bermuda</a><p>I use SBCL with lambda-gtk, lispbuilder-SDL and CL-OpenGL. Couldn't be happier. And oh, on Win32 and Linux :-)
eru大约 16 年前
The pure,lazy, functional programming language 'Clean' includes a jump'n'run in the examples:<p><a href="http://clean.cs.ru.nl/About_Clean/Platform_Games/platform_games.htm" rel="nofollow">http://clean.cs.ru.nl/About_Clean/Platform_Games/platform_ga...</a>
nitam大约 16 年前
You might also want to read this : <a href="http://www.franz.com/success/customer_apps/animation_graphics/naughtydog.lhtml" rel="nofollow">http://www.franz.com/success/customer_apps/animation_graphic...</a>
siong1987大约 16 年前
IF you are coming from a Java background, I strongly recommend you to use clojure. I have never tried clojure myself. But, it is a functional language that is built on JVM. So, it basically supports all the JAVA library you may have used before.
zitterbewegung大约 16 年前
PLT scheme has a couple of demo games included in the distribution that you might be interested in.
gameprogrdr大约 16 年前
Thank you all for responding!
time_management大约 16 年前
Since you're already familiar with Java, consider using Clojure, a Lisp that runs on the JVM and therefore has access to all the Java libraries. Java and Clojure have full interactivity, so if you need speed, you can always move the performance-critical component to Java.<p>Haskell has "state", but uses monads (design patterns derived from the type system) to segregate it carefully. Clojure has state, though "variables" are immutable by default and state requires the use of special concurrency-safe features.