{"id":13568066,"url":"https://github.com/greenfork/nimraylib_now","last_synced_at":"2025-04-04T04:30:45.895Z","repository":{"id":43269880,"uuid":"327959735","full_name":"greenfork/nimraylib_now","owner":"greenfork","description":"The Ultimate Raylib gaming library wrapper for Nim","archived":true,"fork":false,"pushed_at":"2023-04-15T06:27:11.000Z","size":10875,"stargazers_count":149,"open_issues_count":17,"forks_count":16,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-05T00:34:56.306Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/greenfork.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-01-08T16:47:41.000Z","updated_at":"2024-10-03T11:41:09.000Z","dependencies_parsed_at":"2024-01-14T03:46:22.229Z","dependency_job_id":"baca0d05-635c-4022-b7f8-c99740301e7e","html_url":"https://github.com/greenfork/nimraylib_now","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greenfork%2Fnimraylib_now","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greenfork%2Fnimraylib_now/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greenfork%2Fnimraylib_now/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greenfork%2Fnimraylib_now/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/greenfork","download_url":"https://codeload.github.com/greenfork/nimraylib_now/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247123071,"owners_count":20887259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-01T14:00:19.577Z","updated_at":"2025-04-04T04:30:40.886Z","avatar_url":"https://github.com/greenfork.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# End of life\n\nThe project will no longer be maintained. Reasons:\n\n- I personally don't do any game development for some time now.\n\n- The approach of automatic bindings generation was very new and easy to\n  maintain. Unfortunately as the Nim language progresses, it adds a lot of\n  features that help with automatic memory management, boundary detection and\n  other quality of life things. It is not feasible to automatically generate\n  these things, so the whole approach doesn't look very lucrative to continue\n  with. Proper Nim bindings will require lots of manual code to accomodate all\n  the fascinating language features.\n\nThe successor bindings can be considered \u003chttps://github.com/planetis-m/naylib\u003e,\nfeel free to take a look at them! Other projects can also emerge but as of\n2023-04-15 these bindings look like the most promising ones.\n\nFeel free to fork this repository and do anything with the code, happy hacking!\n\n# NimraylibNow! - The Ultimate Raylib wrapper for Nim\n\nThe most idiomatic and up-to-date wrapper for [Raylib] gaming C library.\nUse this library if you want to write games using [Raylib] in [Nim].\n\nThis library is an effort to create an automatically generated wrapper which can\nbe easily upgraded to any future version of [Raylib]. Anyone should be able to\nupgrade it with some effort and [HACKING](HACKING.md) should be a guide on how\nto do it. Please file a bug report if any of that is too far from the reality.\n\n[Nim]: https://nim-lang.org/\n\n## Features\n\n* Automated generation of the wrapper using the power of (((Nim)))\n\n* Idiomatic Nim naming and conventions so you write **Nim** code, not C\n\n* 60+ [examples](examples/) converted from C to Nim\n\n* Includes modules: [raylib], [raymath], [rlgl], [raygui], [physac]\n\n* Supports Windows, Linux, MacOS, Emscripten (see [Emscripten example])\n\n* Supports static compilation, dynamic linking - you choose\n\n[raylib]: https://github.com/raysan5/raylib\n[raymath]: https://github.com/raysan5/raylib/blob/master/src/raymath.h\n[rlgl]: https://github.com/raysan5/raylib/blob/master/src/rlgl.h\n[raygui]: https://github.com/raysan5/raygui\n[physac]: https://github.com/raysan5/raylib/blob/master/src/physac.h\n[Emscripten example]: examples/emscripten/\n\n## Quickstart\n\n1. Install NimraylibNow!\n```shell\n$ nimble install nimraylib_now  # wait 10 minutes for download, sorry\n```\n2. Copy any example to your file, for instance [crown.nim](examples/original/crown.nim)\n3. Compile and run it:\n```shell\n$ nim c -r -d:release --gc:orc crown.nim\n```\n\nExplanation of flags:\n- `-r` - run after compiling\n- `-d:release` - for speed, but also cuts away debugging information\n- `--gc:orc` - memory management without garbage collection and\n  with better C interoperability\n\n## Current version and upgrading from previous versions\n\nNimraylibNow! v0.15 is a wrapper for [Raylib v4.2.0] and [Raygui v3.2] and works\nfor Nim v1.4.2+.\n\nSee [CHANGELOG](CHANGELOG.md) for any tips on how to upgrade your code\nfrom previous versions.\n\n[Raylib v4.2.0]: https://github.com/raysan5/raylib/releases/tag/4.2.0\n[Raygui v3.2]: https://github.com/raysan5/raygui/releases/tag/3.2\n\n## Install NimraylibNow!\n\nInstall this library with nimble (takes **6-10(!) minutes** because of huge\noriginal raylib repository):\n```shell\n$ nimble install nimraylib_now\n```\n\nOr put it into your `.nimble` file:\n```nim\nrequires \"nimraylib_now\"\n```\n\n## How to use NimraylibNow!\n\nImport any necessary modules and use it:\n\n```nim\n# Import everything but rlgl, should be enough for most cases!\nimport nimraylib_now\n\n# Import only necessary modules for more granularity\nimport nimraylib_now/raylib\nimport nimraylib_now/[raylib, raymath, raygui]\nfrom nimraylib_now/rlgl as rl import nil  # import rlgl with a mandatory prefix rl\n```\n\nSee [examples](examples/) for how to use it.\nYou should generally be able to follow any tutorials for official C bindings,\njust mind the [naming](#naming-differences-with-c). Also see official\n[cheatsheet](https://www.raylib.com/cheatsheet/cheatsheet.html) and\ndirectly inspect the binding sources, e.g. for\n[raylib](src/nimraylib_now/not_mangled/raylib.nim).\n\nHere is a long example to showcase most features\n([crown.nim](examples/original/crown.nim)).\n\n```nim\nimport math\nimport nimraylib_now\n\nconst\n  nimFg: Color = (0xff, 0xc2, 0x00)          # Use this shortcut with alpha = 255!\n  nimBg: Color = (0x17, 0x18, 0x1f)\n\n# Let's draw a Nim crown!\nconst\n  crownSides = 8                             # Low-polygon version\n  centerAngle = 2.0 * PI / crownSides.float  # Angle from the center of a circle\n  lowerRadius = 2.0                          # Lower crown circle\n  upperRadius = lowerRadius * 1.4            # Upper crown circle\n  mainHeight = lowerRadius * 0.8             # Height without teeth\n  toothHeight = mainHeight * 1.3             # Height with teeth\n  toothSkew = 1.2                            # Little angle for teeth\n\nvar\n  lowerPoints, upperPoints: array[crownSides, tuple[x, y: float]]\n\n# Get evenly spaced points on the lower and upper circles,\n# use Nim's math module for that\nfor i in 0..\u003ccrownSides:\n  let multiplier = i.float\n  # Formulas are for 2D space, good enough for 3D since height is always same\n  lowerPoints[i] = (\n    x: lowerRadius * cos(centerAngle * multiplier),\n    y: lowerRadius * sin(centerAngle * multiplier),\n  )\n  upperPoints[i] = (\n    x: upperRadius * cos(centerAngle * multiplier),\n    y: upperRadius * sin(centerAngle * multiplier),\n  )\n\ninitWindow(800, 600, \"[nim]RaylibNow!\")  # Open window\n\nvar camera = Camera(\n  position: (5.0, 8.0, 10.0),  # Camera position\n  target: (0.0, 0.0, 0.0),     # Camera target it looks-at\n  up: (0.0, 1.0, 0.0),         # Camera up vector (rotation over its axis)\n  fovy: 45.0,                  # Camera field-of-view apperture in Y (degrees)\n  projection: Perspective      # Defines projection type, see CameraProjection\n)\ncamera.setCameraMode(Orbital)  # Several modes available, see CameraMode\n\nvar pause = false              # Pausing the game will stop animation\n\nsetTargetFPS(60)               # Set the game to run at 60 frames per second\n\n# Wait for Esc key press or when the window is closed\nwhile not windowShouldClose():\n  if not pause:\n    camera.addr.updateCamera   # Rotate camera\n\n  if isKeyPressed(Space):      # Pressing Space will stop/resume animation\n    pause = not pause\n\n  beginDrawing:                # Use drawing functions inside this block\n    clearBackground(RayWhite)  # Set background color\n\n    beginMode3D(camera):       # Use 3D drawing functions inside this block\n      drawGrid(10, 1.0)\n\n      for i in 0..\u003ccrownSides:\n        # Define 5 points:\n        # - Current lower circle point\n        # - Current upper circle point\n        # - Next lower circle point\n        # - Next upper circle point\n        # - Point for peak of crown tooth\n        let\n          nexti = if i == crownSides - 1: 0 else: i + 1\n          lowerCur: Vector3 = (lowerPoints[i].x, 0.0, lowerPoints[i].y)\n          upperCur: Vector3 = (upperPoints[i].x, mainHeight, upperPoints[i].y)\n          lowerNext: Vector3 = (lowerPoints[nexti].x, 0.0, lowerPoints[nexti].y)\n          upperNext: Vector3 = (upperPoints[nexti].x, mainHeight, upperPoints[nexti].y)\n          tooth: Vector3 = (\n            (upperCur.x + upperNext.x) / 2.0 * toothSkew,\n            toothHeight,\n            (upperCur.z + upperNext.z) / 2.0 * toothSkew\n          )\n\n        # Front polygon (clockwise order)\n        drawTriangle3D(lowerCur, upperCur, upperNext, nimFg)\n        drawTriangle3D(lowerCur, upperNext, lowerNext, nimFg)\n\n        # Back polygon (counter-clockwise order)\n        drawTriangle3D(lowerCur, upperNext, upperCur, nimBg)\n        drawTriangle3D(lowerCur, lowerNext, upperNext, nimBg)\n\n        # Wire line for polygons\n        drawLine3D(lowerCur, upperCur, Gray)\n\n        # Crown tooth front triangle (clockwise order)\n        drawTriangle3D(upperCur, tooth, upperNext, nimFg)\n\n        # Crown tooth back triangle (counter-clockwise order)\n        drawTriangle3D(upperNext, tooth, upperCur, nimBg)\n\n    block text:\n      block:\n        let\n          text = \"I AM NIM\"\n          fontSize = 60\n          textWidth = measureText(cstring(text), fontSize)\n          verticalPos = (getScreenHeight().float * 0.4).int\n        drawText(\n          cstring(text),\n          (getScreenWidth() - textWidth) div 2,  # center\n          (getScreenHeight() + verticalPos) div 2,\n          fontSize,\n          Black\n        )\n      block:\n        let text =\n          if pause: \"Press Space to continue\"\n          else: \"Press Space to pause\"\n        drawText(cstring(text), 10, 10, 20, Black)\n\ncloseWindow()\n```\n\n![Nim crown drawn with polygons](crown.png?raw=true)\n\n## Naming differences with C\nNaming is converted to more Nim conventional style but in a predictable manner.\nGenerally just omit any prefixes you see in official docs and use camelCase for\nprocs, everything else stays the same:\n```c\nvoid InitWindow(int width, int height, const char *title);\nvoid GuiSetState(int state);\nvoid rlBegin(int mode);\n```\nto\n```nim\nproc initWindow*(width: cint; height: cint; title: cstring)\nproc setState*(state: cint)\nproc begin*(mode: cint)\n```\n\nAlthough some definitions may have names like `FULLSCREEN_MODE`, you can still\nuse them (and encouraged to) as `FullscreenMode` in code.\n\n### Raymath\n\nAll prefixes specific to types were omitted where possible:\n```c\nVector2 Vector2Zero(void);\nVector3 Vector3Zero(void);\n\nVector2 Vector2Add(Vector2 v1, Vector2 v2);\nVector3 Vector3Add(Vector3 v1, Vector3 v2);\n```\nto\n```nim\nproc vector2Zero*(): Vector2\nproc vector3Zero*(): Vector3\n\nproc add*(v1: Vector2; v2: Vector2): Vector2\nproc add*(v1: Vector3; v2: Vector3): Vector3\n```\n\n## Passing values by addresses\n**BE VERY CAREFUL** with values which are passed as addresses, **always** convert\nthem to approapriate C-compatible types:\n```nim\n# Will do incorrect things!\nvar\n  xPos = 0.0  # this is `float` type, will not be converted to `cfloat` automatically\n  cameraPos = [xPos, camera.position.y, camera.position.z]\nsetShaderValue(shader, viewEyeLoc, cameraPos.addr, Vec3)  # cameraPos.addr is a pointer\n\n# Convert values instead\nvar xPos: cfloat = 0.0\n# or\nvar cameraPos = [xPos.cfloat, camera.position.y, camera.position.z]\n# So this finally works as intended:\nsetShaderValue(shader, viewEyeLoc, cameraPos.addr, Vec3)\n```\n\n## Tips and tricks\n### Tuple to object converters for geometry\nVector2, Vector3, Vector4 (Quaternion), Matrix, Rectangle, Color can be written\nas a tuple to save on typing as they have pretty much standard parameter\nsequence:\n\n```nim\n# All are valid:\nvar\n  v1: Vector2 = (x: 3.0, y: 5.0)\n  v2 = Vector2(x: 3.0, y: 5.0)\n  v3 = (3.0, 5.0)\n  c: Color = (0xc9, 0xc9, 0xc9)  # color can be written as a tuple even without the alpha value!\n```\n\n### Require fully qualified procs\nFor functions operating on global scope it could be convenient to use\nfully qualified proc name:\n```nim\nrlgl.begin(rlgl.Triangles)\n# draw something\nrlgl.end()\n```\nwhich can be enforced by the compiler by importing `rlgl` module like this:\n```nim\nfrom nimraylib_now/rlgl import nil\n\n# or to use a shorter `rl`\nfrom nimraylib_now/rlgl as rl import nil\n```\n\n### Begin-End pairs sugar\nThere are pairs like `beginDrawing()` - `endDrawing()`, each have helping\ntemplates to automatically insert `end`-proc at the end:\n```nim\nbeginDrawing:\n  drawLine(...)\n```\nis same as\n```nim\nbeginDrawing()\ndrawLine(...)\nendDrawing()\n```\n\n### Reserved words\nBe careful and use \"stropping\" when using fields or functions which are also\nreserved words in Nim:\n```nim\n`end`()\n```\n\n### Enums\nAll enums are marked as `{.pure.}` which means they should be fully qualified\nwhen compiler can't guess their type:\n```nim\ncamera.projection = Perspective  # can be guessed, no need for CameraProjection.Perspective\nif isKeyDown(Right):             # can be guessed, no need for KeyboardKey.Right\nif KeyboardKey.Right.isKeyDown:  # cannot be guessed\n```\n\n### Raymath infix operators\nYou can use infix operators like `+`, `-`, `*`, `/` for operations on vectors,\nmatrices and quaternions:\n```nim\nlet\n  v1 = Vector3(x: 5, y: 2, z: 1)\n  v2 = Vector3(x: 3, y: 0, z: 0)\nassert v1 - v2 == Vector3(x: 2.0, y: 2.0, z: 1.0)\n```\n\n## Raylib, the original C library\n\nIf you would like to know more about how this wrapper uses [Raylib] library\nand see all the different options, check [USING_RAYLIB](/USING_RAYLIB.md),\nit should help.\n\n## Contributing\n\nDo you want to contribute but don't know how? Check out\n[CONTRIBUTING](CONTRIBUTING.md)!\n\n## How does wrapper work?\n\nIf you would like to know how this wrapper works or how to update it, check\nout [HACKING](HACKING.md).\n\n## Troubleshooting\n### Freezes on Wayland\nRandom freezes when everything stops being responsive can be caused by glfw\ncompiled against Wayland library. Try X11 version of glfw.\n\n[GLFW] is a raylib dependency that was installed by your package manager, you\ncan uninstall raylib with clearing all of its dependencies and install it again\nchoosing X11 version of glfw.\n\n[GLFW]: https://www.glfw.org/\n\n### Windows error: The application was unable to start correctly (0x00000007b)\nOr similar errors which point to missing `libwinpthread-1.dll` file mean that\nwindows can't find correct library files.\n\nThis is because, by default, nim creates binaries that are dynamically linked.\nNormally, this is fine since windows already has the libraries required for most\nbasic nim applications. It does not however have libwinpthread-1.dll, which causes an error here.\nWe can solve this by instructing nim to create binaries with the libraries\nlinked statically.\n\nTo do this just pass in the `--passL:-static` to nim when compiling your file.\n\nIf you still want dynamic linking:\n\n- If MinGW is not in PATH\n- Add Nim's minGW toolchain to your PATH (You have to add the bin directory with .dll files not the one where nim.exe is located)\n\nIf you already have a version of MinGW (that is already on PATH and seperate from Nim)\n- Copy over `libwinpthread-1.dll` from nim's version of MinGW into the bin directory of your version of MinGW\n\n### NixOS: GLX: Failed to load GLX\n\nThere are two options:\n- Install Raylib shared library via the package manager, use `nim build -d:nimraylib_now_shared` to use a shared library.\n- Use `steam-run` to execute the final binary.\n- See [USING_RAYLIB](/USING_RAYLIB.md) for manual Raylib installation option.\n\n## Community\n\nFind us at `#raylib-nim` channel\nin the official [Raylib discord server](https://discord.gg/raylib).\n\n## Thanks\n\nMany thanks to V.A. Guevara for the efforts on [Raylib-Forever] library which\nwas the initial inspiration for this library.\n\n[Raylib-Forever]: https://github.com/Guevara-chan/Raylib-Forever\n\nThanks to everyone who contributed to this project!\n\n## License\n\nMIT licensed, see LICENSE.md.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreenfork%2Fnimraylib_now","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgreenfork%2Fnimraylib_now","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreenfork%2Fnimraylib_now/lists"}