Initial release

This commit is contained in:
Simon Brodtmann 2026-01-29 17:28:27 +01:00
commit e3357f8bec
6 changed files with 372 additions and 0 deletions

22
README.md Normal file
View file

@ -0,0 +1,22 @@
[![foundrygg.com](https://img.shields.io/badge/foundrygg-4a1402?style=for-the-badge&logo=vercel&logoColor=white)](https://foundrygg.com)[![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/ufvFUJtVwk)[![Forgejo](https://img.shields.io/badge/source%20code-%23f4f4f5?style=for-the-badge&logo=forgejo&logoColor=%23c2410c)](https://git.cacklingfiend.info/cacklingfiend/factorio-light)[![Downloads](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fmods.factorio.com%2Fapi%2Fmods%2Ffactorio-light&query=%24.downloads_count&suffix=%20Downloads&style=for-the-badge&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI%2FPgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDIwMDEwOTA0Ly9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy1TVkctMjAwMTA5MDQvRFREL3N2ZzEwLmR0ZCI%2BCjxzdmcgdmVyc2lvbj0iMS4wIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiB3aWR0aD0iMTIxNnB0IiBoZWlnaHQ9IjEyODBwdCIgdmlld0JveD0iMCAwIDEyMTYgMTI4MCIKIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiPgo8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDEyODApIHNjYWxlKDAuMSwtMC4xKSIKZmlsbD0iI2ZmZmZmZiIgc3Ryb2tlPSJub25lIj4KPHBhdGggZD0iTTM0NzAgOTYwMCBsMCAtMzIwMCAtMTczMSAwIGMtOTUyIDAgLTE3MjkgLTQgLTE3MjcgLTggNCAtMTIgNjA2MgotNjM5MCA2MDY4IC02MzkwIDYgMCA2MDY0IDYzNzggNjA2OCA2MzkwIDIgNCAtNzc1IDggLTE3MjcgOCBsLTE3MzEgMCAwIDMyMDAKMCAzMjAwIC0yNjEwIDAgLTI2MTAgMCAwIC0zMjAweiIvPgo8L2c%2BCjwvc3ZnPgo%3D&label=&labelColor=%23e39827&color=%23e39827)](https://mods.factorio.com/mod/factorio-light/metrics?range=last_two_months&type=mod_downloads)[![Ko-fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/cacklingfiend)
_________________
## Factorio light
Did you ever think Factorio is too complex? Do you want to introduce your child to Factorio but think he/she will be overwhelmed?
Well, that is over now! Factorio light is a reduced version of the vanilla experience.
The following has been removed:
* Production science pack
* Utility science pack
* Uranium and anything related
* Processing units
* mk2 equipment
* Beacons
* Circuitry
* Artillery
* Combat bots
* Infinite research
* Behemoth biters

121
factorio-light/data.lua Normal file
View file

@ -0,0 +1,121 @@
require "__cf-lib__/util/table"
local util = require "util"
local Technology = require("__cf-lib__/data/technology")
local Recipe = require("__cf-lib__/data/recipe")
-- Clear space science
util.removeTechWithPrerequisite("space-science-pack")
-- Clear production/utility science
util.removeEverythingRecursivelyByTechnology("uranium-mining", { hideEntities = { "heat-pipe", "nuclear-reactor", "spidertron" } })
util.removeEverythingRecursivelyByTechnology("circuit-network", { skip = { "iron-stick" }, hideEntity = true })
util.removeEverythingRecursivelyByTechnology("follower-robot-count-1")
util.removeEverythingRecursivelyByTechnology("military-4", { hideEntities = { "power-armor-mk2", "artillery-turret", "artillery-wagon", "spidertron" } })
util.removeEverythingRecursivelyByTechnology("defender")
util.removeEverythingByTechnology("coal-liquefaction")
util.removeEverythingByTechnology("effect-transmission", { hideEntity = true })
util.removeEverythingByTechnology("discharge-defense-equipment")
util.removeEverythingByTechnology("energy-shield-mk2-equipment")
util.removeEverythingByTechnology("personal-roboport-mk2-equipment")
util.removeEverythingByTechnology("battery-mk2-equipment")
util.removeEverythingByItem("discharge-defense-remote")
-- Move rocket
Technology:new("rocket-silo")
:removePrerequisite("productivity-module-3")
:removePrerequisite("speed-module-3")
:removePrerequisite("utility-science-pack")
:removeIngredient("production-science-pack")
:removeIngredient("utility-science-pack")
-- Move production/utility techs to space science
util.replacePrerequisite("production-science-pack", "space-science-pack")
util.replacePrerequisite("utility-science-pack", "space-science-pack")
util.replaceTechIngredient("production-science-pack", "space-science-pack")
util.replaceTechIngredient("utility-science-pack", "space-science-pack")
util.removeEverythingByTechnology("production-science-pack")
util.removeEverythingByTechnology("utility-science-pack")
data.raw["lab"]["lab"].inputs = table.filter(
data.raw["lab"]["lab"].inputs,
function(value)
return not table.contains({ "production-science-pack", "utility-science-pack" }, value)
end
)
-- Remove processing unit
local recipes = { "speed-module-2", "speed-module-3", "efficiency-module-2", "efficiency-module-3", "productivity-module-2", "productivity-module-3" }
for _, recipe in pairs(recipes) do
Recipe:new(recipe):replaceIngredient("advanced-circuit", "electronic-circuit")
end
util.replaceRecipeIngredient("processing-unit", "advanced-circuit", 2)
util.replacePrerequisite("processing-unit", "chemical-science-pack")
util.removeEverythingByTechnology("processing-unit", { skip = { "advanced-circuit" } })
-- Remove tips and tricks
data.raw["tips-and-tricks-item"]["spidertron-control"] = nil
data.raw["tips-and-tricks-item"]["copy-paste-spidertron"] = nil
data.raw["tips-and-tricks-item"]["circuit-network"] = nil
data.raw["tips-and-tricks-item"]["connect-switch"] = nil
-- Remove menu simulations
data.raw["utility-constants"]["default"].main_menu_simulations.nauvis_biter_base_laser_defense = nil
-- Remove behemoth enemies
data.raw["unit"]["behemoth-biter"] = nil
data.raw["unit"]["behemoth-spitter"] = nil
data.raw["turret"]["behemoth-worm-turret"] = nil
data.raw["corpse"]["behemoth-biter-corpse"] = nil
data.raw["corpse"]["behemoth-spitter-corpse"] = nil
data.raw["corpse"]["behemoth-worm-corpse"] = nil
data.raw["corpse"]["behemoth-worm-corpse-burrowed"] = nil
data.raw["unit-spawner"]["biter-spawner"].result_units = (function()
local res = {}
res[1] = { "small-biter", { { 0.0, 0.3 }, { 0.6, 0.0 } } }
if not data.is_demo then
res[2] = { "medium-biter", { { 0.4, 0.0 }, { 0.6, 0.3 }, { 0.8, 0.1 } } }
res[3] = { "big-biter", { { 0.8, 0.0 }, { 1.0, 0.4 } } }
end
return res
end)()
data.raw["unit-spawner"]["spitter-spawner"].result_units = {
{ "small-biter", { { 0.0, 0.3 }, { 0.55, 0 } } },
{ "small-spitter", { { 0.2, 0.0 }, { 0.4, 0.3 }, { 0.6, 0.0 } } },
{ "medium-spitter", { { 0.4, 0.0 }, { 0.6, 0.3 }, { 0.8, 0.1 } } },
{ "big-spitter", { { 0.8, 0.0 }, { 1.0, 0.4 } } }
}
data.raw["group-attack-achievement"]["it-stinks-and-they-dont-like-it"].entities = table.filter(
data.raw["group-attack-achievement"]["it-stinks-and-they-dont-like-it"].entities,
function(value)
return not table.contains({ "behemoth-biter", "behemoth-spitter" }, value)
end
)
-- Remove uranium
data.raw["resource"]["uranium-ore"] = nil
data.raw["autoplace-control"]["uranium-ore"] = nil
data.raw["planet"]["nauvis"].map_gen_settings.autoplace_controls["uranium-ore"] = nil
data.raw["planet"]["nauvis"].map_gen_settings.autoplace_settings["entity"].settings["uranium-ore"] = nil
data.raw["map-gen-presets"]["default"]["rich-resources"].basic_settings.autoplace_controls["uranium-ore"] = nil
data.raw["map-gen-presets"]["default"]["rail-world"].basic_settings.autoplace_controls["uranium-ore"] = nil
data.raw["map-gen-presets"]["default"]["ribbon-world"].basic_settings.autoplace_controls["uranium-ore"] = nil
util.removeEverythingByItem("uranium-235")
util.removeEverythingByItem("uranium-238")
util.removeEverythingByItem("depleted-uranium-fuel-cell")
-- Buff rocket silo
data.raw["rocket-silo"]["rocket-silo"].rocket_parts_required = 25
-- Buff LDS
Recipe:new("low-density-structure")
:replaceIngredient("copper-plate", 2)
:replaceIngredient("steel-plate", 1)
-- Update character
data.raw["character"]["character"].animations[3].armors = table.filter(data.raw["character"]["character"].animations[3].armors, function(value)
return value ~= "power-armor-mk2"
end)
data.raw["character-corpse"]["character-corpse"].armor_picture_mapping["power-armor-mk2"] = nil
-- Increase moisture
data.raw.planet["nauvis"].map_gen_settings.autoplace_controls["starting_area_moisture"] = { size = 2, richness = 6 }

16
factorio-light/info.json Normal file
View file

@ -0,0 +1,16 @@
{
"name": "factorio-light",
"version": "1.0.0",
"title": "Factorio light",
"description": "A light-weight version of Factorio for a chill round or your kids.",
"author": "cackling fiend",
"homepage": "https://discord.gg/ufvFUJtVwk",
"factorio_version": "2.0",
"dependencies": [
"base",
"cf-lib >= 1.4.0",
"? elevated-rails",
"! space-age",
"! quality"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

213
factorio-light/util.lua Normal file
View file

@ -0,0 +1,213 @@
local util = {}
util.removeTechWithPrerequisite = function(name)
for techName, technology in pairs(data.raw.technology) do
if technology.prerequisites and table.contains(technology.prerequisites, name) then
data.raw.technology[techName] = nil
end
end
end
util.removeAchievementByItem = function(name)
for type in pairs(defines.prototypes['achievement']) do
if data.raw[type] then
for achievementName, achievement in pairs(data.raw[type]) do
if achievement.ammo_type == name or achievement.consumed_condition == name
or achievement.produced_condition == name or achievement.science_pack == name then
data.raw[type][achievementName] = nil
end
end
end
end
end
util.removeAchievementByEntity = function(name)
for protoType in pairs(defines.prototypes['achievement']) do
if data.raw[protoType] then
local match = function(stringOrTable)
if stringOrTable == nil then
return false
end
local tableValue = type(stringOrTable) == "string" and { stringOrTable } or stringOrTable
return table.contains(tableValue, name)
end
for achievementName, achievement in pairs(data.raw[protoType]) do
if achievement.to_build == name or match(achievement.to_kill) or match(achievement.damage_dealer)
or achievement.entity == name or match(achievement.excluded) or match(achievement.included) then
data.raw[protoType][achievementName] = nil
end
end
end
end
end
util.removeOrHide = function(type, name, options)
local hide = options and options.hideEntity or false
if options and options.skip then
if table.contains(options.skip, name) then
return false
end
end
if options and options.hideEntities then
if table.contains(options.hideEntities, name) then
hide = true
end
end
if hide then
data.raw[type][name].hidden = true
data.raw[type][name].hidden_in_factoriopedia = true
else
data.raw[type][name] = nil
end
return true
end
util.removeEntity = function(name, options)
for type in pairs(table.merge(defines.prototypes['entity'], defines.prototypes['equipment'])) do
if data.raw[type] then
local entity = data.raw[type][name]
if entity then
util.removeOrHide(type, name, options)
util.removeAchievementByEntity(name)
return
end
end
end
end
util.removeEverythingByItem = function(name, options)
for type in pairs(defines.prototypes['item']) do
if data.raw[type] then
local item = data.raw[type][name]
if item then
if item.place_result then
util.removeEntity(item.place_result, options)
end
if item.place_as_equipment_result then
util.removeEntity(item.place_as_equipment_result, options)
end
util.removeOrHide(type, name, options)
for customInputName, customInput in pairs(data.raw["custom-input"]) do
if customInput.item_to_spawn == name then
data.raw["custom-input"][customInputName] = nil
end
end
util.removeAchievementByItem(name)
return
end
end
end
end
util.removeEverythingByRecipe = function(name, options)
local recipe = data.raw.recipe[name]
local removed = util.removeOrHide("recipe", name, options)
if not removed then
return
end
if recipe.main_product then
util.removeEverythingByItem(recipe.main_product, options)
elseif recipe.results and #recipe.results == 1 and recipe.results[1].type == "item" then
util.removeEverythingByItem(recipe.results[1].name, options)
end
data.raw.recipe[name] = nil
end
util.removeEverythingByTechnology = function(name, options)
local technology = data.raw.technology[name]
if technology and technology.effects then
for _, effect in pairs(technology.effects) do
if effect.type == "unlock-recipe" then
util.removeEverythingByRecipe(effect.recipe, options)
end
end
end
data.raw.technology[name] = nil
for shortcutName, shortcut in pairs(data.raw.shortcut) do
if shortcut.technology_to_unlock then
data.raw.shortcut[shortcutName] = nil
end
end
end
util.removeEverythingRecursivelyByTechnology = function(name, options)
util.removeEverythingByTechnology(name, options)
for techName, technology in pairs(data.raw.technology) do
if technology.prerequisites and table.contains(technology.prerequisites, name) then
util.removeEverythingRecursivelyByTechnology(techName, options)
end
end
end
util.replacePrerequisite = function(source, target)
for _, technology in pairs(data.raw.technology) do
if technology.prerequisites and table.contains(technology.prerequisites, source) then
table.removeValue(technology.prerequisites, source)
if not table.contains(technology.prerequisites, target) then
table.insert(technology.prerequisites, target)
end
end
end
end
util.replaceTechIngredient = function(old, new)
for _, technology in pairs(data.raw.technology) do
if technology.unit and technology.unit.ingredients then
local matchOld = table.filter(technology.unit.ingredients, function(v)
return v[1] == old
end)
local matchNew = table.filter(technology.unit.ingredients, function(v)
return v[1] == new
end)
if #matchNew > 0 then
technology.unit.ingredients = table.filter(technology.unit.ingredients, function(v)
return v[1] ~= old
end)
elseif #matchOld > 0 then
matchOld[1][1] = new
end
end
end
end
util.replaceRecipeIngredient = function(old, new, multiplier)
multiplier = multiplier or 1
local function replace(tbl)
if not tbl then return end
for _, entry in pairs(tbl) do
if entry.name == old then
entry.name = new
if entry.amount then
entry.amount = entry.amount * multiplier
end
if entry.amount_min then
entry.amount_min = entry.amount_min * multiplier
end
if entry.amount_max then
entry.amount_max = entry.amount_max * multiplier
end
if entry.ignored_by_stats then
entry.ignored_by_stats = entry.ignored_by_stats * multiplier
end
if entry.ignored_by_productivity then
entry.ignored_by_productivity = entry.ignored_by_productivity * multiplier
end
end
end
end
for _, recipe in pairs(data.raw["recipe"]) do
replace(recipe.ingredients)
replace(recipe.results)
if recipe.main_product == old then
recipe.main_product = new
end
end
end
return util

BIN
sources/thumbnail.afphoto Normal file

Binary file not shown.