Chichi Munga

Archives
Bluesky
Log in
Subscribe
Aug. 9, 2026, 5:50 p.m.

A Little Refactoring and Tidying Up

Chichi Munga

Since last week, I've updated the tiles to something less distracting and closer to the art style I can create. I can't wait to learn pixel art, by the way — I already bought Aseprite but have managed to hold off using it for now.

I added icons for strength and magic weapons. Right now each weapon is a 16x16 sprite, but I want them to span multiple tiles — a sword in the player's inventory would look like the letter "t," a staff like the letter "l." You get the picture.

I also learned about Camera2d's limit method, which stops the camera from following the character so it can expose the level's bounds. Before I found it, I'd planned to detach the camera from the player and lock it onto a tile whenever the level's edges came into view. Setting limits was much easier.

A GIF of a 16x16 sprite traversing a 2d level

I stupidly skipped creating a Grid when I started building the level and inventory. Building it after the fact took a while, but I can already tell, from the handful of methods I've added, how useful this class will be for future games. I also understand Godot doesn't have a package manager like NPM, and I'm curious what installing packages looks like if I'm not just copy/pasting code.

class_name Grid
extends RefCounted

## Builds out both the level and inventory grids.
## Provides helper methods for the grid.

var num_cols: int
var num_rows: int
var _tiles: Array[Array] = []


## RefCounted isn't a node so we use _init() instead of _ready().
func _init(cols: int, rows: int, def_val: Variant) -> void:
    num_cols = cols
    num_rows = rows

    var base_state_col: Array = []
    base_state_col.resize(rows)
    base_state_col.fill(def_val)

    for col in cols:
        _tiles.append(base_state_col.duplicate())


## Returns the given tile's state.
func get_tile(coords: Vector2i) -> Variant:
    return _tiles[coords.x][coords.y]


## Sets the given tile's state with the provided value.
func set_tile(coords: Vector2i, val: Variant) -> void:
    _tiles[coords.x][coords.y] = val


## Determines if the given tile exists inside the grid.
func is_in_bounds(coords: Vector2i) -> bool:
    return coords.x >= 0 and coords.x < num_cols and coords.y >= 0 and coords.y < num_rows


## Determines if the given tile is vacant.
func is_vacant_tile(coords: Vector2i, vac_tile: Variant) -> bool:
    return _tiles[coords.x][coords.y] == vac_tile


## Checks if an entity can move to the given coordinates.
func is_walkable_tile(coords: Vector2i, vac_tile: Variant) -> bool:
    return is_in_bounds(coords) and is_vacant_tile(coords, vac_tile)


## Determines if the given tile is on the edge of the grid.
func is_edge_tile(coords: Vector2i) -> bool:
    return coords.x == 0 or coords.x == num_cols - 1 or coords.y == 0 or coords.y == num_rows - 1


## Loops through each tile and run the callback function.
func for_each_tile(xy: Vector2i, cb: Callable) -> void:
    for col in xy.x:
        for row in xy.y:
            cb.call(Vector2i(col, row))

Next, I need to make the active column stand out more. More importantly, I need to figure out where the weapons will do damage. Right now the character auto-attacks the tile in front of them after moving, which is boring, and I still don't know how to implement or show the player which tiles a weapon will hit. Thinking, thinking...

You just read issue #4 of Chichi Munga. You can also browse the full archives of this newsletter.

← Newer I Made Some Weapons Older → WASD Dwarf

Add a comment:

Posting this comment will subscribe you to this newsletter with the email address you enter.
Powered by Buttondown, the easiest way to start and grow your newsletter.