Somethings not (or hidden) in doc but you need to know

Place to post guides, observations, things related to modding that are not mods themselves.

Somethings not (or hidden) in doc but you need to know

Postby Mooncat » Tue Aug 08, 2017 6:23 pm

It has been some time since I've started modding for Factorio. There's something that happens quite often: wow, so I can / cannot do this? I wish someone had told me before!
Many hours have been wasted and we should avoid this. So, I would like to list the things that are not documented, or well hidden in the documents, so we don't make the same mistakes again.

Starting from the basic ones in data phase to the things about control phase:

Data

Prototype naming
It is important to make sure you have named your prototypes correctly. Impropriate prototype names may lead to mod incompatibility, errors will be thrown when your mod is loaded with another one.

Golden rule: add prefix to your prototype names, unless you know what you are doing.

For each prototype in each type (entity, item, fluid, recipe, technology, resource, etc.), its name has to be unique. You have to make sure it won't collide with any prototype of the same type provided by other mods.
When more mods are involved, being unique is more difficult. So, the easiest way is to add prefix, which is your mod ID.
For example, the ID of my Creative Mode is creative-mode, so you can see that every prototypes in the mod is named after "creative-mode_".

You may ask what "you know what you are doing" means. Well, think of some common intermediate products (type = "item" or "fluid") or resources (type = "resource"), like tin ores, silver ores, iron-wire, etc. items that may be commonly used in different mods and should be interchangeable. In these cases, adding prefix to them will make things more complicated. We don't want "mod1-tin_ore", "mod2-tin_ore", "mod3-tin_ore", "mod4-tin_ore"...... right? But if you go for the non-prefixed name, make sure the prototype of the same name has not been defined yet before you define it your own way. Error will be thrown if any prototype is defined more than once. To avoid that, you can either
1) add dependency to the mod that has the prototype defined, or
2) use if-then like the following (take tin-ore as an example):
Code: Select all
if data.raw["resource"]["tin-ore"] then
    -- TODO: tin-ore has not be defined. Define it now.
end


Note: pretty sure that items for building the entities in your mod need prefixed names.

This rule can also apply to GUI naming in control phase. See GUI Naming for the reason.


Error - invalid prototype array nil
If you encounter the error "invalid prototype array nil" and you are sure your prototype data is not nil, make sure you have written
Code: Select all
data:extend{ ... }

instead of
Code: Select all
data.extend{ ... }

( ":" vs "." )

It is fine to use "." if you use it this way:
Code: Select all
data.extend(data, { ... })


Only some entity types support apply_runtime_tint
Not everything supports masks with apply_runtime_tint. So far, I have only found the following entity types support this:
  • turret, ammo-turret, fluid-turret, electric-turret (force color)
  • combat-robot (force color)
  • gate (force color)
  • locomotive (entity color)
  • cargo-wagon (entity color)
  • fluid-wagon (entity color)
  • car (player color)
  • simple-entity-with-owner (player color, force color (when LuaEntity.color is {r=0,g=0,b=0,a=0} or custom LuaEntity.color) (added in 0.15.33)
  • simple-entity-with-force (force color) (added in 0.15.33)
No, unit does not support runtime masks.
Note: force color is the color of the first player in the force.


Solution to incorrect icon size
There is a known inconsistency between the base mod and our mods in 0.15: the default icon size for item-group and technology is different.

While the default icon size for item groups from the base mod is 64x64 px, it is 32x32 px in our mods.
While the default icon size for technologies from the base mod is 128x128 px, it is also 32x32 px in our mods.
To use 128x128px icon for your own technologies, you will have to add the following in the technology data:
Code: Select all
icon_size = 128


Source: https://forums.factorio.com/viewtopic.php?t=46437


Max image size
We know you can create beautiful and detailed graphics for Factorio, but make sure they are not too detailed (size is too big).

For normal resolution (graphics quality <= "normal"), the maximum supported size for each image is 2048px on any side.
For high resolution (graphics quality = "high"), the maximum supported size for each image is 4096px on any side.
If any of your images exceeds the above limits, you will see error like this:
MaxSizeForHR.png
MaxSizeForHR.png (43.79 KiB) Viewed 1263 times


Icon tinting, Multi-layered icon
It is possible to tint icons and/or use multiple images in a single icon by changing
Code: Select all
icon = "__foo__/graphics/my-icon.png"

into
Code: Select all
icons =
{
    {
        icon = "__foo__/graphics/my-icon-1.png",
        tint = {r = 0.8, g = 0.8, b = 1}
    },
    {
        icon = "__foo__/grahpics/my-icon-2.png",
        tint = {r = 1, g = 0.5, b = 0.5}
    }
}

Note: so you shouldn't expect the "icon" attribute to always exist. It can be presented in "icons" instead.


How to use data.raw
Once the data has been registered by data:extend, you can access the data by
Code: Select all
data.raw[type][name]

and then you will get the original table.

For example, you can change the max_health of the vanilla fluid wagon like this:
Code: Select all
data.raw["fluid-wagon"]["fluid-wagon"].max_health = 100000

while the first "fluid-wagon" is the type and the second one is the name.

You may also want to see "Data structure in data vs control"


fast_replaceable_group is not the magic solution
Even though it is possible to put everything into the same fast replaceable group by setting "fast_replaceable_group", but Factorio only supports replacing entities of the same size, i.e. not possible to replace a transport belt with splitter because transport belt is 1x1 while splitter is 1x2.


order is not black magic
Have you ever wondered what is the magic behind the ordering in Factorio? Like, is "a-b-c" a special format?
Well, the answer is NO. "a-b-c" is not a special format. It is just a string. It can be "whateveryoulike". And the logic behind the ordering function is simply
Code: Select all
if left.order < right.order then
    left go first
end

^ Provided by Rseding91 :P

Also, from the official wiki about order: https://wiki.factorio.com/Types/Order
The order property is a simple string.


player-port is special
Somethings special about player-port:
  • Its animation speed is unchangeable.
  • All player ports play the same frame at the same time.
  • If a player port is placed in game, it will immediately respawn player when the player is killed.


Large maximum_wire_distance can cause lag
From time to time, you might see mods that increase the wire distance of electric poles by changing their values of "maximum_wire_distance" to sky high. But actually, that may make the game lags when you build the poles manually. This has been classified as "Not a bug": https://forums.factorio.com/viewtopic.php?f=23&t=28095


stream projectile particle_buffer_size has to be at least 2
You can't set "particle_buffer_size" of "stream" projectiles to be smaller than 2, or otherwise it won't work as expected (or error will simply be thrown).

According to posila's response to stream prototype particle_buffer_size=1 causes display bug (the thread was renamed as the original report turned out to be not a bug, but it revealed another bug):
posila wrote:It is supposed to create illusion of continuous stream of fluid by drawing line segments to form parabolic shape. The line segments are drawn between particles generated in regular interval and while the turret is shooting segment between last particle and muzzle of the turret is also drawn. When the turret stops shooting one last particle is generated as "tail" so the stream is not detached from the turret rapidly.

To keep track of the particles it uses circular buffer of size particle_buffer_size, so in your case "tail" particle overwrites head. With single particle there is no segment to draw.


cluster_count has to be at least 2
You can't set "cluster_count" to be 1 in "cluster" actions. API request for making it possible has been made: Allow cluster_count to be 1


push-back effect takes the target entity collider size into account
Before working on making a "push-back" effect, you may want to know how it works first. To avoid being merged into another entity, collision check is done for the pushed entity against other entities. Well it should be easily understandable.

But what you may not know is that the pushed entity also checks collision against itself. As the result, if the "distance" of the "push-back" effect is too short, it will not be able to push entities that have large colliders.
(Because the devs are using the collider size as "weight"?)

A request for "fixing" this issue has been made: Lower the minimum distance of push-back effect. But no further news is heard.


Data and Control

Data structure in data vs control
While you can access the actual data table of each prototype in data phase using data.raw, you can't do this in control phase.
You have to rely on the API listed on http://lua-api.factorio.com/latest/, because the data has been processed and formatted by the game.


Code accessibility in data vs control
There is big difference between the accessibility of the code defined in data phase and that of the code defined in control phase.

- Data: any non-local variable or function you defined in data phase can be shared to the mods that are loaded after yours without the need of "require". For example, mod A defined function abc(). Mod B depends on mod A so it is loaded after A, and hence it can also call A's abc().
While this is convenient, you may need to take extra care about overriding. Say, mod A defined abc() in data.lua, mod B also defined its abc() in data.lua, if mod A calls abc() in data-updates.lua or data-final-fixes.lua, B's abc() will be executed instead of A's.
Therefore, keep your variables and functions local unless you want to share them with other mods.

- Data-Control: the variables and functions in data phase are not accessible in control phase. But there are exceptions*.

- Control: each mod is in its own namespace. Mod A's foo() defined in control.lua will not be accessible by mod B. But there are exceptions*.

*Exceptions: some variables and functions defined in Factorio/data/core/lualib are always accessible by all mods in both data and control phase. For example, data, data:extend(otherdata), util, util.oppositedirection(direction), table.deepcopy(object), etc.
(Please take extra care about "util". As it is a very common word, you may want to build up your own util object for your mod by
Code: Select all
util = {}
function util.foo() ... end

But this is wrong, as you are overriding the whole util object provided by Factorio. Error will be thrown when other mods use the original functions.
A solution is replace the first line by
Code: Select all
util = util or {}

But the best solution is define a local util with different name, like
Code: Select all
local my_util = {}


Useful functions and libraries
log(string) - log the message into factorio-current.log
error(string) - throw an error, just like when a mod has done something wrong.
serpent - a library that can be used as pretty printer in Factorio, and it is already included in the engine. No "require" is needed. Document can be found here: https://github.com/pkulchenko/serpent.

If you are messing with prototypes that are created or changed by other mods but you are not sure what they are doing, you can use the following to see the final data table:
Code: Select all
log(serpent.block(data.raw[type][name]))


LuaEntityPrototype.collision_mask does not return not-colliding-with-itself
Although you can add "not-colliding-with-itself" to entity collision_mask in data phase, it is actually not a mask, but a property to collision mask. When you are reading LuaEntityPrototype.collision_mask in control phase, you will find out that "not-colliding-with-itself" is never returned.

A quick demonstration:
Code: Select all
/c game.print(serpent.block(game.entity_prototypes["rocket-silo-rocket"].collision_mask))

The above comment will print "nil" instead of "{not-colliding-with-itself}"


Control

The global table
Even though it is documented, but I think many modders have still believed wrongly that the global table is shared across mode, due to its name "global".
But no. Each mod has its own global table. Mods can only share things using the LuaRemote class.
So, yes, you don't need to worry about the other mods when using the global table.
(It is unnecessary to add an extra object to save data and save the object to global, like how I did in Creative Mode. :oops: )
e.g. You don't need
Code: Select all
global.mod_id.foo = 1

Instead, it is safe to do
Code: Select all
global.foo = 1


Only one handler for each event
Currently, only one handler can be added for each event in each mod. If you add more than one handlers to an event, only the latest one will be called.
Meaning that if you do the following:
Code: Select all
script.on_event(defines.events.on_built_entity, function() game.print("a") end)
script.on_event(defines.events.on_built_entity, function() game.print("b") end)

You will notice that only "b" is printed when you build an entity.

If you really want to use multiple handlers, the solution is to make your handlers into functions, and call them in the actual event handler, like
Code: Select all
function print_a() game.print("a") end
function print_b() game.print("b") end
script.on_event(defines.events.on_built_entity, function()
    print_a()
    print_b()
end)

Then, both "a" and "b" will be printed.

This concept can apply to how you unsubscribe an event. In fact, you are adding "nil" as the handler, which override the original one.
Code: Select all
script.on_event(defines.events.on_built_entity, nil)


GUI Naming
Similar to Prototype Naming, it is recommended to also add prefix to your GUI element names. There are 2 reasons for that:
The first one is rather obvious. GUI elements under the same parent have to have unique names, or error will be thrown.
The second reason may be a bit tricky. Events, including those on_gui events, are broadcasted to every mods. If multiple mods have created different buttons but given them the same name, when a player click on any of these buttons and on_gui_click is invoked, the mods cannot distinguish the buttons easily with event.element.name. Things will get messy.


Setting player.character
If you want to, for example, disable god mode by doing the following:
Code: Select all
player.character = character_entity

make sure the character entity is on the same surface as the player or an error will be thrown.
Also, you should also note that teleportation across surfaces using LuaControl.teleport only works on players at this moment. You can't teleport the character entity to the surface of the player, or error will be thrown.


How to order deconstruct tiles
LuaEntity.order_deconstruct(force) won't work on tiles.
Instead, you create a proxy (marker) to tell the robots to deconstruct the tile:
Code: Select all
surface.create_entity
{
    name = "deconstructible-tile-proxy",
    position = tile.position,
    force = your_force
}


The cause in on_entity_died does not always work
Killing worms or any other turrets will trigger on_entity_died, but without the cause.
Rseding91 on Discord wrote:Turrets don't track the killer because they don't die on 0 health. They switch to a death animation and when that finishes then they die.


Find entity using position will not return entities without collider
When you use LuaSurface.find_entity, LuaSurface.find_entities, LuaSurface.find_entities_filtered or LuaSurface.count_entities_filtered, please be noted that:

  1. Position-search will NOT return entities that don't have collider, like smoke, non-directional projectile, explosion, flying-text, etc.
    • i.e. LuaSurface.find_entity will never return those entities.
  2. Area-search will count all entities including those that don't have collider.
    • i.e. LuaSurface.find_entities will also return those entities.
Note: the space rocket (rocket-silo-rocket) does have collider. It can be found by position-search.

We don't know why it is implemented like this. A request for standardizing them has been made (LuaSurface::find_entity returns no-collision entity), but no further news is heard.


The Mod Portal

Character limit
Before you decide to write your very detailed mod description in the "Information" block on Mod Portal, there is one thing you should know first: you can't write more than 10000 characters, or it will show an error when you click the submit button.

While it is convenient for the users to read mod description directly on Mod Portal, as a side note, this forum allows up to 60000 characters per post.


New Portal
Source: https://forums.factorio.com/viewtopic.php?f=189&t=38238&p=228951#p228951
Klonan wrote:We have someone working on a completely better mod portal as we speak,


And this is already in Factorio Roadmap for 0.16+:
Mod portal improvement (Rewrite)

So, be patient. ;)


Feel free to contribute if you know more and you think that should be added. :)
Last edited by Mooncat on Wed Sep 06, 2017 7:23 am, edited 22 times in total.
User avatar
Mooncat
Smart Inserter
Smart Inserter
 
Posts: 1163
Joined: Wed May 18, 2016 4:55 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby darkfrei » Thu Aug 10, 2017 9:01 pm

It would be nice to know, that functions in data.lua must be early than calling of this functions. By control.lua it's not important.
User avatar
darkfrei
Filter Inserter
Filter Inserter
 
Posts: 758
Joined: Thu Nov 20, 2014 11:11 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby Nexela » Thu Aug 10, 2017 10:20 pm

darkfrei wrote:It would be nice to know, that functions in data.lua must be early than calling of this functions. By control.lua it's not important.


Not sure what you are trying to say here.
Nexela
Smart Inserter
Smart Inserter
 
Posts: 1666
Joined: Wed May 25, 2016 11:09 am

Re: Somethings not (or hidden) in doc but you need to know

Postby d3x0r » Thu Aug 10, 2017 11:10 pm

darkfrei wrote:It would be nice to know, that functions in data.lua must be early than calling of this functions. By control.lua it's not important.

it is important still of you specify 'local' on the function.
d3x0r
Filter Inserter
Filter Inserter
 
Posts: 305
Joined: Sun Jun 04, 2017 8:56 am

Re: Somethings not (or hidden) in doc but you need to know

Postby Mooncat » Fri Aug 11, 2017 3:07 am

d3x0r wrote:
darkfrei wrote:It would be nice to know, that functions in data.lua must be early than calling of this functions. By control.lua it's not important.

it is important still of you specify 'local' on the function.


I think I understand what you meant.
Added "CODE ACCESSIBILITY IN DATA VS CONTROL". ;)
User avatar
Mooncat
Smart Inserter
Smart Inserter
 
Posts: 1163
Joined: Wed May 18, 2016 4:55 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby Koub » Fri Aug 11, 2017 5:56 am

I am no modder, so I'm not sure how overwhelmingly useful all these tips are, but I guess it's the kind of stuff that should be stickied, so that it doesn't disappear in the mysterious deapths of the forum, where there be biters lurking, and stuff.
[Koub] Stickied.
Koub - Please consider English is not my native language.
Koub
Global Moderator
Global Moderator
 
Posts: 2944
Joined: Fri May 30, 2014 8:54 am
Location: France

Re: Somethings not (or hidden) in doc but you need to know

Postby Optera » Fri Aug 11, 2017 6:20 am

Very useful compendium.
It contains a lot of things I stumbled across myself.

Here's another peculiarity that broke a lot of my mods when transitioning from 0.14 to 0.15.
Variable paths can conflict between mods
setting paths like this can cause Factorio to look in the wrong place
Code: Select all
icon = "__"..MOD_NAME.."__/graphics/icon.png"

instead use static paths
Code: Select all
icon = "__my_mod__/graphics/icon.png"
My Mods:
User avatar
Optera
Smart Inserter
Smart Inserter
 
Posts: 1268
Joined: Sat Jun 11, 2016 6:41 am
Location: Österreich

Re: Somethings not (or hidden) in doc but you need to know

Postby Mooncat » Fri Aug 11, 2017 7:38 pm

Koub wrote:I am no modder, so I'm not sure how overwhelmingly useful all these tips are, but I guess it's the kind of stuff that should be stickied, so that it doesn't disappear in the mysterious deapths of the forum, where there be biters lurking, and stuff.
[Koub] Stickied.


Thanks! I'm sure this will help a lot of people. :D

Optera wrote:Very useful compendium.
It contains a lot of things I stumbled across myself.

Here's another peculiarity that broke a lot of my mods when transitioning from 0.14 to 0.15.
Variable paths can conflict between mods
setting paths like this can cause Factorio to look in the wrong place
Code: Select all
icon = "__"..MOD_NAME.."__/graphics/icon.png"

instead use static paths
Code: Select all
icon = "__my_mod__/graphics/icon.png"


I tried but couldn't reproduce. :?
But there is a slight difference: my mod names don't use underscore (_) but hyphen (-). Don't know if that matters. Don't know why even if so.
Are you really sure MOD_NAME = "my_mod"?
User avatar
Mooncat
Smart Inserter
Smart Inserter
 
Posts: 1163
Joined: Wed May 18, 2016 4:55 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby Optera » Fri Aug 11, 2017 8:09 pm

Mooncat wrote:I tried but couldn't reproduce. :?
But there is a slight difference: my mod names don't use underscore (_) but hyphen (-). Don't know if that matters. Don't know why even if so.
Are you really sure MOD_NAME = "my_mod"?

It seemed to be quite a problem for some users of my mods. I couldn't reproduce it myself either, maybe they where haphazardly repacking them into modpacks. :roll:
After changing my paths to static strings all complaints stopped entirely.
My Mods:
User avatar
Optera
Smart Inserter
Smart Inserter
 
Posts: 1268
Joined: Sat Jun 11, 2016 6:41 am
Location: Österreich

Re: Somethings not (or hidden) in doc but you need to know

Postby Mooncat » Fri Aug 11, 2017 8:30 pm

Optera wrote:
Mooncat wrote:I tried but couldn't reproduce. :?
But there is a slight difference: my mod names don't use underscore (_) but hyphen (-). Don't know if that matters. Don't know why even if so.
Are you really sure MOD_NAME = "my_mod"?

It seemed to be quite a problem for some users of my mods. I couldn't reproduce it myself either, maybe they where haphazardly repacking them into modpacks. :roll:
After changing my paths to static strings all complaints stopped entirely.


I can't add if I can't verify it. Sorry. :(
User avatar
Mooncat
Smart Inserter
Smart Inserter
 
Posts: 1163
Joined: Wed May 18, 2016 4:55 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby Nexela » Fri Aug 11, 2017 9:03 pm

Optera wrote:Very useful compendium.
It contains a lot of things I stumbled across myself.

Here's another peculiarity that broke a lot of my mods when transitioning from 0.14 to 0.15.
Variable paths can conflict between mods
setting paths like this can cause Factorio to look in the wrong place
Code: Select all
icon = "__"..MOD_NAME.."__/graphics/icon.png"

instead use static paths
Code: Select all
icon = "__my_mod__/graphics/icon.png"



The reason this broke is explaind in CODE ACCESSIBILITY IN DATA VS CONTROL

You are setting a global variable with a generic name MOD_NAME in the data stage.
Mod B is now setting the same variable with their mod name
When data-updates time rolls around MOD_NAME is set to Mod B's name


The solution(s) in order of preference
1. local all the damn things
2. Use a less generic var name LTN_PATH
Nexela
Smart Inserter
Smart Inserter
 
Posts: 1666
Joined: Wed May 25, 2016 11:09 am

Re: Somethings not (or hidden) in doc but you need to know

Postby Mooncat » Fri Aug 11, 2017 9:08 pm

Ah, yes! That can explain it.
User avatar
Mooncat
Smart Inserter
Smart Inserter
 
Posts: 1163
Joined: Wed May 18, 2016 4:55 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby Optera » Sat Aug 12, 2017 5:00 am

Nexela wrote:
Optera wrote:Very useful compendium.
It contains a lot of things I stumbled across myself.

Here's another peculiarity that broke a lot of my mods when transitioning from 0.14 to 0.15.
Variable paths can conflict between mods
setting paths like this can cause Factorio to look in the wrong place
Code: Select all
icon = "__"..MOD_NAME.."__/graphics/icon.png"

instead use static paths
Code: Select all
icon = "__my_mod__/graphics/icon.png"



The reason this broke is explaind in CODE ACCESSIBILITY IN DATA VS CONTROL

You are setting a global variable with a generic name MOD_NAME in the data stage.
Mod B is now setting the same variable with their mod name
When data-updates time rolls around MOD_NAME is set to Mod B's name


The solution(s) in order of preference
1. local all the damn things
2. Use a less generic var name LTN_PATH

Thanks, that explains it.

You might want to explicitly state variables used in config.lua should have an unique prefix like prototype names. Localizing those variables makes no sense, but they they should be prone to overwrite each other.
My Mods:
User avatar
Optera
Smart Inserter
Smart Inserter
 
Posts: 1268
Joined: Sat Jun 11, 2016 6:41 am
Location: Österreich

Re: Somethings not (or hidden) in doc but you need to know

Postby Nexela » Sat Aug 12, 2017 7:10 am

config.lua is just a lua file and the recommendation is to treat it like all other lua modules.

config.lua
Code: Select all
local config = {}
config.a = "a"
config.b = "b"
return config



otherfile.lua
Code: Select all
local config = require 'config'
if config.a then print config.b end
Nexela
Smart Inserter
Smart Inserter
 
Posts: 1666
Joined: Wed May 25, 2016 11:09 am

Re: Somethings not (or hidden) in doc but you need to know

Postby Mooncat » Tue Aug 15, 2017 2:54 am

Added some new topics these few days:

Data:
  • Error - invalid prototype array nil
  • Solution to incorrect icon size
  • Max image size
  • Icon tinting, multi-layered icon
  • Large maximum_wire_distance can cause lag
  • Stream projectile particle_buffer_size has to be at least 2
  • cluster_count has to be at least 2

Control:
  • Only one handler for each event
  • How to order deconstruct tiles
  • The cause in on_entity_died does not always work

The Mod Portal:
  • Character limit
  • New portal
User avatar
Mooncat
Smart Inserter
Smart Inserter
 
Posts: 1163
Joined: Wed May 18, 2016 4:55 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby Mooncat » Fri Aug 25, 2017 3:00 am

Added the following info:
Data: push-back effect takes the target entity collider size into account
Control: Find entity using position will not return entities without collider

Also improved:
Data: Stream projectile particle_buffer_size has to be at least 2
User avatar
Mooncat
Smart Inserter
Smart Inserter
 
Posts: 1163
Joined: Wed May 18, 2016 4:55 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby eradicator » Sun Aug 27, 2017 7:24 pm

New modders often seem to misunderstand why "function() end" is often used when registering event handlers and use it wrongly (this is more of a generic lua thing than factorio specific tho).

For example mods i look at often do something like this:

Code: Select all
local function my_tick_handler(event)
  --stuff
  end

script.on_event(defines.events.on_tick, function(event) my_tick_handler(event) end)



instead of just

Code: Select all
script.on_event(defines.events.on_tick,my_tick_handler)


So they create an unnessecary wrapper function when they already have a seperate handler function.
User avatar
eradicator
Filter Inserter
Filter Inserter
 
Posts: 383
Joined: Tue Jul 12, 2016 9:03 am

Re: Somethings not (or hidden) in doc but you need to know

Postby darkfrei » Sun Aug 27, 2017 7:47 pm

eradicator wrote:New modders often seem to misunderstand why "function() end" is often used when registering event handlers and use it wrongly (this is more of a generic lua thing than factorio specific tho).
So they create an unnessecary wrapper function when they already have a seperate handler function.


And when I need two handlers?

Code: Select all
function first_tick_handler(event)
-- first part
end

function second_tick_handler(event)
-- second part
end

script.on_event(defines.events.on_tick, function(event)
first_tick_handler(event)
second_tick_handler(event)
end)
Last edited by darkfrei on Mon Aug 28, 2017 8:14 am, edited 1 time in total.
User avatar
darkfrei
Filter Inserter
Filter Inserter
 
Posts: 758
Joined: Thu Nov 20, 2014 11:11 pm

Re: Somethings not (or hidden) in doc but you need to know

Postby eradicator » Sun Aug 27, 2017 8:15 pm

darkfrei wrote:And when I need two handlers?

Then you do what you just said.
My point was the erroneous usage when the extra wrapper is added just because the new modder saw someone else do it like that and they didn't understand why that works. Also if you have two different tick handlers for the same thing you should probably combine them ;P.

Edit:

Oh an while talking about tick handlers, the often used "if event.tick % 60 == 0" can be slightly improved by using semi-random numbers instead, e.g. ""if event.tick % 61 == 42", this makes it less likely that several mods end up doing their handler on the same tick. As long as the tick handler isn't really heavy this won't make a huge differnce tho. But processing spikes are something to be kept in mind when dealing with on_tick.
User avatar
eradicator
Filter Inserter
Filter Inserter
 
Posts: 383
Joined: Tue Jul 12, 2016 9:03 am

Re: Somethings not (or hidden) in doc but you need to know

Postby darkfrei » Sun Aug 27, 2017 8:59 pm

Why in control.lua can be that:
Code: Select all
function foo(event)
-- code here
end

script.on_event(defines.events.on_tick, function(event)
foo(event)
bar(event)
end)

function foo(event)
-- code here
end


But in data.lua it don't works?

Code: Select all
function foo(data)
-- code here
end

foo(data)
bar(data)

function foo(data)
-- code here
end


Here function must be early than calling of it.
User avatar
darkfrei
Filter Inserter
Filter Inserter
 
Posts: 758
Joined: Thu Nov 20, 2014 11:11 pm

Next

Return to Modding discussion

Who is online

Users browsing this forum: dtoxic and 1 guest