[Guide] Tips & Tricks for modding Factorio

Place to get help with not working mods / modding interface.
Post Reply
User avatar
ownlyme
Filter Inserter
Filter Inserter
Posts: 400
Joined: Thu Dec 21, 2017 8:02 am
Contact:

[Guide] Tips & Tricks for modding Factorio

Post by ownlyme »

After making over 40 mods, i thought it was time to write down what i've learned.
1. Don't use deepcopy on base game files
Other mods that got loaded before yours and don't respect point 3 might have changed them and suddenly you have to deal with the new update-target not being compatible or other shennigans
Also some factorio update might change them.
So i suggest creating some file like "vanilla_prototypes.lua" where you store all the prototypes you're using and deepcopy from there.

2. Also copy base game functions and base game files
The base game is subject to change, especially in beta versions of factorio.
If you don't want to deal with graphics or the sound system getting changed, i suggest you copy the functions that create them and storing the assets you're using in your mod.

3. change base game files in data-updates.lua
You'd usually create your prototypes in data.lua, like most mods do.
When you already change the base game's files in data.lua, another mod might have the issues i described in point 1

4. Only process 1 entity each tick
Nobody likes lagspikes.
Thats why i suggest spreading your script-load across multiple ticks, whenever possible.
Bad example:

Code: Select all

script.on_nth_tick(15, function()
	for a,b in pairs(global.my_games_entities) do
		-- code..
	end
end)
Good example:

Code: Select all

script.on_event(defines.events.on_tick, function(event)
	local entity_count = table_size(global.entities)
	local runs = entity_count/30+(global.partial_tick or 0) --executed every 30 ticks
	global.partial_tick = runs%1
	local i = 1
	while i <= runs do
		local temp_iter = global.iterate_entities
		global.iterate_entities = next(global.entities, global.iterate_entities)
		if temp_iter and global.entities[temp_iter] then
			if not global.entities[temp_iter].entity.valid then
				global.entities[temp_iter].entity.destroy()
				global.entities[temp_iter].blueprint_data.destroy()
				global.entities[temp_iter] = nil
			else
				-- do your stuff here
			end
			i=i+1
		else
			i=i+0.1
		end
	end
end)
5. Use a unique prefix
To maximize compatibility with other mods, use a unique prefix on your prototypes and settings.
You don't want to accidently use the same name that another mod uses too.

6. multiple events
Only subscribing to the player-built and robot-built events might not be enough depending on other installed mods.
To make sure you don't miss your entity being built, i suggest using something like this:

Code: Select all

script.on_event({defines.events.on_robot_built_entity,defines.events.on_built_entity,defines.events.script_raised_revive,defines.events.script_raised_built,defines.events.on_entity_cloned}, function(event)
	local entity = event.created_entity or event.entity or event.destination
	....

7. Storing custom entity data in blueprints
It's possible to store your custom data in a blueprint.
Unfortunately it's a little complex, so i included a small demo that demonstrates this:
blueprint_demo_0.18.1.zip
(92.52 KiB) Downloaded 57 times
(a chests that gets it's contents stored in the blueprint)
credits to thelordodin viewtopic.php?p=288672#p288672 for coming up with this idea.
mods.factorio.com/user/ownlyme
My requests: uiAbove||Grenade arc||Blueprint allies||Creeps forget command/ don't get removed||Player Modifiers||textbox::selection||Better Heat IF||Singleplayer RCON||tank bug w/ min_range >= projectile_creation_distance

User avatar
Deadlock989
Smart Inserter
Smart Inserter
Posts: 2528
Joined: Fri Nov 06, 2015 7:41 pm

Re: [Guide] Tips & Tricks for modding Factorio

Post by Deadlock989 »

1 and 2 are terrible advice.

A very recent example was the logistic robot shadow change. If you are using the same resource as an established game entity but made your own cut and paste from some ancient Factorio version's prototypes, bang, your copy is now broken and your mod won't load because the sprite sheet it points at now has different dimensions. Several mods broke that day because they did what you are advising here - they literally cut and pasted a definition that still points at a media resource still provided by the base or core resources. Unless you want to copy the old sprite sheets into your mod as well, which would be a waste of everyone's bandwidth.

If you are creating a mildly tweaked version of an existing prototype, it's perfectly reasonable and normal to copy it dynamically from base game data, and then the 99% of the prototype you didn't change won't randomly break without notice on future game updates.
Image

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: [Guide] Tips & Tricks for modding Factorio

Post by eradicator »

1,2 Generally concur with @Deadlock. If you "don't want to deal with changes" then don't mod experimental versions.

3 Race to the bottom much?

4 is bullshit because it's far too generic. on_tick processing needs to be tailored to each mods requirements. If you have very few entities using batch processing in nth_tick is likely faster because you save overhead due to fewer handler calls and less iteration management code. If you need guaranteed runtime you can't distribute randomly. The "good example" is also funnily bullshit because it does a bunch of calculations just to decide that it doesn't need to run most of the time - exactly what the introduction of nth_tick was supposed to abolish.

I recommend to anyone reading this to look at other threads like: viewtopic.php?f=25&t=53405

5 Actually correct

6 Sure. As long as you don't care where the entity came from.

7 TL;DR
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Post Reply

Return to “Modding help”