Creative space-platform travel testing mode: indestructible wall, self-fueling thruster, asteroid spawning rate#58
Merged
Conversation
The creative wall stays a normal destructible target (biters path to it, asteroids hit it) but is healed to full on every hit via a name-filtered on_entity_damaged handler, so it can never be destroyed. max_health is bumped high as defense-in-depth. The wall and its item icon are tinted red to match the mod's other creative entities. Not Space-Age gated. The on_entity_damaged handler is registered with event filters and excluded from the generic filterless event loop; Phase 3 (asteroid protection) will extend this same handler rather than registering a second one.
A clone of the vanilla thruster that keeps the normal performance curve but has its fuel + oxidizer topped off every tick by script, so a space platform travels at vanilla speed with no fuel chain to supply. Defined only when Space Age is present (its fluids are space-age-only); the entity is cloned in data-final-fixes where the vanilla thruster prototype is guaranteed to exist. The body and item icon are tinted red to match the mod's other creative (spawn/source) entities; exhaust flames/glow are left natural.
…on only The thruster's animated body doesn't take a flat tint cleanly (only the integration patch picked it up, leaving a half-red look). The creative variant is now distinguished solely by its red item icon.
Add an 'Asteroid spawning rate' numeric input to the Game Settings cheats submenu, exposing game.map_settings.asteroids.spawning_rate directly (a float multiplier, default 1; set 0 to stop all asteroid spawning). Modeled on the existing game_speed numeric cheat and clamped to >= 0. Applies game-wide with zero runtime cost - no event handler, no per-tick work. Gated to Space Age via get_player_can_access_function, so the row is hidden on vanilla. Replaces the originally planned per-surface on_entity_damaged asteroid-protection toggle, which playtesting showed was redundant (creative walls block asteroids fully; remove/kill all enemies clear them).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Artifacts | Task deep link | PR Walkthrough (alpha)
What problems was I solving
This implements the Creative space-platform travel testing story (US-2.3): as a creative-mode player, I want to test space platforms in flight without managing thruster fuel or losing the platform to asteroid damage, so I can prototype platform layouts and interplanetary routes freely.
In vanilla Space Age, two things make in-transit platform testing tedious:
thruster-fuelandthruster-oxidizer— a whole production chain just to keep something moving while you iterate on a layout.There was no built-in way to switch either off. After shipping, a creative player can place a self-fueling thruster to travel with no fuel chain, protect builds with an indestructible wall, and dial asteroid spawning down to zero — all opt-in, with vanilla behavior unchanged when not enabled, and all Space-Age-specific behavior absent/no-op on vanilla.
What user-facing changes did I ship
1(vanilla); set0to stop asteroids entirely. Applies game-wide, not per surface.How I implemented it
Each feature is a thin vertical slice (data prototype + runtime + headless behavior test) reusing the mod's existing creative-entity conventions. See the PR Walkthrough for an interactive top-to-bottom tour with inline diffs.
Phase 1 — Indestructible creative wall (ungated)
prototypes/entity.lua— clone basestone-wall, keepdestructible = true, bumpmax_healthto 1,000,000 as defense-in-depth, and recursively tint every non-shadow sprite layer red.scripts/events.lua— the mod's singleon_entity_damagedhandler heals the wall to full on every hit.destructible = falsewas rejected because it removes the entity from the targeting system entirely.control.lua— registeron_entity_damagedwith anameevent filter and exclude it from the generic filterless loop so it isn't re-registered without filters.prototypes/item.lua/recipe.lua— hidden red item (flags = { "spawnable" }) and zero-ingredient disabled recipe auto-enabled by the existingcreative_tools_recipessweep.Phase 2 — Self-fueling creative thruster (Space Age only)
scripts/creative-thruster.lua(new) — per-tick loop that tops fuel + oxidizer back to capacity (1000 each) viainsert_fluid, following thesuper_boilerconvention (storage list,tick(), backwards iteration with self-cleaning of invalid entries).data-final-fixes.lua— clone the vanilla thruster indata-final-fixes(so the base prototype is guaranteed to exist), keeping the vanilla performance curve. The placed thruster keeps vanilla graphics; the creative variant is marked only by its red item icon.scripts/global-util.lua— initstorage.creative_mode.creative_thrusterand register placed thrusters into it.scripts/events.luacallscreative_thruster.tick();control.luarequires the module;.luacheckrcwhitelists its global. Item + recipe are guarded byif mods["space-age"].Phase 3 — Asteroid spawning rate (global Game-Settings input)
scripts/cheats.lua— a numeric cheat modeled ongame_speedthat reads/writesgame.map_settings.asteroids.spawning_rate, clamps to a non-negative range, and is gated toscript.feature_flags["space_travel"]. Essentially free: noon_tick, no per-entity scanning, just a persisted setting write.scripts/gui-menu-cheats.lua— anumeric_applyrow next togame_speed.defines.lua(name constants) andlocale/en/base.cfg(captions, tooltip, messages, plus entity/item strings for the wall and thruster).Deviations from the plan
No formal
*plan*.mdexists for this task — the planning artifact is the structure outline (04-structure-outline-platform-travel.md), which was itself reworked twice during implementation and documents its own resolved decisions. Comparing the final code against that outline:Implemented as planned
on_entity_damaged, red tint,destructible = falseexplicitly rejected, ungated/available on vanilla.super_boiler-style storage list +tick()self-cleaning loop, Space-Age-guarded item/recipe, red item icon only.numeric_applycheat overgame.map_settings.asteroids.spawning_ratein Game Settings, gated tospace_travel, no runtime handler or stored state.Deviations/surprises
data-final-fixes.lua, notprototypes/entity.lua. The outline placed theif mods["space-age"]clone inprototypes/entity.lua; the implementation moved it todata-final-fixesso the vanillathrusterprototype is guaranteed to exist before cloning.tick()readentity.fluidbox.get_filter(i)and assignedfluidbox[i] = {...}. The shipped code uses a hardcoded{ fuel, oxidizer }table andinsert_fluid(the thruster exposes no writablefluidboxproperty).placeable-neutral,placeable-player,player-creation,not-rotatable) andfast_replaceable_groupcleared, rather than reusing the vanilla flags as the outline implied.Additions not in plan
.luacheckrcgained acreative_thrusterglobal whitelist entry (required by luacheck for the new module).Items planned but not implemented (intentionally)
on_entity_damagedheal / impact damage-type filter was dropped. Playtesting showed asteroid survival is already covered by creative walls + "kill all enemies", so the asteroid spawning-rate setting replaced it. The wall heal is now the onlyon_entity_damageduse; the "Phase 3 will OR an impact damage-type filter" comments incontrol.lua/events.luaare historical.How to verify it
git fetch origin git worktree add ../creativemod-pr58 creative-space-platform-travel-testing-mode cd ../creativemod-pr58 uv run verify.py allManual Testing
0, fly a route (use "kill all enemies" once to clear any in flight), confirm no new asteroids appear; set it back to1and confirm they resume.Automated Tests
Description for the changelog
Add three opt-in creative space-platform travel aids: an indestructible creative wall, a self-fueling creative thruster (Space Age), and a global asteroid spawning-rate input (Space Age).