{"id":28471178,"url":"https://github.com/johnalexinl/moongin","last_synced_at":"2026-04-19T05:34:58.096Z","repository":{"id":293378021,"uuid":"902145426","full_name":"JohnAlexINL/moongin","owner":"JohnAlexINL","description":null,"archived":false,"fork":false,"pushed_at":"2025-05-23T09:44:17.000Z","size":5091,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-14T18:28:19.280Z","etag":null,"topics":["3d-engine","framebuffer","game-development","game-engine","lua","lua-programming","md2","sdl2","tinygl"],"latest_commit_sha":null,"homepage":"https://modula.dev","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JohnAlexINL.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-12T02:00:49.000Z","updated_at":"2025-05-23T09:44:20.000Z","dependencies_parsed_at":"2025-07-01T21:42:49.072Z","dependency_job_id":null,"html_url":"https://github.com/JohnAlexINL/moongin","commit_stats":null,"previous_names":["johnalexinl/moongin"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/JohnAlexINL/moongin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnAlexINL%2Fmoongin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnAlexINL%2Fmoongin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnAlexINL%2Fmoongin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnAlexINL%2Fmoongin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JohnAlexINL","download_url":"https://codeload.github.com/JohnAlexINL/moongin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnAlexINL%2Fmoongin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31996445,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d-engine","framebuffer","game-development","game-engine","lua","lua-programming","md2","sdl2","tinygl"],"created_at":"2025-06-07T10:30:39.525Z","updated_at":"2026-04-19T05:34:58.078Z","avatar_url":"https://github.com/JohnAlexINL.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Moongin\n\nMoongin is a cross-platform games and applications engine.\nIt is intended to build against libraries like SDL, Lua, and TinyGL.\nEventually, the intent is to get Moongin set up\nin a way that its binaries can be statically cross-compiled,\nand assets can be created for it in cross-platform tools like Blender.\n\n## Architecture\n\nMoongin depends on compilers like `clang` to do\nthe heavy-lifting of compiling C-code, and\ndepends on libraries like `SDL2` to handle\ncomplex stuff like getting windows and drawing to\nthem in a way that's cross-platform.\n\nThe 3D and rendering side of Moongin assumes the window is \n(or contains) a framebuffer that can be manipulated trivially \nwith something like TinyGL/OpenGL.\nThe framebuffer is then cast as a texture \nto the real graphics frontend of the target system \nusing SDL to make it very easy to use software \n*OR* hardware rendering, as well as to make\nporting Moongin's entire application architecture very easy.\n\nMoongin also includes support for animated `MD2` models\nusing a variety of image types as textures.\nTo keep the system as lightweight as possible, \nMoongin's 3D engine does not have things like \nlighting support or kinematics out of the box,\nbut is easy to add and expose C-extensions to\nMoongin at compile time.\n\n\u003c!-- \nSDL_Texture *tex = SDL_CreateTexture(renderer,\n    SDL_PIXELFORMAT_ARGB8888,\n    SDL_TEXTUREACCESS_STREAMING,\n    width, height); ??\n--\u003e\n\n## Philosophy\n\nMoongin is intended to be a game engine that \"sucks less\" --\nnot only in the sense that \nit's easier to use than things like Godot or Unity, \nnor only in the sense that it's very easy to\nlook under the hood and understand\n-- but also in the sense that it has things like\nextensibility, important features like community modding,\nand Quick-Use already in mind and baked into the design.\n\n## Licensing\n\n`moongin` is made available under the BSD 3-Clause License.\nThe code linked into executables produced with `moongin`\nis shared code under the same license, and because of that\nthe permissive BSD license was chosen instead of something like GPLv3.\n\nAs long any program generated using Moongin \nincludes an acknowledgement that it was built\nwith the following software and their licenses, \nand does not imply endorsement by these projects, \nit is compliant\n\n| Asset | License | Link |\n|--|--|--|\n| Moongin | [BSD-3 Clause](https://github.com/JohnAlexINL/moongin/blob/main/LICENSE) | [modula.dev](https://modula.dev) |\n| SDL2 | [zlib](https://libsdl.org/license.php) | [libsdl.org](https://libsdl.org) |\n| Lua | [MIT](https://lua.org/license.html) | [lua.org](https://lua.org) |\n| tinyGL * | [zlib](https://github.com/C-Chads/tinygl/blob/main/LICENSE) | [github.com/C-Chads](https://github.com/C-Chads/tinygl/tree/main) |\n| miniaudio * | Public domain | [miniaud.io](https://miniaud.io/) |\n| `Mono.ttf` | [https://ubuntu.com/legal/font-licence](https://ubuntu.com/legal/font-licence) | [fonts.google.com?query=Dalton+Maag](https://fonts.google.com?query=Dalton+Maag) |\n\n\\* not yet actually incorporated in the project,\nmay be replaced with something else later\n\n## Usage\n\n`moongin` takes in a `.lua` file that functions as the\nmain logic of the program to build, and then embeds\nit into a C-based runtime and compiles it with `clang`.\nThe output executable is **_not_** a static executable,\nbut I would like to eventually get to the point where\n`moongin` does build static binaries.\nIt also expects the platforms to build for as additional flags.\n\n## Moongin API\n\nThe full API is also annotated in the [`api.lua`](./helpers/api.lua) header\n\n### `core` - engine functions\n\nall entities store a copy of their `id`;\nremoving the `id` will cause erroneous behavior.\n_TODO: if possible, make it so it can't be deleted\nwithout calling the `destroy` method_\n\n|--| Function | Interface | \u003cabbr title=\"Source of Truth\"\u003esot\u003c/abbr\u003e |\n|--| -------- | ----------- | ---------------------------------------- |\n|🗹| `core.parseid` | \u003cabbr title=\"str: id\"\u003e`str`\u003c/abbr\u003e ➔ `void *` | _change to be `instance` instead_ |\n|🗹| `core.id` | \u003cabbr title=\"int: id\"\u003e`int`\u003c/abbr\u003e ➔ `void *` | _change to be `instance` instead_ |\n|--| `core.castid` | \u003cabbr title=\"int: type, void *: reference\"\u003e`type, void *` ➔ \u003cabbr title=\"int: id\"\u003e`id`\u003c/abbr\u003e | _this should be the only function that touches any `void *`; stored as `lightuserdata: ref`_ |\n|--| `core.clone` | \u003cabbr title=\"int: id, int: clonetype\"\u003e`id, type`\u003c/abbr\u003e ➔ `id` | |\n|--| `core.type` | \u003cabbr title=\"int: id\"\u003e`id`\u003c/abbr\u003e ➔ \u003cabbr title=\"int: type\"\u003e`type`\u003c/abbr\u003e |  |\n|--| `core.types` | _table_, _TODO:  Docs_ |  |\n|--| `core.typedef` | `str` ➔ \u003cabbr title=\"int: type\"\u003e`int`\u003c/abbr\u003e | |\n|--| `core.typefunc` | `type, function` | |\n|--| `core.destroy` | `int` | uses the type's destructor to free any data if exists, then deletes the entity instance | \n|🗹| `core.exit` | \u003cabbr title=\"int: status\"\u003e`int`\u003c/abbr\u003e | |\n\n#### types implemented by `core`\n\n|--| Type | Field | Notes |\n|--|--|--|--|\n|--| `script` | _lua bytecode_ | _NOTE: `script` type cannot be cloned_|\n|--| `room` | `baseid` | _if `baseid != id`_ then instanciated |\n|--| | `init` | `id` script: takes `(room, table)`\n|--| | `parent` | room `id`; root will have the window `id` |\n|--| | `render` | draws contained objects and returns |\n|--| | `pop` | returns to `parent` context unless at root and decrements `types.room.next` |\n|--| | `sprite` | _optional_, _TODO: Docs_ |\n|--| `object` | `baseid` | _if `baseid != id`_ then instanciated | \n|--| | `events` | pseudo `event.self(object, args)`; a named list of script `id`s\n|--| | `init` | `id` script: takes `(object, table)`\n|--| | `parent` | room `id` |\n|--| | `sprite` | _TODO: Docs_, basically contains texture id, rect, and some optional fields |\n|--| | `pop` | destroys the object and moves `type.self.next` back\n### `gfx` - windowing, graphics, and i/o functions\n\n|--| Function | Interface | \u003cabbr title=\"Source of Truth\"\u003esot\u003c/abbr\u003e |\n|--| -------- | ----------- | ---------------------------------------- |\n|🗹| `gfx.eventPoll` | modifies _gfx.event_ | [SDL_Event](https://wiki.libsdl.org/SDL2/SDL_Event) |\n|--| `gfx.break` | \u003cabbr title=\"table: callbacks, number: timeout\"\u003e`table, timeout`\u003c/abbr\u003e | _MOONGIN DOCS_ |\n|🗹| `gfx.newWindow` | `title, width, height, flags` ➔ `id` | [SDL_CreateWindow](https://wiki.libsdl.org/SDL2/SDL_CreateWindow) |\n|🗹| `gfx.destroyWindow` | `id` | [SDL_DestroyWindow](https://wiki.libsdl.org/SDL2/SDL_DestroyWindow) |\n|🗹| `gfx.newRenderer` | `window, flags` ➔ `id` | [SDL_CreateRenderer](https://wiki.libsdl.org/SDL2/SDL_CreateRenderer) |\n|🗹| `gfx.destroyRenderer` | `id` | [SDL_DestroyRenderer](https://wiki.libsdl.org/SDL2/SDL_DestroyRenderer) |\n|🗹| `gfx.presentRenderer` | `id` | [SDL_RenderPresent](https://wiki.libsdl.org/SDL2/SDL_RenderPresent) |\n|--| `gfx.getRenderViewport` | `id` ➔ `box` | [SDL_RenderGetViewport](https://wiki.libsdl.org/SDL2/SDL_RenderGetViewport) |\n|🗹| `gfx.setColor` | \u003cabbr title=\"int: red, int: green, int: blue, int: alpha\"\u003e`rgba` | [SDL_SetRenderDrawColor](https://wiki.libsdl.org/SDL2/SDL_SetRenderDrawColor) |\n|--| `gfx.setBlendMode` | `flags` | [SDL_BlendMode](https://wiki.libsdl.org/SDL2/SDL_BlendMode)\n|🗹| `gfx.clear` | \u003cabbr title=\"id: renderer\"\u003e`id`\u003c/abbr\u003e | [SDL_RenderClear](https://wiki.libsdl.org/SDL2/SDL_RenderClear), [SDL_RenderPresent](https://wiki.libsdl.org/SDL2/SDL_RenderPresent) |\n|--| `gfx.renderDot` | `id, point` | [CategoryRender](https://wiki.libsdl.org/SDL2/CategoryRender) |\n|--| `gfx.renderDots` | `id, list` | _list of points_  |\n|--| `gfx.renderLine` | `id, point, point` | |\n|--| `gfx.renderLines` | `id, list` | _list of points_ |\n|--| `gfx.renderLineBox` | `id, box` | _no fill_ |\n|--| `gfx.renderLineBoxes` | `id, list` | _no fill, list of boxes_ |\n|--| `gfx.renderBox` | `id, box` | |\n|--| `gfx.renderBoxes` | `id, list` | _list of boxes_ |\n|🗹| `gfx.delay` | \u003cabbr title=\"number: number of milliseconds\"\u003e`number`\u003c/abbr\u003e | [SDL_Delay](https://wiki.libsdl.org/SDL2/SDL_Delay) |\n|🗹| `gfx.loadTexture` | \u003cabbr title=\"id: renderer, filename: texture\"\u003e`id, filename`\u003c/abbr\u003e ➔ `id` | [IMG_LoadTexture](https://wiki.libsdl.org/SDL2_image/IMG_LoadTexture) |\n|🗹| `gfx.renderTexture` | \u003cabbr title=\"id: renderer, id: texture, box: texture area, box: renderer location\"\u003e`id, id, box, box`\u003c/abbr\u003e | [SDL_RenderCopy](https://wiki.libsdl.org/SDL2/SDL_RenderCopy) |\n|--| `gfx.renderRotatedTexture` \u003cabbr title=\"id: renderer, id: texture, box: texture area, box: renderer location, number: angle, int: flags\"\u003e`id, id, box, box, angle, flags`\u003c/abbr\u003e | [SDL_RenderCopyEx](https://wiki.libsdl.org/SDL2/SDL_RenderCopyEx) |\n|--| `gfx.colorTexture` | `id, rgb` | [SDL_SetTextureColorMod](https://wiki.libsdl.org/SDL2/SDL_SetTextureColorMod) |\n|--| `gfx.alphaTexture` | `id, alpha` | [SDL_SetTextureAlphaMod](https://wiki.libsdl.org/SDL2/SDL_SetTextureAlphaMod) |\n|--| `gfx.blendModeTexture` | `id, flags` | [SDL_BlendMode](https://wiki.libsdl.org/SDL2/SDL_BlendMode) |\n|--| `gfx.scaleModeTexture` | `id, flags` | [SDL_SetTextureScaleMode](https://wiki.libsdl.org/SDL2/SDL_SetTextureScaleMode)\n|--| `gfx.readRenderer` | `id, box` ➔ \u003cabbr title=\"list: rgba values\"\u003e`list`\u003c/abbr\u003e | [SDL_RenderReadPixels](https://wiki.libsdl.org/SDL2/SDL_RenderReadPixels) |\n|--| `gfx.loadFont` | `filepath, ptsize` ➔ `id`  | [TTF_OpenFont](https://wiki.libsdl.org/SDL2_ttf/TTF_OpenFont) |\n|--| `gfx.destroyFont` | `id` | [TTF_CloseFont](https://wiki.libsdl.org/SDL2_ttf/TTF_CloseFont) |\n|--| `gfx.measureFont` | `id, text, width` ➔ `chars` | *Return the number of characters* [TTF_MeasureUTF8](https://wiki.libsdl.org/SDL2_ttf/TTF_MeasureUTF8) |\n|--| `gfx.resizeFont` | `id, ptsize` | [TTF_SetFontSize](https://wiki.libsdl.org/SDL2_ttf/TTF_SetFontSize) |\n|--| `gfx.getStyleFont` | `id` ➔ `flags` | [TTF_GetFontStyle](https://wiki.libsdl.org/SDL2_ttf/TTF_GetFontStyle) |\n|--| `gfx.setStyleFont` | `id, flags` | [TTF_SetFontStyle](https://wiki.libsdl.org/SDL2_ttf/TTF_SetFontStyle) |\n|--| `gfx.renderFontSolid` | `id, string` | [TTF_RenderUNICODE_Solid](https://wiki.libsdl.org/SDL2_ttf/TTF_RenderUTF8_Solid) |\n|--| `gfx.renderFontBlended` | `id, string` | [TTF_RenderUNICODE_Blended](https://wiki.libsdl.org/SDL2_ttf/TTF_RenderUTF8_Blended) |\n\n\u003c!-- \n    SDL_SetTextureUserData ? direct manipulating of pixels\n    SDL_LockTexture + SDL_UnlockTexture ? possibly needed for texture i/o operations\n    SDL_RenderGeometry maybe for adding 3D/hand-rendering\n--\u003e\n\n\u003c!--\n    TODO:\n\n    - Extensions API\n\n    All of following should be *OPTIONAL* and added by includng them\n    with the Moongin Extensions API\n\n    - 3D rendering functions\n    - model loader functions\n    - audio functions\n    - generic API for Achievements\n--\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnalexinl%2Fmoongin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnalexinl%2Fmoongin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnalexinl%2Fmoongin/lists"}