From dto1138 at gmail.com Thu Mar 18 11:09:34 2010 From: dto1138 at gmail.com (David O'Toole) Date: Thu, 18 Mar 2010 07:09:34 -0400 Subject: [lisp-game-dev] Announce: 2010 LISP Game Design Challenge! Message-ID: <64bfe3d51003180409l695af674g77b5cbde1a784233@mail.gmail.com> A preliminary info page is up at http://dto.github.com/notebook/lgdc.html From elliottslaughter at gmail.com Fri Mar 19 20:58:00 2010 From: elliottslaughter at gmail.com (Elliott Slaughter) Date: Fri, 19 Mar 2010 13:58:00 -0700 Subject: [lisp-game-dev] Announce: 2010 LISP Game Design Challenge! In-Reply-To: <64bfe3d51003180409l695af674g77b5cbde1a784233@mail.gmail.com> References: <64bfe3d51003180409l695af674g77b5cbde1a784233@mail.gmail.com> Message-ID: <42c0ab791003191358g227b34c1jce1c012d1235523@mail.gmail.com> On Thu, Mar 18, 2010 at 4:09 AM, David O'Toole wrote: > A preliminary info page is up at http://dto.github.com/notebook/lgdc.html > Where has this been announced so far? I believe it was decided that this would be open to all LISP dialects (hence the old-fashioned capitalization), so we might consider announcing it in some of these places: Arc - http://arclanguage.org/forum Clojure - http://groups.google.com/group/clojure Scheme? -- Elliott Slaughter "Don't worry about what anybody else is going to do. The best way to predict the future is to invent it." - Alan Kay -------------- next part -------------- An HTML attachment was scrubbed... URL: From dto1138 at gmail.com Fri Mar 19 23:28:47 2010 From: dto1138 at gmail.com (David O'Toole) Date: Fri, 19 Mar 2010 19:28:47 -0400 Subject: [lisp-game-dev] Registration reminder Message-ID: <64bfe3d51003191628w71063ebk173c6683d8faf447@mail.gmail.com> Welcome, participants! Whether spectator or Challenger, please register yourself at the Cliki page if you haven't already. http://www.cliki.net/LispGameDesignChallenge From dto1138 at gmail.com Mon Mar 29 18:23:15 2010 From: dto1138 at gmail.com (David O'Toole) Date: Mon, 29 Mar 2010 14:23:15 -0400 Subject: [lisp-game-dev] LGDC010 entrant questionnaire Message-ID: <64bfe3d51003291123v1565f3f2scb0ed92e2b635df7@mail.gmail.com> I'd like everyone to post an entry postmortem, even if (like me) you failed to produce a complete game. Just present what you do have and perhaps touch on the following questions: 1. what did you learn? 2. what went right? 3. what went wrong? 4. what's lispy about my entry? 5. what interesting algorithms or designs did i use? Thanks everyone for participating! From pat at nklein.com Tue Mar 30 14:33:54 2010 From: pat at nklein.com (Patrick Stein) Date: Tue, 30 Mar 2010 09:33:54 -0500 Subject: [lisp-game-dev] LGDC010: Roto Mortar post-mortem In-Reply-To: <64bfe3d51003291123v1565f3f2scb0ed92e2b635df7@mail.gmail.com> References: <64bfe3d51003291123v1565f3f2scb0ed92e2b635df7@mail.gmail.com> Message-ID: <6C455DBD-9A42-473F-AF3C-70298CB33B5F@nklein.com> On Mar 29, 2010, at 1:23 PM, "David O'Toole" wrote: > I'd like everyone to post an entry postmortem My game is called Roto Mortar [1]. When I started trying to come up with a game that I might be able to pull off in a week, I remembered an exercise from the book: Game Design Workshop [2]. The exercise was to design a game with a one-button interface. The concept I came up with for this contest was that you were trying to defend a base against attack. You've got two mortar cannons. Unfortunately, their controls have been blasted. Lucky for you, Ace Repair Guy Billy Bob has rigged one of them to rotate and hooked up a button that let's you tilt it while you hold the button and fires when you release it. Here is the game announcement I made on my blog [3]. What I got done was the basic shell of the game. There is a quick title screen with a message from Billy Bob setting the stage. Then, you're plopped into the game. Another message from Billy Bob announces that he's gotten one turret back online. The game scenery, enemies, and projectiles are all UV textured, X3D objects made in Blender with PNG textures. The game uses shadow- volume techniques to overlay a range and angle indicator onto the scenery so you can tell where you're aiming. Those shadow volumes are non-textured, X3D objects built in blender. I used my own code for font-rendering in cl-OpenGL using zpb-ttf [4] to render the messages from Billy Bob and the opening title. I used cl-png to load the PNG files (textures and Billy Bob icon). I used a custom parser atop CXML SAX parsing to read the X3D files. I used CLOS throughout and made much use of the PROGN method combination. [1] http://nklein.com/software/roto-mortar/ [2] http://www.amazon.com/Game-Design-Workshop-Prototyping-Playtesting/dp/1578202221 [3] http://tinyurl.com/ykeahl8 [4] http://nklein.com/2010/01/better-text-rendering-with-cl-opengl-and-zpb-ttf/ > 1. what did you learn? I had read about Shadow Volume rendering in OpenGL several times before. This is the first that I actually did it. I could probably do it again now without references. I had a bunch of my methods return a new 'screen instance if you want to switch screens. I think, if I were to do it again, I'd either make a robust check on the receiving end to ignore return results that aren't of type screen or add a slot to the screen class that is NIL until it's time to switch screens. As it was, I accidentally returned T or a mesh or something incompatible from my event handlers way too many times (especially by the end of the second all-nighter). > 2. what went right? I drew a simple UV cube in Blender. I exported it to every choice on the export menu. After looking a bit, I opted for X3D. It's badly structured XML, but not too hard to parse. (I say badly structured because its lists of number are all encoded into strings. Rather than stuff like 3.52.0... or even: 3.5 2.0... they instead have attributes of comma-separated lists coordinates="3.5 2.0, ...".) Anyhow, I think X3D was a good choice... easy to get going. And, with baked textures from Blender, things looked pretty good. I was glad I had already published the font-rendering code cuz I could otherwise have a day there. As it was, I just pulled in the font.lisp I had published earlier [4]. I used SBCL's save-lisp-and-die to make a command-line executable and Platypus to wrap that up as an OS X executable. Those both worked great. > 3. what went wrong? As I mentioned, having each event handler for a screen possibly return a new screen seems like a cool, lispy idea. Really, it is easy to mess up when you're tired. I spent lots of time, too, trying to figure out which attributes I hadn't saved that I should have in one place which screwed up things in another place. I also spent way too much time working around the OpenGL matrix methodology. What I needed to do for my direction-indicator and range- indicator was... translate to where they need to be and draw them at the appropriate angle and scale. What I wanted to be able to do is set up the angle and scale and then translate things and draw. If OpenGL had more room available on the :projection matrix stack or another :model-local matrix after the :model-view, I could have reused code much more. As it was, I had to make some custom draw code for these objects to get the rotation and scaling to happen after the translation. There is a whole list at [1] of things I wanted to get done in a week, but didn't. There may well be an option to CXML to get it to ignore the DOCTYPE declaration. But, I just manually removed them from the X3D files to keep CXML from trying to fetch them. > 4. what's lispy about my entry? In the game-play itself? Nothing. In the implementation, I used PROGN method combination to great effect here. In particular: (defmethod update-item (item delta-time) (:method-combination progn :most-specific-last)) This way, the base object can track total time elapsed since some point, but derived objects can use either that total time or the most recent delta or an intermediate classes total time since some other indicator. The XML parsing also makes use of interning symbols to avoid lots of string compares. > 5. what interesting algorithms or designs did i use? The basis of the X3D parser was generated from other Lisp code that I was working on a few weeks back. And, the PROGN thing was pretty cool. And, the shadow volume technique is pretty flexible for projecting stuff onto surfaces. -- Patrick From alastair.bridgewater at gmail.com Tue Mar 30 16:16:16 2010 From: alastair.bridgewater at gmail.com (Alastair Bridgewater) Date: Tue, 30 Mar 2010 12:16:16 -0400 Subject: [lisp-game-dev] LGDC010 entrant questionnaire In-Reply-To: <64bfe3d51003291123v1565f3f2scb0ed92e2b635df7@mail.gmail.com> References: <64bfe3d51003291123v1565f3f2scb0ed92e2b635df7@mail.gmail.com> Message-ID: <3a35f3641003300916g10265a53odac0a5328074cfee@mail.gmail.com> A postmortem, huh? What I have is about 970 lines of code over nine files, imaginatively named "game-stuff". There is possibly the beginnings of a classic dungeon crawl (such as Wizardry or Shining in the Darkness) in there, but it would need at least another few days of work to bring it out. 1. What I learned: ?* The heart of a UI toolkit is event and redraw management, and is easier to build than I had thought. ?* Not being able to create game art is a serious handicap for a game developer, and leads to using more "abstract" visuals ("The pentagon hath smote thy shoulder for five damage."). This is fine as a stylistic choice, to a point, but it is far better to not be virtually forced into it. ?* Not running your game loop in its own thread adversely impacts SLIME behavior. ?* Running your game loop in its own thread makes use of *standard-output* for information gathering more annoying. ?* Model-view-controller, or at least view-controller, is still king. ?* Text rendering is still annoying at best. ?* For short-timescale development, such as a 7-day compo, it helps to have an idea of what you're going to do when you start, actual practice using the libraries and tools before you start, and to be able to leverage existing code. I expect that the next time I try one of these events I'll be better prepared, simply from having a better idea of what I'm doing, from the code that I produced this time already written, and possibly from having improved the code in the interim. ?* As a unit-test library SB-RT is lame. It might be a tolerable starting point, but it desperately needs some utilities layered over the top. 2. What went right: ?* Small files and one package per file. This has a number of effects, mostly promoting the definition of small, close-to-explicitly defined protocols between parts of the system. Small files applies a certain "pressure" towards each file doing just one thing. One package per file leads to explicitly defining what that one thing is and how to make it happen. On the whole, it's API and protocol design in the small. I'm not sure how well this scales, but I'm interested in finding out. ?* Being able to discuss problems on IRC. Especially if it's a problem with an unfamiliar library (such as OpenGL), or a problem with common tools such as SLIME, or how to structure some part of your system, feedback and suggestions from other people can help immensely. ?* Using OpenGL for 2d rendering. I don't know if this went right, or simply didn't go wrong, but I'll give it the benefit of the doubt. ?* Swiping ideas from other people and code from my own copious archives (though there's not much -game- code in my archives). 3. What went wrong: ?* The GLX implementation I used is still more than a little rough around the edges (incomplete, not well documented, and has an awful tendency to ignore commands if the parameters are of the "wrong" type). ?* I was badly distracted in several different directions over the course of the event, including attempting to get a video capture device working properly in one of my computers. ?* The tool support for working with lots of small packages instead of few large packages is either non-obvious or non-existent. This was most noticeable when "splitting" a package, moving some of its functionality to a new package. ?* I have no mouth texture image, and I must scream. 4. What was lispy: ?* I used SBCL, CLX, and the GLX implementation in CLX. ?* Redefining input handling and redraw completely while the main loop was still running. ?* Using generic functions for output redraw control. ?* Using first-class functions for input handling. 5. What interesting algorithms or designs were involved: ?* I swiped the pseudo-3d maze bits from an old X program I wrote back in 2004 that used line-drawing primitives to lay out the maze views (much as the original Apple ][ Wizardry did). ?* In order to issue a glCallLists request for drawing text on the screen, I copy the string to be output and smash up the type and length bits of the copy to be consistent with an octet vector, then ship the octet vector off to the server. This is horribly SBCL-specific, but it gets the job done. ?* All visual output ended up being performed in terms of "widget" objects that were on a global list. This list was set up via defparameter, so I ended up being able to experiment with new widgets and widget parameters by simply reevaluating a variable initialization instead of involving the main redraw function or reinitializing the entire main loop. 6. What I believe I need to do going forward. * Start working on producing decent 2d game art. This is one of my major handicaps, and I'd like it to be at least partly compensated for. * The input model in game-stuff is lame, and needs a rewrite. Just as soon as I figure out what wouldn't be lame. * My current text-message widget is static-text only. Being able to treat it as an output stream, or at least to be able to write new messages into it without recompiling it, would make it actually -useful-. * Fix some of the outstanding issues with the GLX I'm using. * Learn more about the OpenGL rendering model, especially the matrix stack and various glEnable options. * Produce an actual, end-to-end, full game. Even if the plot is basically "go down to the bottom of the dungeon, kill the evil wizard Riatsala and recover his Book of Primary Aspiration" it would at least be a full game, and that would be a first for me. * Sink some effort into improving my tools, both in terms of development environment and in terms of available libraries and documentation. Note that this expressly does -not- mean compiler-backend hacks (my usual playground). I think that's basically it, and I'm looking forward to the next LGDC. -- Alastair Bridgewater From dto1138 at gmail.com Tue Mar 30 21:21:17 2010 From: dto1138 at gmail.com (David O'Toole) Date: Tue, 30 Mar 2010 17:21:17 -0400 Subject: [lisp-game-dev] post-mortem for CONS Message-ID: <64bfe3d51003301421o67a5f33au2f5294c877633322@mail.gmail.com> #+TITLE: LGDC10 Postmortem *Tuesday March 30, 2010* First let me thank everyone for participating in the 2010 Lisp Game Design Challenge! I think the whole contest has been a success. With ten registered entries (8 individuals and 2 teams), I think we'll have a lot to discuss in the coming days. The LGDC also brought some new people to the lispgames community, and we're continuing to build a knowledge base for developing and delivering games in Lisp across multiple platforms. For example the http://www.cliki.net/LispGameDesignChallenge cliki registration page now has a big list of links to various libraries and tools, and the IRC channel's ranks have swelled to an average of over 30 people. I've read the postmortems mailed so far and I think these documents will be a great contribution to the lispgames noosphere. And now for my postmortem! For my 7-day Challenge entry I implemented the core gameplay mechanics and settings of a loosely Lisp-themed sci-fi combat game called CONS. I'm classifying my entry as a failure because I did not finish a complete game within the time limit. I will continue working on CONS though, and I'm looking forward to fleshing out the design. * What's lispy about my entry? The player is a multi-segment Lisp list snake! See the design document at http://dto.github.com/notebook/cons.html for details. In addition some interesting "minilanguage" techniques were used for this game, see the algorithms section below. * Tools and technology My entry is programmed in Common Lisp running on SBCL. I used my own [[file:xe2-reference.org][XE2 game engine]], which is based on LISPBUILDER-SDL. Image editing was done with the GIMP, and program development with GNU Emacs and SLIME running on Ubuntu. For music and sound I used varying combinations of Hexter (a software Yamaha DX7 emulator), Audacity (digital audio editor), Ardour (digital audio recording workstation), and Milkytracker (MOD tracking application.) * What went right? - The 7-day process is good for focusing on the core play mechanics, despite being a bit stressful at times. - My design called for five different level types plus an overworld map. This forced me to focus on improving XE2's random level generation framework, and led to some interesting new functionality. See the "interesting algorithms" section below. - Focusing on usability led to simplified controls---gameworld interaction uses only the arrow keys, Z, X, and Shift. The number one category of user feedback complaints about my games relate to controls, so this is a big win. I also made the controls user-configurable through an interactive spreadsheet screen, which is also joystick-compatible (with some glitches at the moment.) This is (finally) a port of my circa-2006 OO spreadsheet program "Cellmode". However, this was a time-sink, see next section. * What went wrong? My only real mistake was developing CONS as a 7-day thing. The design is a bit larger than my recent games and only the skeleton was finished by that time. Also, I spent an inordinate amount of time on the input configuration screen, and on the music for the game, when I should have focused on fleshing out the gameplay. * What did you learn? Don't attempt to port major features from an old codebase while in the middle of a 7-day challenge. Although porting Cell-mode and creating the configuration UI was unquestionably time well spent, I should have waited until after my entry was complete to work on these features. * What interesting algorithms or designs did i use? There are two main points here, one relates to level generation and the other to user interfaces. (The combination of both elements mean we will soon have a user interface for level generation.) Development on my 2010 7DRL challenge entry XIOTANK was troubled by the issue of how to generate solvable puzzles while still randomizing the layout. This is a hard problem, and occasionally-unsolvable levels have been a criticism of XONG (see http://playthisthing.com/xong ) In XIOTANK the more elaborate combination-lock style puzzle was unexpectedly hard to implement, and the result was still less than satisfying. Late in development, I overemphasized combat to compensate for this, and the result was (according to some players) an overly difficult game. I realized I had a bunch of level generation tools but nothing to tie them together. With some new functionality implemented in XE2 this has changed. First came support for randomly generating sentences (Lisp lists of individual words, strings, or symbols) according to simple context-free grammars. http://en.wikipedia.org/wiki/Context-free_grammar This is similar to L-systems except that substitutions are not simultaneous. Here's an example grammar for a fictional sci-mission: : (defparameter *test-grammar* : '((mission >> (at location please goal+ in exchange for reward)) : (location >> mars zeta-base nebula-m corva-3) : (goal+ >> goal (goal and goal+)) : (goal >> (defeat foe) (defend friend) (activate button) (retrieve documents) : (collect mineral+)) : (mineral+ >> mineral (mineral and mineral+)) : (mineral >> endurium technetium molybdenum francium a-biosilicates) : (foe >> scanner biclops unique) : (friend >> transport skiff soldier scientist) : (unique >> zx-90 xioblade) : (reward >> money part) : (money >> 10000 20000 30000 40000 50000) : (part >> muon-pistol lepton-cannon ion-shield-belt))) When "foe" is encountered for example, it is replaced with either "scanner" "biclops" or "unique". (Sublists represent concatenation.) A few example output sentences. : (AT MARS PLEASE COLLECT A-BIOSILICATES IN EXCHANGE FOR MUON-PISTOL) : (AT NEBULA-M PLEASE DEFEAT XIOBLADE IN EXCHANGE FOR MUON-PISTOL) : (AT CORVA-3 PLEASE RETRIEVE DOCUMENTS AND ACTIVATE BUTTON IN EXCHANGE FOR : ION-SHIELD-BELT) These are unintepreted data, but it is straightforward to give them an interpretation. I haven't yet done this with mission structures as in the example, but I *have* made a working implementation of a simple LOGO-like language, to interpret randomly-generated LOGO programs like this: : 9 :JUMP :PUSHLOC CONS-GAME::=BARRIER= :COLOR 90 :RIGHT 7 :DRAW :POPLOC 9 :JUMP : :PUSHLOC CONS-GAME::=BARRIER= :COLOR 90 :RIGHT 7 :DRAW :POPLOC 9 :JUMP : :PUSHLOC CONS-GAME::=BARRIER= :COLOR 90 :RIGHT 7 :DRAW :POPLOC 9 :JUMP : :PUSHLOC CONS-GAME::=BARRIER= :COLOR 45 :RIGHT 7 :DRAW :POPLOC 10 :JUMP 90 : :RIGHT :ORIGIN :PUSHLOC 45 :RIGHT 5 :JUMP CONS-GAME::=EXIT= :COLOR :DROP : :POPLOC 90 :RIGHT 20 :JUMP 90 :LEFT 25 :JUMP 90 :LEFT :PUSHLOC : CONS-GAME::=BARRIER= :COLOR 5 :DRAW :PUSH-COLOR :PUSHLOC 90 :LEFT : CONS-GAME::=BOMB-DEFUN= :COLOR 1 :JUMP 2 :DRAW :POPLOC :COLOR 5 :DRAW 90 : :RIGHT 4 :DRAW 2 :JUMP 4 :DRAW 90 :RIGHT 10 :DRAW 90 :LEFT : CONS-GAME::=BARRIER= :COLOR 5 :DRAW :PUSH-COLOR :PUSHLOC 90 :LEFT : :RIGHT 4 :DRAW 2 :JUMP 4 :DRAW 90 :RIGHT 10 :DRAW 90 :RIGHT 6 :JUMP :PUSHLOC : CONS-GAME::=PURPLE-BRICK= :COLOR 5 :DRAW 90 :RIGHT 5 :DRAW 90 :RIGHT 2 :DRAW 1 : :JUMP 2 :DRAW 90 :RIGHT 10 :DRAW 90 :LEFT CONS-GAME::=PURPLE-BRICK= :COLOR 5 : :DRAW 90 :RIGHT 5 :DRAW 90 :RIGHT 2 :DRAW 1 :JUMP 2 :DRAW 90 :RIGHT 10 :DRAW : :POPLOC :PUSHLOC CONS-GAME::=BLUE-BRICK= :COLOR 5 :DRAW 90 :RIGHT 6 :DRAW 90 : :RIGHT 5 :DRAW 90 :RIGHT 6 :DRAW 90 :LEFT CONS-GAME::=BLUE-BRICK= :COLOR 5 : :DRAW 90 :RIGHT 6 :DRAW 90 :RIGHT 5 :DRAW 90 :RIGHT 6 :DRAW 90 :LEFT 1 :JUMP : :NOOP :PUSHLOC 90 :RIGHT 3 :JUMP :DROP-REACTOR :POPLOC :POPLOC :POPLOC : :DROP-DRONES The twist on LOGO is that it's a Forth-style prefix notation. I maintain a stack of data items for each world. The LOGO program is generated according to a supplied grammar. When a non-keyword symbol is encountered, push its value onto the stack. When a string or number is encountered, push it onto the stack also. But when a keyword-symbol is encountered, we invoke the correspondingly-named method on the =world= object, which may pull arguments from the stack. The operation :COLOR sets the "paint color", in this case the type of game object to draw. The operations :PUSHLOC and :POPLOC save and restore (respectively) the turtle's current position and orientation. :DRAW and :JUMP move N squares in the current direction, either painting (with :DRAW) or not painting (:JUMP). Here's part of a "reactor level" generation grammar: : '((world >> (rod-square : :origin : :pushloc : 45 :right : 5 :jump : =exit= :color :drop : :poploc : 90 :right : 20 :jump : 90 :left : 25 :jump : 90 :left : :pushloc security-structure :poploc : :drop-drones)) : (rod-angle >> 90 45) : (rod >> (9 :jump : :pushloc : =barrier= :color : rod-angle :right : 7 :draw : :poploc)) : (rod-row >> (rod rod rod rod rod 10 :jump 90 :right)) : (rod-square >> (rod-row rod-row rod-row rod-row)) : (side-chamber >> (:pushloc : room3 90 random-turn : room3 90 :left : 1 :jump : gun-maybe : :pushloc : 90 :right : 3 :jump : :drop-reactor : :poploc : :poploc)) : (gun-maybe >> :noop :noop (=shocker= :color :drop)) : (security-structure >> (room 90 :left : room 90 :left : room 90 :left : room 90 :right : 6 :jump : :pushloc room2 90 random-turn room2 :poploc : side-chamber)) : (random-turn >> :right :left) : (random-brick >> =purple-brick= =blue-brick=) This is a big change for XE2. With turtle graphics it's easy to scale and rotate drawing elements, and express their mututal arrangement in both absolute and relative terms. But the drawing elements can be anything, because the keywords in the randomly generated sentences can trigger any method you choose to define---not just LOGO-like operations. So all the other existing tools in XE2 (lines, boxes, circles, plasma) are now tied together into a cohesive and extensible framework for procedural content generation of all kinds, not just levels. (I'm interested in seeing what can happen with procedural story elements.) A related development is the porting of cell-mode from Emacs Lisp into Common Lisp. It's a sort of object-oriented spreadsheet program with dataflow from left-to-right amongst cells of different types. Instead of implementing a new grid structure, I made a new system called "forms". One can build a spreadsheet UI out of game objects, or open an editable spreadsheet view of a game world. Combine this ability to hand-edit with the procedural generation tools, and we could have a very powerful interactive gamesdev environment. Thanks for reading everyone.