Guidance for AI coding agents working in this repository.
RedMew is a Factorio scenario written in Lua. It provides custom maps, map generation, gameplay features and server tooling for the RedMew community servers.
control.lua— scenario entry point; loads modules based onconfig.luaconfig.lua— central configuration; feature toggles live heremap_gen/— map generation; playable maps inmap_gen/maps/map_gen/data/— do not read these files (see warning below)
features/— gameplay feature modules (each toggled viaconfig.lua)utils/— shared helper modules (math,string,event,global, ...)resources/— data-stage and lifecycle helperslocale/— translations;.cfgfiles only (sorted, English first)scenario_templates/— optional per-scenario override folders (see below)docs/— additional docs (mostly moved to the project wiki)
Never open or read files under map_gen/data/ (especially map_gen/data/presets/, e.g. factory.lua is ~13 MB). They hold huge generated pixel/picture data used to build image-based maps and will blow up the context window in one read. Grep with head_limit if you must locate something there, but do not dump file contents. (These files are also excluded from luacheck via .luacheckrc.)
- To run/select a map, copy
map_selection.sample.luatomap_selection.lua(gitignored) and change therequireon the first line. Never commitmap_selection.lua. There is also a starting template atmap_gen/maps/template.lua. - The Factorio modding API is sandboxed; only modules loaded in
control.luarun in the control stage. Never callscript.on_eventdirectly — use the wrapper inutils/event.lua(Event.add,Event.on_init,Event.on_load,Event.on_nth_tick). - Never keep state that must survive save/load in plain module locals; register it with
Global.registerfromutils/global.lua. Closures in global storage are forbidden — store aToken.registertoken instead.Token.registermust only be called at control stage /on_init(desync risk otherwise). - Define chat commands with
Command.addfromutils/command.lua(handles ranks, locales, server flags) rather than rawcommands.add_command; build GUIs with the helpers inutils/gui.lua. - Player-facing strings should be translatable: add keys to
locale/en/*.cfg(the source of truth) and keep keys in sync across locales — the CI pipeline (.github/workflows/CI.yml, run before PRs todevelopare merged) checks for missing/misplaced keys and rejects duplicate keys or sections. - Whenever adding, editing, or translating strings in
locale/, followdocs/LOCALE.md. - Tests run inside Factorio using the framework in
utils/test/: create a<module>_tests.luanext to the code (seeutils/core_tests.lua) and run the/test-runnercommand in game (_DEBUG = trueinconfig.lua). - Keep changes surgical; feature modules should be independently disableable through
config.lua.
If the map should be a standalone scenario, add a folder in scenario_templates/ named after the scenario. It may contain
any files that the scenario should override or add to the base scenario — typically just a map_selection.lua whose first
line selects the map, e.g. return require 'map_gen.maps.crash_site.presets.arrakis'.
The RedMew servers run these scenarios via FactorioWebInterface.
If you have questions about how features/server.lua, features/server_commands.lua work, or about how scenario loading
works in general, look in that repository.
luacheck (config in .luacheckrc) is the CI gate on PRs to develop (.github/workflows/CI.yml) and should be run before finishing:
luacheck .
Warnings are treated as errors, so the run must end with 0 warnings / 0 errors. RedMew globals (Debug, ServerCommands, ...) are pre-declared in .luacheckrc.
- Follow the existing Lua style: 4-space indentation, single quotes,
snake_casefunctions,PascalCasemodules. - Community docs (data lifecycle, style) live in the wiki.
All contributions must be licensed under GPL-3.0.