* Features ** TODO [#A] sexp->glsl compiler Port http://wiki.call-cc.org/eggref/4/glls to Guile? Meh, probably best to write something new that fits with Sly more. The meta-language ought to be purely functional. Would be nice if the sexp->glsl conversion happened at compile time rather than runtime, so Guile can spit out errors if shader code has syntax problems. ** TODO [#B] Smooth animation helper Remove the temporal aliasing in animation by interpolating between current and previous state of animated objects. ** TODO [#B] Bitmap font rendering from tileset Some fonts aren't available in TTF format, only as a tileset image. It would very useful for 2D games to be able to render these. Even better if the font rendering procedures are made polymorphic to handle this new type of font. ** TODO [#B] Geometry combinators A functional interface for composing complex geometry from the simple building block of triangles. A square is 2 triangles, a cube is 6 squares, etc. A triangle has 3 vertices with a particular winding. ** TODO [#B] 3D model file loader Use guile-assimp to support loading many 3D model file formats. ** TODO [#B] Multi-pass rendering pipelines It's possible to do multi-pass rendering now by binding framebuffers, shaders, etc. and running the same rendering code again, but there's probably some nicer abstraction that could clean this up. ** TODO [#B] GUI widgets Provide a set of common graphical widgets such as buttons, scroll bars, and sliders. ** TODO [#C] Tile maps - [ ] Create a generic tilemap module - [ ] Create a loader for Tiled .tmx map files. ** TODO [#C] A* pathfinding A* is a commonly used pathfinding algorithm for games. Pathfinding is such a common task that it would be nice to provide users with a generic implementation. ** TODO [#C] Bounding box collision detection Most games need simple bounding box collision detection. Provide an efficient implementation that uses quad trees. - [X] Rect module - [ ] Quadtree module (needs more thought, a purely functional data structure would be preferable) ** TODO [#C] Keymaps Provide an Emacs-like way of defining key combinations so that multi-button input is easy for users. - [ ] Abstract away input methods Controls can be bound to keys, mouse, whatever - [ ] Basic sequences Press A then B - [ ] Simultaneous key presses Press A and B at the same time - [ ] Composing sequences Press A then B + C - [ ] Timeouts Press A then B then C within 15 frames time - [ ] Sequences with actions along the way Press A to kick, then forward + B to uppercut, within 30 frames time. ** TODO [#C] Job control for agenda Allow for pausing and cancelling jobs. ** TODO [#C] Async/threaded signals? Not sure how to do this as some things, such as SDL and OpenGL calls, *must* be done in the main thread. Maybe signals should just stay synchronous. ** TODO [#C] Lighting Ambient, point, directional, etc. Requires GLSL shaders for each light types. ** TODO [#C] Instanced rendering A nice optimization when rendering the same mesh a bunch of times. Should be very handy for particle systems. * Improvements ** TODO [#A] Turn type into type I think this name makes more sense, because it's managing GPU client state. ** TODO [#A] Remove model/view/projection matrix stacks I don't think this kind of state belongs at the lowest level of the API, and it has implications on the rest of the rendering API. Right now we assume that shaders have mat4 uniforms named "model", "view", and "projection" and set them before we render any mesh. This is too limiting, so removing the matrix stacks allows us to remove the mandated uniforms. ** TODO [#A] Clean up imperative rendering API The functional, monadic rendering API is nice and clean, but the low-level imperative API is very messy. Perhaps it could use some syntactic sugar for all of the "call-with-foo" forms. Also, a naming convention needs to clearly differentiate procedures/macros in the imperative API from those in the high-level API. Originally, I didn't expect users to really ever have to use the imperative API, but the introduction of sprite batches has made me realize that writing custom low-level rendering routines will be common enough to merit a nice API. ** TODO [#A] Use uniform buffer objects Uniform buffer objects allow setting many uniform values at once, rather than performing a GPU call for each, which results in better performance. ** TODO [#B] Implement , , , and as packed f64 bytevectors Currently, it's expensive to use these types when performing OpenGL operations such as writing to vertex buffer objects because Guile does scm->f64 conversions before writing to a bytevector. To take advantage of Guile 2.2's float unboxing, we can implement these types as a record type with one field: a bytevector. The bytevector will store all of the fields packed together. To take advantage of unboxing, the procedures that get/set these "fields" should be inlined. ** TODO [#C] inotify-based live reloading Better than periodically making 'stat' calls in a loop. * Documentation ** TODO Document rendering API I can't settle on a rendering API, so I haven't bothered making good docs for it. Once the above rendering tasks are complete, it's probably safe to write docs. ** TODO Write a tutorial Walk a beginner through the basic features of Sly and establish a simple development workflow. - Start the game loop - Render a sprite - Move the sprite - Live hack * Bugs * Releases ** DONE 0.1 Release A 0.1 release was made under the project's old name, guile-2d. Now that things have changed so drastically and the name has been changed, a new 0.1 release will be made. - [X] New REPL server Use the (system repl coop-server) module in Guile 2.0.11. - [ ] Screencast - [-] Relatively complete documentation (it's a start) - [X] Clean up font module - [X] Add GLSL shaders - [X] Finish FRP module - [X] Make basic webpage with HTML docs - [X] Basic rendering (must support sprites and text) * Archived Tasks ** DONE [#A] Game loop :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Provide a game loop structure that responds to input events, updates the game state, renders the scene. Use a fixed update timestep and cap the maximum FPS. ** DONE [#A] Allow modules to declare state via signals, including OpenGL resources :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Improvements :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: This is a tricky one. The major headache with my Lisp Game Jam attempt was that the signal framework had to be abandoned *everywhere* except the top-level environment of the script that starts the game loop. The reason for this was that the game state typically required that the SDL window was opened and the OpenGL context was available in order to work. Thus, at the top-level, we first had to open a window and only then could we define signals. The goal here would be to eliminate this major restriction so that a game can be factored into many Guile modules and still declare time varying state with signals. One important consequence here is that all OpenGL resources *must* be declared as signals that wait for the game loop to start before loading. ** DONE [#A] Implement sprite batch in terms of a mesh :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Improvements :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Fix code that assumes meshes to be static, allowing for the dynamic sprite batch use-case. ** DONE [#A] Pure Scheme 4x4 matrix multiplication implementation :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Improvements :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Guile 2.1.2's float unboxing optimizations should enable this to be both fast and not allocate so much. The GSL dependency can be removed (yay!) once this is complete. Be sure to use Guile's ,x metacommand to view the disassembly to ensure that the necessary optimizations are indeed being used. ** DONE [#B] Use a single OpenGL resource guardian structure :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Improvements :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: This will deduplicate code amongst all Scheme data types that wrap OpenGL resources, because right now each one uses its own separate guardian. ** DONE [#A] Input :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Provide hooks to respond to keyboard, mouse, and joystick events. Wrap SDL keycode, mouse button, etc. constants in our own enumeration. - [X] Keyboard - [X] Mouse - [X] Window (active, resize, quit) - [X] Joystick ** DONE [#A] Sprites :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Encapsulates an image and all of its transformations: position, rotation, scale, color, etc. - [X] Use SDL2_image - [X] Add support for texture regions - [X] Add support for animations - [X] Use a sprite batch when drawing if one is currently bound ** DONE [#A] Sprite batches :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Efficiently render a large number of sprites. Only change OpenGL context when necessary. For example, don't change texture when rendering several sprites in a row that use the same one. - Use streaming vertex buffers - See: https://www.opengl.org/wiki/Buffer_Object#Mapping - See: https://www.opengl.org/wiki/Buffer_Object_Streaming - See: https://bitbucket.org/rude/love/src/d95dfb67079a60f8de64304dac9002544695f1bb/src/modules/graphics/opengl/SpriteBatch.cpp?at=default ** DONE [#A] Tilesets :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Break an image up into many small pieces. Useful for creating maps. - [X] Algorithm to split texture into tiles - [X] type ** DONE [#A] Coroutines :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Provide a way for users to easily script asynchronous behaviors using coroutines and a scheduler. - [X] Coroutines - [X] Agenda ** DONE [#A] Vectors and matrices :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Vectors and matrices are needed constantly for games. Provide an easy-to-use module that provides procedures for common vector/matrix math operations - [X] Vectors - [X] Matrices ** DONE [#A] Fonts :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: - [X] Write wrappers for needed FTGL functions - [X] Write font rendering procedures ** DONE [#A] Sound :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Provide helpful wrappers around SDL sound procedures? ** DONE [#A] REPL :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Provide a REPL that plays nice with the game loop. Easier said than done. - [X] Modify Guile's REPL to work with the game loop - Short-term solution that *mostly* works - [X] Write a new REPL that runs in the current thread - Use coroutines - Read user input from a separate thread so as to not block the main thread - Will be available in Guile 2.0.10! ** DONE [#A] Upgrade to SDL2 :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: - Write necessary bindings and release [[https://git.dthompson.us/guile-sdl2.git][guile-sdl2]]. - Replace freeimage with sdl_image 2.0 ** DONE [#B] Animations :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Create a data type to represent an animated sequence of textures and/or texture regions. ** DONE [#B] Asset Management :PROPERTIES: :ARCHIVE_TIME: 2016-02-27 Sat 12:07 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: - [X] Live asset reloading ** DONE [#A] Actors and scripts :PROPERTIES: :ARCHIVE_TIME: 2016-04-24 Sun 19:22 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Provide a purely functional means of scripting objects using a monadic combinator interface. ** TODO [#A] Shaders :PROPERTIES: :ARCHIVE_TIME: 2016-05-18 Wed 16:11 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: TODO :END: Shader data type ** DONE [#C] "Nine patches" :PROPERTIES: :ARCHIVE_TIME: 2016-05-27 Fri 22:22 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: DONE :END: Images that have a resizable central area but fixed width/height edges. See [[https://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch][this Android document]] for details. ** TODO [#C] Particle systems :PROPERTIES: :ARCHIVE_TIME: 2016-05-28 Sat 18:31 :ARCHIVE_FILE: ~/Code/sly/TODO.org :ARCHIVE_OLPATH: Features :ARCHIVE_CATEGORY: TODO :ARCHIVE_TODO: TODO :END: Provide a highly configurible particle simulation system.