Skip to content

Commit b5422f7

Browse files
jodliclaude
andcommitted
feat: add Super Quality Module and let the super-beacon broadcast quality
Add a super_quality_module (category = "quality", effect = { quality = 1.0 }) granted by the Creative-tools sweep and stocked by the Creative Provider Chest, giving a guaranteed at-least-+1 quality upgrade on a machine's output. Add "quality" to super_beacon.allowed_effects so a single beacon can distribute the effect, and align its distribution effectivity with the vanilla beacon (1.5 baseline + 0.2 per quality level). Cover both with verify.py behavior assertions. Deliberate data-stage no-ops (labs, empty-ingredient recipes, roboport quality flag) are documented inline. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 15eb4cf commit b5422f7

9 files changed

Lines changed: 94 additions & 2 deletions

File tree

changelog.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
---------------------------------------------------------------------------------------------------
2+
Version: 2.4.0
3+
Date: 2026-06-30
4+
Features:
5+
- Add a Super Quality Module: a creative module that guarantees the produced item is upgraded by at least one quality level (the engine's fixed cascade can still push it to +2/+3). It is granted by the normal Creative tools' recipe sweep and stocked by the Creative Provider Chest, alongside the other super modules.
6+
- The Super Beacon now broadcasts the quality effect, so a single beacon fitted with the Super Quality Module can distribute the guaranteed quality upgrade to every nearby crafting machine.
7+
Changes:
8+
- The Super Beacon's distribution effectivity is raised from 0.5 to 1.5 and now scales with quality (+0.2 per level), mirroring the vanilla beacon so a legendary beacon reaches 2.5.
9+
---------------------------------------------------------------------------------------------------
210
Version: 2.3.0
311
Date: 2026-06-29
412
Features:

defines.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ creative_mode_defines.names.items = {
220220
super_slow_module = creative_mode_defines.name_prefix .. "super-slow-module",
221221
super_consumption_module = creative_mode_defines.name_prefix .. "super-consumption-module",
222222
super_pollution_module = creative_mode_defines.name_prefix .. "super-pollution-module",
223+
super_quality_module = creative_mode_defines.name_prefix .. "super-quality-module",
223224
belt_immunity_equipment = "belt-immunity-equipment",
224225
super_fusion_reactor_equipment = creative_mode_defines.name_prefix .. "super-fusion-reactor-equipment",
225226
super_personal_roboport_equipment = creative_mode_defines.name_prefix .. "super-personal-roboport-equipment",
@@ -307,6 +308,7 @@ creative_mode_defines.names.recipes = {
307308
super_slow_module = creative_mode_defines.name_prefix .. "super-slow-module",
308309
super_consumption_module = creative_mode_defines.name_prefix .. "super-consumption-module",
309310
super_pollution_module = creative_mode_defines.name_prefix .. "super-pollution-module",
311+
super_quality_module = creative_mode_defines.name_prefix .. "super-quality-module",
310312
belt_immunity_equipment = creative_mode_defines.name_prefix .. "belt-immunity-equipment",
311313
super_fusion_reactor_equipment = creative_mode_defines.name_prefix .. "super-fusion-reactor-equipment",
312314
super_personal_roboport_equipment = creative_mode_defines.name_prefix .. "super-personal-roboport-equipment",
@@ -1726,6 +1728,10 @@ table.insert(
17261728
creative_mode_defines.values.creative_provider_chest_additional_content_names,
17271729
creative_mode_defines.names.items.super_pollution_module
17281730
)
1731+
table.insert(
1732+
creative_mode_defines.values.creative_provider_chest_additional_content_names,
1733+
creative_mode_defines.names.items.super_quality_module
1734+
)
17291735

17301736
table.insert(
17311737
creative_mode_defines.values.creative_provider_chest_additional_content_names,
1.91 KB
Loading

locale/en/base.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ creative-mod_super-clean-module=Super clean module
129129
creative-mod_super-slow-module=Super slow module
130130
creative-mod_super-consumption-module=Super consumption module
131131
creative-mod_super-pollution-module=Super pollution module
132+
creative-mod_super-quality-module=Super quality module
132133
133134
[item-description]
134135
creative-mod_energy-absorption=Absorbing energy from the network. (You shouldn't hold this item. Return it ASAP!)
@@ -145,6 +146,7 @@ creative-mod_super-clean-module=Massively decreases machine pollution. Minimum p
145146
creative-mod_super-slow-module=Massively decreases machine speed. Minimum speed is 20%.
146147
creative-mod_super-consumption-module=Massively increases machine energy consumption.
147148
creative-mod_super-pollution-module=Massively increases machine pollution.
149+
creative-mod_super-quality-module=Guarantees the produced item is upgraded by at least one quality level.
148150
creative-mod_super-fusion-reactor-equipment=Generates unlimited power for your equipment.
149151
creative-mod_super-personal-roboport-equipment=Supports large numbers of robots. Large construction radius. Can recharge robots instantly without causing any energy.
150152

prototypes/entity.lua

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,10 @@ local function inserter(
918918
end
919919

920920
-- Generates data for lab.
921+
-- Deliberate no-op: the vanilla lab declares no allowed_effects, and the
922+
-- LabPrototype engine default is "all effects except quality". We leave that
923+
-- default untouched on purpose, so the creative labs continue to reject quality
924+
-- modules — a quality effect on a lab is inert (labs roll no item quality).
921925
local function lab(entity_name, item_name, icon_name, on_animation_filename, off_animation_filename)
922926
local lab = table.deepcopy(data.raw["lab"]["lab"])
923927
lab.name = entity_name
@@ -2852,7 +2856,9 @@ data:extend({
28522856
dying_explosion = "medium-explosion",
28532857
collision_box = { { -1.2, -1.2 }, { 1.2, 1.2 } },
28542858
selection_box = { { -1.5, -1.5 }, { 1.5, 1.5 } },
2855-
allowed_effects = { "consumption", "speed", "pollution", "productivity" },
2859+
-- "quality" added so the super-beacon can broadcast the super quality module across nearby
2860+
-- crafting machines (the "flood a base for quality testing" use case).
2861+
allowed_effects = { "consumption", "speed", "pollution", "productivity", "quality" },
28562862
base_picture = {
28572863
filename = creative_mode_defines.mod_directory .. "/graphics/entity/super-beacon-base.png",
28582864
width = 116,
@@ -2890,7 +2896,10 @@ data:extend({
28902896
filename = "__base__/sound/car-metal-impact.ogg",
28912897
volume = 0.65,
28922898
},
2893-
distribution_effectivity = 0.5,
2899+
-- Mirror the vanilla beacon's distribution-effectivity model: 1.5 baseline plus 0.2 per quality
2900+
-- level, so a legendary beacon reaches 2.5 just like vanilla.
2901+
distribution_effectivity = 1.5,
2902+
distribution_effectivity_bonus_per_quality_level = 0.2,
28942903
module_slots = 7,
28952904
module_info_icon_shift = { 0, 0.5 },
28962905
module_info_multi_row_initial_height_modifier = -0.3,

prototypes/equipment.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ data:extend({
6060
stationing_offset = { 0, -0.6 },
6161
charging_station_shift = { 0, 0.5 },
6262
charging_station_count = 1000,
63+
-- Deliberate no-op: charging_station_count_affected_by_quality is omitted
64+
-- (defaults to false), so the station count stays a flat 1000. Intentional —
65+
-- this equipment is only ever obtainable at normal quality, so a quality
66+
-- scalar would never apply.
6367
charging_distance = 1.6,
6468
charging_threshold_distance = 5,
6569
categories = { "armor" },

prototypes/item.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,22 @@ data:extend({
863863
stack_size = 50,
864864
effect = { pollution = 2.5 },
865865
},
866+
{
867+
-- Super quality module
868+
type = "module",
869+
name = creative_mode_defines.names.recipes.super_quality_module,
870+
icon_size = 32,
871+
icon = creative_mode_defines.mod_directory .. "/graphics/icons/super-quality-module.png",
872+
hidden = hidden,
873+
subgroup = creative_mode_defines.names.item_subgroups.modules,
874+
category = "quality",
875+
tier = 50,
876+
order = "i",
877+
stack_size = 50,
878+
-- 1.0 = 100%: guaranteed at-least-+1 level; the engine's fixed ~10% cascade
879+
-- can still push to +2/+3. Values >1.0 are identical (cascade is fixed).
880+
effect = { quality = 1.0 },
881+
},
866882
-----------------------------------------------------------------------------
867883

868884
{

prototypes/recipe.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,18 @@ data:extend({
523523
results = { { type = "item", name = creative_mode_defines.names.items.super_pollution_module, amount = 1 } },
524524
enabled = false,
525525
},
526+
{
527+
-- Super quality module
528+
-- Deliberate no-op: like every recipe here, ingredients = {} so the engine
529+
-- resolves can_set_quality to false (this module item is craftable at normal
530+
-- quality only). Intentional — cheat items are already maxed, so quality
531+
-- variants of the module itself would have no functional payoff.
532+
type = "recipe",
533+
name = creative_mode_defines.names.recipes.super_quality_module,
534+
ingredients = {},
535+
results = { { type = "item", name = creative_mode_defines.names.items.super_quality_module, amount = 1 } },
536+
enabled = false,
537+
},
526538
-----------------------------------------------------------------------------
527539

528540
{

verify.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,39 @@ def cmd_behavior(args: argparse.Namespace) -> int:
480480
"true",
481481
"super_boiler_placed",
482482
),
483+
# super_quality_module_effect_applied: place a quality-capable crafting machine
484+
# (assembling-machine-2 allows the "quality" effect by vanilla default), read its
485+
# baseline resolved quality effect, insert the creative super-quality-module into its
486+
# module inventory, and read the effect again. LuaEntity.effects is a flat table keyed
487+
# by effect type (e.g. { quality = 0.5 } before, { quality = 1.5 } after for AM-2). The
488+
# module's effect = { quality = 1.0 } must raise the resolved quality by >= 1.0
489+
# (guaranteed at-least-+1 upgrade). Proves the module's effect is legal in a module slot
490+
# AND carries the intended magnitude: the engine accepted both the category and the
491+
# effect key, and the delta is the module's full contribution.
492+
_assert_rcon(
493+
sb,
494+
'/c local s = game.surfaces["cm_verify"] '
495+
'local m = s.create_entity{name="assembling-machine-2", position={14, 12}, force="player"} '
496+
"local before = (m.effects and m.effects.quality) or 0 "
497+
'm.get_module_inventory().insert{name="creative-mod_super-quality-module", count=1} '
498+
"local after = (m.effects and m.effects.quality) or 0 "
499+
"rcon.print(tostring(after - before >= 1.0))",
500+
"true",
501+
"super_quality_module_effect_applied",
502+
),
503+
# super_quality_module_beacon_insertable: validates the Phase-2 super_beacon
504+
# allowed_effects edit end-to-end. Place a super-beacon and insert the
505+
# super-quality-module into its module inventory; a successful insert (count == 1)
506+
# proves the "quality" allowed-effects gate now admits the module for distribution.
507+
# Before the edit the engine would reject the insert (insert returns 0).
508+
_assert_rcon(
509+
sb,
510+
'/c local s = game.surfaces["cm_verify"] '
511+
'local b = s.create_entity{name="creative-mod_super-beacon", position={18, 12}, force="player"} '
512+
'rcon.print(tostring(b.get_module_inventory().insert{name="creative-mod_super-quality-module", count=1} == 1))',
513+
"true",
514+
"super_quality_module_beacon_insertable",
515+
),
483516
]
484517
# Let the server tick so the per-tick refill runs on the just-placed thruster.
485518
time.sleep(1.0)
@@ -553,6 +586,8 @@ def cmd_behavior(args: argparse.Namespace) -> int:
553586
"asteroid_spawning_rate_restore",
554587
"item_source_to_crafter_placed",
555588
"super_boiler_placed",
589+
"super_quality_module_effect_applied",
590+
"super_quality_module_beacon_insertable",
556591
"creative_thruster_refuels",
557592
"item_source_feeds_crafter",
558593
"super_boiler_heats_fluid",

0 commit comments

Comments
 (0)