{"id":26094076,"url":"https://github.com/statismike/grid-forge","last_synced_at":"2026-04-17T18:32:45.173Z","repository":{"id":235578442,"uuid":"790948193","full_name":"StatisMike/grid-forge","owner":"StatisMike","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-12T08:24:52.000Z","size":21358,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-08T04:57:27.668Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StatisMike.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-04-23T20:19:21.000Z","updated_at":"2025-07-20T15:22:42.000Z","dependencies_parsed_at":"2025-12-05T15:04:04.862Z","dependency_job_id":null,"html_url":"https://github.com/StatisMike/grid-forge","commit_stats":null,"previous_names":["statismike/proc_grid"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/StatisMike/grid-forge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatisMike%2Fgrid-forge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatisMike%2Fgrid-forge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatisMike%2Fgrid-forge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatisMike%2Fgrid-forge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StatisMike","download_url":"https://codeload.github.com/StatisMike/grid-forge/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatisMike%2Fgrid-forge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31940873,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T17:29:20.459Z","status":"ssl_error","status_checked_at":"2026-04-17T17:28:47.801Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2025-03-09T12:49:43.857Z","updated_at":"2026-04-17T18:32:45.155Z","avatar_url":"https://github.com/StatisMike.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# grid-forge\n\nGeneric abstraction for grid maps.\n\nI've found it pretty frustrating that every engine of framework have their own way of handling grid maps. This made any attempts at generic\nsolutions for common problems not easily applicable.\n\n`grid-forge` tries to solve this problem, providing a generic abstraction for grid maps - currently only 2D rectangular grids are supported,\n3D grids are planned as well, and possibly support for other shapes in the future.\n\n## Basic functionality\n\nData hold for each tile in the grid is very flexible, and can be anything that is needed. Just implement a `TileData` marker trait and you are good to go.\n\n```rust\nuse grid_forge::TileData;\n\nenum TileColor {\n    Blue,\n    Green,\n}\n\nstruct TwoColoredTile {\n    color: TileColor,\n}\n\nimpl TileData for TwoColoredTile {}\n```\n\nSuch data can then be placed inside of the `GridMap2D`, and used hovewer you want. Outside of the grid, the data is always contained\nwithin one of the `TileContainer` implementors:\n\n- `GridTile\u003cT\u003e` - container owning the data for a tile.\n- `GridRef\u003cT\u003e` - reference to the data for a tile.\n- `GridRefMut\u003cT\u003e` - mutable reference to the data for a tile.\n\n```rust\nlet size = GridSize::new_xy(100, 100);\nlet mut map = GridMap2D::\u003cTwoColoredTile\u003e::new(size);\nlet mut rng = thread_rng();\n\nfor pos in map.size().get_all_possible_positions() {\n    let color = if rng.gen_bool(0.5) {\n        TileColor::Blue\n    } else {\n        TileColor::Green\n    };\n    let tile = GridTile::new(pos, TwoColoredTile { color });\n    map.insert_tile(tile);\n}\n```\n\nIt can be then retrieved from the GridMap in such a container, holding alongside your data the position of the tile.\n\nIts tends to be useful when you would want to pass the data further through the function - information about its position is often\ncrucial.\n\n```rust\nlet pos = GridPosition::new_xy(10, 10);\nlet tile: GridRef\u003cTwoColoredTile\u003e = map.get_tile_at_position(\u0026pos);\n\nassert_eq!(tile.grid_position(), pos);\n\nlet mut tile: GridRefMut\u003cTwoColoredTile\u003e = map.get_mut_tile_at_position(\u0026pos);\nassert_eq!(tile.grid_position(), pos);\n\ntile.as_mut().color = TileColor::Blue;\n```\n\n### Identifiable tile data\n\nThere are often times when you want to use a finite set of tiles, which share some common baseline properties - and often holding all of these properties inside of the grid is not desirable.\n\nFor this reason, there is a `IdentifiableTileData` trait - holding an unique identifier for each *tile type*.\n\n```rust\nstruct TwoColoredTile {\n    tile_type_id: u64,\n    color: TileColor,\n}\n\nimpl IdentifiableTileData for TwoColoredTile {\n    fn tile_type_id(\u0026self) -\u003e u64 {\n        self.tile_type_id\n    }\n}\n```\n\nThis allows for storing additional data specific to each tile type in some other container (e.g. one implementing provided `IdentTileCollection` trait) and also easily creating new tile instance of specific type.\n\n```rust\nimpl ConstructableViaIdentifierTile for TwoColoredTile {\n    fn tile_new(tile_type_id: u64) -\u003e Self {\n        if tile_type_id == 0 {\n            Self { tile_type_id, color: TileColor::Blue }\n        } else {\n            Self { tile_type_id, color: TileColor::Green }\n        }\n    }\n}\n```\n\n`IdentifiableTileData` is used by some built-in tile types used by different more specialized functionalities.\n\n### Visual representation of tiles\n\nThere are some basic visualization methods provided within the `grid-forge`, lying under the `#[vis]` feature flag. These are most useful for loading and saving 2D grid maps from/to image files, and use `image` crate under the hood.\n\n`VisTileData` make it easy to generate visual representation of the tile data *dynamically*, eg. by using some other characteristics of the tile.\n\n```rust\nstruct TwoColoredTile {\n    color: TileColor,\n}\n\n// Each tile will be represented by 10x10 RGB pixels.\nimpl\u003cDefaultVisPixel, 10, 10\u003e VisTileData for TwoColoredTile {\n    fn vis_pixels(\u0026self) -\u003e [[DefaultVisPixel; 1]; 1] {\n      let pixel = match self.color {\n          TileColor::Blue =\u003e [[DefaultVisPixel::new([0, 0, 255])]],\n          TileColor::Green =\u003e [[DefaultVisPixel::new([0, 255, 0])]],\n      }\n      vec![vec![pixel; 10]; 10]\n    }\n}\n```\n\nThere are also options associated with `VisCollection` struct, which holds visual representation of each `IdentifiableTileData` tile type - making it kind of naive and basic resource system.\n\n### Procedural generation\n\nThere is a whole procedural generation module, at the moment containing two kind of generators:\n\n- basic *Random Walk algorithm* - see `gen_walker` example.\n- collapsible tile generation (Model Synthesis/Wave function collapse) - see `gen_collapse_overlap` and `gen_collapse_singular` examples. \n\n### Godot integration\n\n`godot` module contains a collection of structs allowing for easy roundtrips between Godot's and `grid-forge` data structures, using `IdentifiableTileData` trait to synchronize the data between the two sources. \n\nFor Rust-Godot communication it uses GDExtension `godot-rust` crate.\n\nSee `example_godot` crate for an example of simple Godot App using the `grid-forge` for loading the map from image file and procedural generation, rendering it in Godot's `TileMap` class. ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatismike%2Fgrid-forge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstatismike%2Fgrid-forge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatismike%2Fgrid-forge/lists"}