* Tasks ** TODO [#C] Rename some matrix procedures matrix4-mult! -> matrix4-mul! matrix4* -> matrix4:* matrix4= -> matrix4=? ditto for matrix3 ** TODO [#A] Add define-script syntax isaneran on #guile said that they were re-evaluating top-level definitions with geiser that contained a script value, and when they did that they lost the reference to the old script. Sometimes this means old and new scripts are running at the same time but there's no way to cancel the old since the reference is no longer accessible. A =define-script= form that checks if the variable is defined and a script first would help here, as it could cancel the old script before starting the new one. ** TODO [#A] Set proper load path when launching chickadee script Add the installation location to GUILE_LOAD_PATH and GUILE_LOAD_COMPILED_PATH, as determined at configure time, to the chickadee script so that the script "just works" without the user having to setup load paths in a certain way. ** TODO [#A] Clarfiy that 'chickadee play' starts game loop for you ekaitz and wklew have both been confused why 2 windows open up when they try to use 'chickadee play'. The docs don't make it clear that they don't have to call 'run-game' when using 'chickadee play'. Also, update the examples to be run with 'chickadee play' because people copy/paste them and wonder why they don't just work! ** TODO [#A] Rewrite renderer It is finally time to make Chickadee at least theoretically capable of using a graphics API other than OpenGL. OpenGL is showing its age and all newer graphics APIs use a stateless render queue approach that is much better than OpenGL's awful global state. MacOS doesn't support anything past OpenGL 3 and there's already been a number of compatibility issues for Chickadee. WebGPU is quickly becoming a thing and with Guile Hoot on the horizon it should be possible to ship Chickadee games in the browser that use modern graphics APIs, but the work to make that happen needs to start now. So, the goal is to move all OpenGL code to an OpenGL backend, add support for multiple backends, and expose a WebGPU-like interface since the team who made it have already done the hard work of abstracting over Vulkan, Metal, and Direct3D. When we can target the web via Hoot, our graphics backend will be a thin wrapper over the WebGPU JS API, more or less. And of course on native targets we will now have the option of using whatever graphics API makes the most sense. Some big subtasks here: - [ ] Decouple OpenGL state management from dynamic render context - [ ] Refactor all OpenGL calls into a single module - [ ] Add generic WebGPU-like graphics API - [ ] Implement that API for OpenGL backend - [ ] Update all graphics modules to use new API One big caveat is that our shading language will still be GLSL at the end of this, which prevents us from being truly generic. The Seagull shading language project will take care of that so we can compile to whichever shader language our backend uses. See this for how Trial does graphics pipelines: https://reader.tymoon.eu/article/363 ** TODO [#A] Move game logic to its own thread The main thread should be reserved for running the game loop, processing the input queue, and processing the render queue. ** TODO [#A] Switch from OpenAL to SDL2 audio I've decided that OpenAL is too high level to be a library that Chickadee should rely upon, since part of the goal of Chickadee is to implement as much as possible in Scheme and only resort to C if absolutely necessary. OpenAL will also make it more difficult to ship games on the web using Web Audio when Hoot is ready (no I am not going to compile OpenAL with emscripten.) Instead, we can use SDL2's cross-platform audio API and implement all the audio mixing directly in Scheme in a dedicated audio thread. ** TODO [#A] Improve error messages in sprite-batch-add! =sprite-batch-add!= throws an error if it is called before =sprite-batch-clear!= maps the GPU memory, but the error message doesn't mean anything to users. Also, make sure the docs explain why you need to clear first. Consider renaming =sprite-batch-clear!= to =sprite-batch-begin!= while you're at it. Explain the difference between capacity and size. ** TODO [#A] Bug: Bundled games don't close properly? The window goes black but doesn't close. Closing the window again actually closes it. ** TODO [#B] Remove allocations in hot code paths - [ ] hash-for-each causes closure allocation in at least the shader, text, and audio modules - [ ] call-with-error-handling in (chickadee game-loop) allocates closures and is called twice per loop iteration. ** TODO [#B] Bug: Vertical line rendering not working Vertical lines are invisible. Not great! ** TODO [#B] The Seagull Shading Language Like CL's varjo but for Scheme! The goal here is to stop exposing GLSL to users. For one thing, GLSL sucks to write when you're a Lisper. If you want to embed a shader in a Scheme module, it has to be in a gross multi-line string literal. It also tightly couples Chickadee to OpenGL, but ideally we want to be graphics API agnostic. By using a Schemey shader language we get something that composes well with regular Scheme code while also opening up the possibility of targetting modern graphics APIs in the future. Goals: - Scheme-like syntax - Embeddable within Scheme source files - Compiles to GLSL (for now) - Clean interface for passing data from Scheme to shaders - Implicit returns in tail position (no 'return' keyword) - Everything is an expression - Type inference - Understands built-in shader stage variables - See: https://www.khronos.org/opengl/wiki/Built-in_Variable_(GLSL) - Macros - Nested functions if they don't form closures - Shader libraries for reusing and composing code #+BEGIN_SRC scheme ;; Input vertices are positional arguments, uniforms are keyword ;; arguments. (define (sprite-vertex (vec2 position) (vec2 tex) #:key (mat4 mvp)) ;; First argument returned is the vertex position, all others get ;; mapped to fragment shader inputs. (values (* mvp (vec4 (-> position x) (-> position y) 0.0 1.0)) tex)) (define (sprite-fragment (vec2 ))) #+END_SRC ** TODO [#B] Uniform buffers Need some way to support these while falling back to the current, slow way that is compatible with OpenGL 2.1. ** TODO [#B] Ditch the readline dependency Figure out how to get back to using Guile's built-in REPL for =chickadee play= so the custom can go away. Readline is hard to make work in an async manner. ** TODO [#B] Bug: Framebuffer stencil issues Render a vector path to a framebuffer and you'll notice that the first filled path doesn't show up. Why is this?? ** TODO [#B] Framebuffer multisampling Requires creating multisampled texture. ** TODO [#B] Add screenshots to manual ** TODO [#C] Add shear transformations to vector paths ** TODO [#C] Dashed lines for stroked vector paths ** TODO [#C] Mitered corners for stroked vector paths ** TODO [#C] Even-odd rule fills for vector paths Right now only the non-zero rule is supported. ** TODO [#C] Reverse winding order for vector paths ** TODO [#C] Text rendering for vector paths ** TODO [#C] Texture fills for vector paths ** TODO [#C] Improve particle system Allow more settings to be modified. Add angular velocity. Auto-expand to hold all particles rather than setting a hard cap upfront. ** TODO [#C] Support loading fonts from system font cache ** TODO [#C] REPL meta-command for rendering to an image file =,render-image= or something. Use a throwaway framebuffer to render arbitrary stuff to a texture and then save it as a PNG. ** TODO [#C] Rename array-list-size to array-list-length ** TODO [#C] Bug: Bounding boxes for stroked paths are too small Not sure how to fix right now but the bounding boxes are too small because they only account for the points within a path, not the thickness of the line, the length of the miters in a polyline, or the end caps. ** TODO [#C] Shader cache in ~/.cache/chickadee? ** TODO [#C] Binary bundles for MacOS ** TODO [#C] 2D physics simulation Add bindings for the chipmunk library or implement a rigid body simulator in Scheme. ** TODO [#C] Multiplayer networking Take a look at Xelf's UDP networking code and https://gafferongames.com/categories/building-a-game-network-protocol/ ** TODO [#C] Signed distance field font rendering ** TODO [#C] Physically-based ambient lighting The PBR shader currently does image based ambient lighting in a very naive way that does not use physically-based equations. ** TODO [#C] Right-to-left text rendering ** TODO [#C] Top-to-bottom text rendering ** TODO [#C] Octree spatial partitioning ** DONE [#A] Mention (chickadee-user) module in 'chickadee play' docs When you connect to the REPL server, it's in (guile-user) but there's nothing telling the user to switch to the right default place. Can we make the REPL automatically go to the right module? ** DONE [#A] Improve window resizing support For example, there's no user hook to handle a resize event. ** DONE [#A] Images that can be rendered in Geiser REPL Make == type that prints as =#= ** DONE [#A] CPU-side pixel buffer manipulation Make == type and use it for all image loading/manipulation, such as texture creation. ** DONE [#A] Fix 9-patch rendering not working with texture regions ** DONE [#A] Add #:clear-color argument to run-game ** DONE [#A] Tests for (chickadee math rect) ** DONE [#A] Add matrix{3,4}-copy! procedures ** DONE [#A] Load palleted PNGs ** DONE [#A] Remove SDL2-image dependency Directly link against libpng and libjpeg-turbo, for starters. Support for other formats can be added later. This will give us more flexibility since we won't be tied to SDL surfaces and thus a single thread for image loading. ** DONE [#A] Fix keyboard layout bug For example, someone with a QWERTZ keyboard layout, when they press their Z key, will invoke the key-press handler with the Z key, but (key-pressed? 'z) will be false and (key-pressed? 'y) will be true. ** DONE [#B] Quadtree spatial partitioning ** DONE [#B] Add arc-to procedure for vector paths ** DONE [#A] Tests for (chickadee data array-list) ** DONE [#A] Tests for (chickadee data heap) ** DONE [#A] Tests for (chickadee data queue) ** DONE [#A] Update rendering engine docs ** DONE [#A] Update live coding section of manual ** DONE [#A] Document polygon, cull face, depth test, stencil modes ** DONE [#A] Document cube map texture procedures ** DONE [#A] Document materials, lights, and meshes ** DONE [#A] Add intensity field to lights ** DONE [#A] Test suite ** DONE [#A] Binary bundles for Linux For easy distribution of builds so players don't have to build anything from source. ** DONE [#A] Mipmapping ** DONE [#A] Skyboxes ** DONE [#A] Basic 3D shape primitives Plane, tesselated plane, sphere, cube ** DONE [#A] Image based lighting for 3D models Cube maps and such. See: https://learnopengl.com/PBR/IBL/Diffuse-irradiance ** DONE [#A] Reimplement 9-patches ** DONE [#A] Chunk-based tile map rendering ** DONE [#A] Render rotated tiles in Tiled maps correctly See STIB library for love2d for implementation details. ** DONE [#A] Render animations in Tiled maps ** DONE [#A] Support modifications to Tiled maps ** DONE [#A] Handle window resizing gracefully ** DONE [#A] Display clear error when using OpenGL before game loop has been started ** DONE [#A] Macro for looping over number ranges Get rid of all the dang named lets for looping over x and y values in a grid. ** DONE [#A] High-level vertex buffer packing API Filling vertex buffers by hand sucks and leads to lots of redundant, brittle code all over the place. Especially so for anything that does vertex buffer streaming like sprite batches and vector paths. Maybe copy something like guile-opengl's packed structs. ** DONE [#A] Front/back face culling support ** DONE [#A] Vector graphics rendering Like NanoVG. ** DONE [#A] Feature request: Support color keyed tilesets in Tiled maps ** DONE [#A] Bug fix: Clear screen even when nothing is being drawn ** DONE [#A] Allow user to manipulate the current window ** DONE [#A] OBJ model loader and renderer ** DONE [#A] Fix bugs/missing features in particle renderer ** DONE [#A] Document how to hook up cooperative REPL server ** DONE [#A] Document (chickadee graphics tiled) module ** DONE [#A] Add pixel x,y to tile x,y procedure for Tiled maps ** DONE [#A] TrueType font rendering Like love2d or NanoVG ** DONE [#A] Chickadee executable Like love2d's =love= executable. For getting new users up and running quickly. ** DONE [#B] Linear/radial gradient fills for vector paths ** DONE [#B] Improved blending API Rather than using symbols to represent some predefined blending modes, create an api that supports the full range of options that OpenGL provides for defining the blending function. ** DONE [#B] Tile map scrolling ** DONE [#B] OpenAL sound Better than SDL_mixer. For love2d parity. ** DONE [#B] glTF 2.0 asset loading Partially implemented but most example models don't render correctly. ** DONE [#C] Rewrite GPU state and render context code Adding a new piece of state requires too much work, much of which feels redundant. ** DONE [#C] Improve technique-specific state handling Right now everything (shaders, buffers, etc.) is wrapped in 'delay' forms and then 'force'd when rendering. It would be better if we could somehow register this stuff with the gpu object. A plugin system, maybe. The plugins would be initialized when the gpu object is created and all the state would live there instead of at the top-level of various modules. ** DONE [#C] Physically based rendering Needed for full glTF rendering support but just good in general for 3D.