Skip to content

Nicer map handling in lua#164

Merged
LiquidityC merged 2 commits intodevfrom
better_lua_map_handling
Mar 20, 2026
Merged

Nicer map handling in lua#164
LiquidityC merged 2 commits intodevfrom
better_lua_map_handling

Conversation

@LiquidityC
Copy link
Member

@LiquidityC LiquidityC commented Mar 20, 2026

map no longer needs to be a global variable.

Summary by CodeRabbit

  • Refactor
    • Map generation was reworked to use explicit, returned map objects rather than implicit globals, and texture-loading helpers now operate on the provided map instance.
    • Internal validation/error messages were simplified and stack handling made more robust.
    • Improves stability and predictability of map creation and asset loading with no user-facing behavior changes.

@LiquidityC LiquidityC enabled auto-merge (squash) March 20, 2026 07:56
@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

📝 Walkthrough

Walkthrough

Map generation was refactored to avoid global map usage: scripts now create a local map and return it; texture-loading helpers accept a map parameter; the C Lua binding was updated to read the returned map from the Lua stack instead of fetching a global.

Changes

Cohort / File(s) Summary
Map generation refactoring
data/mapgen.lua, data/menumapgen.lua
Replaced global map = create_map(...) with local map = create_map(...) and added return map at script end so callers receive the generated Map explicitly.
Texture loading updates
data/maproombuilder.lua
Changed load_decor_textures and load_special_tiles to accept a map parameter; module.load_textures(map) now forwards the map to these helpers instead of relying on outer-scope globals.
Lua C bindings
src/map_lua.c
Removed use of lua_getglobal(L, "map") in generate_map(); now extracts the returned Map* from the top of the Lua stack via luaL_checkmap(L, -1). Simplified some validation/fatal messages.

Sequence Diagram(s)

sequenceDiagram
    participant C as C (generate_map)
    participant Lua as Lua mapgen script
    participant Builder as maproombuilder
    participant Map as Map object

    C->>Lua: call map generation (lua_call)
    Lua->>Map: local map = create_map(...)
    Lua->>Builder: module.load_textures(map)
    Builder->>Builder: load_decor_textures(map) / load_special_tiles(map)
    Builder-->>Lua: textures added to map
    Lua->>Map: populate rooms / monsters / traps / chests
    Lua-->>C: return map (push userdata onto stack)
    C->>C: luaL_checkmap(L, -1) -> obtain Map*
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • enforce lua formatting #154 — Similar refactor converting global map usage to returned/local maps and updating texture-loader interfaces and C binding stack handling.

Poem

🐰
Maps hopped out from global fog to light,
Now carried home in tidy return-flight.
Helpers learn to cuddle maps by name,
The stack now hands back what once had shame.
A rabbit cheers: explicit paths take flight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Nicer map handling in lua' accurately captures the main objective of the pull request: refactoring map handling in Lua to eliminate the need for a global map variable by using local declarations and explicit return values instead.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch better_lua_map_handling
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

map no longer needs to be a global variable.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/map_lua.c (1)

707-713: ⚠️ Potential issue | 🔴 Critical

Validate Lua return before dereferencing map pointer.

Line 712 uses unchecked lua_touserdata(L, -1) and line 718 immediately dereferences it without validation. If the script returns nil/non-pointer (or unexpected extra returns with LUA_MULTRET), this crashes.

🔧 Proposed fix
-	result = lua_pcall(L, 0, LUA_MULTRET, 0);
+	result = lua_pcall(L, 0, 1, 0);
 	if (result) {
 		fatal("Failed to run script: %s\n", lua_tostring(L, -1));
 	}
 
-	Map *map = lua_touserdata(L, -1);
+	Map *map = luaL_checkmap(L, -1);

luaL_checkmap() (defined at line 72) validates the type and null-checks before returning, consistent with how it's used throughout the rest of the file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/map_lua.c` around lines 707 - 713, The code calls lua_pcall(L, 0,
LUA_MULTRET, 0) and then directly uses lua_touserdata(L, -1) which can return
nil or a wrong type; replace the unchecked lua_touserdata usage with the type-
and null-checked helper luaL_checkmap(L, -1) (the existing function defined at
line 72) to validate the returned value before dereferencing the Map pointer,
and keep the fatal/log behavior consistent if luaL_checkmap reports an error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/map_lua.c`:
- Around line 707-713: The code calls lua_pcall(L, 0, LUA_MULTRET, 0) and then
directly uses lua_touserdata(L, -1) which can return nil or a wrong type;
replace the unchecked lua_touserdata usage with the type- and null-checked
helper luaL_checkmap(L, -1) (the existing function defined at line 72) to
validate the returned value before dereferencing the Map pointer, and keep the
fatal/log behavior consistent if luaL_checkmap reports an error.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 71e21407-a351-4ae9-854f-aa7bcf6d5fd0

📥 Commits

Reviewing files that changed from the base of the PR and between c05b0f5 and 939e1e8.

📒 Files selected for processing (4)
  • data/mapgen.lua
  • data/maproombuilder.lua
  • data/menumapgen.lua
  • src/map_lua.c

@LiquidityC LiquidityC disabled auto-merge March 20, 2026 08:03
@LiquidityC LiquidityC enabled auto-merge (squash) March 20, 2026 08:13
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/map_lua.c (1)

707-713: Harden the Lua contract by requesting exactly one return value.

The generator scripts (mapgen.lua and menumapgen.lua) currently return only a map value. However, using LUA_MULTRET means the code depends on the map being the last returned value. Requesting exactly one result makes the interface explicit and prevents breakage if a script accidentally returns extra values.

Proposed hardening diff
-	result = lua_pcall(L, 0, LUA_MULTRET, 0);
+	result = lua_pcall(L, 0, 1, 0);
 	if (result) {
 		fatal("Failed to run script: %s\n", lua_tostring(L, -1));
 	}
 
 	Map *map = luaL_checkmap(L, -1);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/map_lua.c` around lines 707 - 713, The call to lua_pcall currently uses
LUA_MULTRET which allows any number of return values and relies on the map being
the last; change the pcall invocation in this block (lua_pcall) to request
exactly 1 result instead of LUA_MULTRET so the script contract is explicit, then
keep using luaL_checkmap(L, -1) to fetch that single return value; ensure the
existing error path (fatal with lua_tostring) remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/map_lua.c`:
- Around line 707-713: The call to lua_pcall currently uses LUA_MULTRET which
allows any number of return values and relies on the map being the last; change
the pcall invocation in this block (lua_pcall) to request exactly 1 result
instead of LUA_MULTRET so the script contract is explicit, then keep using
luaL_checkmap(L, -1) to fetch that single return value; ensure the existing
error path (fatal with lua_tostring) remains unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: de824751-726f-4f42-955a-cb85f2759411

📥 Commits

Reviewing files that changed from the base of the PR and between 939e1e8 and c3f1f50.

📒 Files selected for processing (1)
  • src/map_lua.c

@LiquidityC LiquidityC merged commit 295db79 into dev Mar 20, 2026
12 checks passed
@LiquidityC LiquidityC deleted the better_lua_map_handling branch March 20, 2026 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant