Replacing Beacons with Overclocking Stations - possible?

Place to post guides, observations, things related to modding that are not mods themselves.
Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Edit: Proof of concept mod is now available on Github: https://github.com/Katharsas/Overclocking-Stations-OCS
Edit: Releases now available: https://github.com/Katharsas/Overclocki ... S/releases

Hi,

i want to make a mod that replaces beacons with "Overclocking Stations (OCS)".

Unlike beacons those would only transfer their module effects to crafting machines built directly adjacent to the OCS. In particular, one side of the OCS building must fully touch a side of a crafting machine to connect. This would allow me to maybe even create an animation that shows the OCS building physically connecting to surrounding crafting machines.

My Problem:
It seems like the existing beacons always assume you want to have a rectangular effect transmission area (not allowing me to define the detailed positioning constraints i need).

My planned workaround:
- Implement positioning checker code myself in Lua
- Give the OCS building zero transmission range, so by itself it does not do anything.
- Listen to event when crafting building is placed/removed (on_built_entity, on_entity_destroyed?)
- Place an invisible helper building underneath each crafting building that takes over the module effects of any adjacent OCS building with a range so small that it only affects the building on top of itself
- Listen to events when player changes module configuration in OCS to update all adjacent helper buildings so that crafting machines are updated with new module effect

My questions:
- Is that an idea that could work? xD
- Is there an event for when player changes (module) slots in a building? I did not find one in the API docs.

I am happy for any information i can get before i really start with this :)
Last edited by Katharsas on Wed May 18, 2022 4:29 pm, edited 3 times in total.

PFQNiet
Filter Inserter
Filter Inserter
Posts: 257
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by PFQNiet »

It sounds like it could work. It might be tricky but nothing you've described sounds outside the capabilities of the engine.

For detecting the transfer of items into or out of a beacon, you will need the fast-transfer events (if the destination is a beacon) as well as player-inventory-changed and cursor-changed events (if the player has a beacon gui open).

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Ok thanks a lot!
I already have more questions! xD

1.)
I can set a LuaEntity to be indestructable during runtime:
https://lua-api.factorio.com/latest/Lua ... structible

But it seems i cannot make my prototype indestructible from the beginning? There seems to be no attribute for that:
https://wiki.factorio.com/Prototype/Beacon#base_picture

2.)
Can i give my helper beacon object zero energy usage? When i try to set energy_usage in the beacon prototype to 0, i get

Code: Select all

Error while loading entity prototype "ocs-helper" (beacon): energy_usage must be > 0. in property tree at ROOT.beacon.ocs-helper.energy_usage
I guess i could give it a really small value, but i want to make these helper buildings as light as possible on UPS.

Edit:
Anyway, i have managed to spawn my "helper beacon" inside an assembly machine, so lets see if i can garantuee that it only affects a single machine, and i would like to support small assemblers like from bobs mods as well.

I have to say, writing Lua code in control.lua is really fun with really fast feedback cycle, and "Factorio Mod Debug" Extension for VSCode works very well (shows errors directly in my code).

Edit2:
Maybe this thread could be moved to Modding Help? I think i will have even more questions later xD

PFQNiet
Filter Inserter
Filter Inserter
Posts: 257
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by PFQNiet »

Energy usage must be strictly positive, but that energy can come from a void energy source.

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Thanks!

Another question that really troubles me a lot right now:

Everything works out fine with the helper object so far, except that my helper objects does not draw any energy. I thought this was fine, but it means that neither my Overclocking Station nor my crafting machine need to be powered at all to activate module effects, which kind of sucks (being low on power has no repercussions). Obviously, the module synchronization i scripted does only synchronize the module inventory between OCS and invisible helper but not power...

Is there a way to link my helper object to the same energy grid / power area as the corresponding crafting machine (without wires showing up), even when it has a different size, position and no selection box? (edit: found workaround, see below)

It seems like my entity must have a selection box if it wants to receive power from a power area that does not overlap its center. But the selection box for it must not be usable by the player. As an ugly workaround I could maybe make helper prototypes in varying sizes and always choose one with a selection box as big as crafting machine.

Does somebody have an idea?

Edit: And I managed to work around the visible seletion problem by placing the helper exactly centered under the machine and giving it selection_priority=0 to make it effectively unselectable, so generating helpers for all sized would be a possible workaround.

Edit 2:
Okay if have experimented with this a bit more. Apparently beacons have such massive buffers, that in the case of a power draw they request about 8.4 times as much power as they usually need just to fill their buffer. This means that beacons always get a massive amount of energy priority compared to other buildings and almost always run at 100% energy even when all other machines already grind to a halt. So usually beacons either have 100% energy or your base has died already anyway.

The worse problem is that i have found no way to dynamically change the power requirements of my OCS helper building. Anybody knows if this is possible for beacons? If i cannot adjust the power usage, then I have no chance to make the helper building power usage sync with the number of adjacent OCS buildings.

Maybe i had a chance if i could base my OCS helper on Prototype/ElectricEnergyInterface, but i think i have to base it on Prototype/Beacon to transfer the module effects... :(

Or i could spawn a second helper entity from that interface for each machine just to "simulate" appropriate energy draw....

PFQNiet
Filter Inserter
Filter Inserter
Posts: 257
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by PFQNiet »

selectable_in_game=false

If you want dynamic power management, then you will indeed need to spawn an Electric Energy Interface in addition to your Beacon.

I would suggest having the beacon draw some small fixed amount of power so that it is affected by low-power situations, then have the dynamic portion handled by the EEI.

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Thanks a lot!

Hmm that would mean that i have to generate all the different sizes to make it same size as crafting machine so it is powered when crafting machine is, i kinda wanted to avoid that because i am a little bit afraid that it is bad for load times or UPS, but i am probably wrong and it does not make much difference.

The EEI would also have to be generated for all sizes, so that would double the number of prototypes, and i already have a lot. I should just try it i guess.

PFQNiet
Filter Inserter
Filter Inserter
Posts: 257
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by PFQNiet »

In vanilla Factorio a single 3x3 entity would be enough to cover basically any machine, with only the refinery needing a 5x5 and the silo needing a 9x9. That's three entities for every size building in the game, unless I'm forgetting something.

So you won't need too many EEI entities even with modded buildings.

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Well yeah it seems to be managable. I want to support mods so i just default to generate all furnace sizes, so i get 5 sizes total for vanilla. Will be a bunch more with B&A but its still fine.

One thing though:
I generate my blueprint names like this:

Code: Select all

ocs-helper-{{-1'5, -1'5}, {1'5, 1'5}}
Basically i just append the bounding box (serialized by serpent.line and commas replaced) to the name prefix. However, if i want to reference the name that i need when i need to place them in control.lua, i need the bounding box of my entity as it is defined in data.raw (because the selection_box of runtime entities is given in absolute coordinates). Can i get read access to data.raw somehow in control.lua?

If not ill just calculate the total size and use that instead i guess. Is off-center selection_box even a thing?

Edit:
Another small thing:
If i make the helper use power, it shows up in the power statistics. That by itself is not the problem, rather that i cannot dynamically generate the locale entries for all the differently sized helper blueprints. Is there a way to do this? If not i will just hardcode this for Vanilla and some popular mod sizes i guess.

User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 387
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Silari »

Katharsas wrote:
Fri Jan 21, 2022 11:54 pm
Basically i just append the bounding box (serialized by serpent.line and commas replaced) to the name prefix. However, if i want to reference the name that i need when i need to place them in control.lua, i need the bounding box of my entity as it is defined in data.raw. Can i get read access to data.raw somehow in control.lua?
data.raw doesn't exist anymore as it's only used to make the prototypes during the data stage, but you still have access to Prototype properties through LUAGameScript. For instance, game.entity_prototypes gets you access to all the entity prototypes - it's a table indexed by the entity name. You can access the collision box property from there.

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Thanks!

Another question:
Is it performant and generally "ok" to use Entity object references as keys in a lua table? Or should i use unit_number instead? Basically

Code: Select all

table[entity] = { ... }
-- vs
table[entity.unit_number] = { ... }
I think both would work for my code, but there might be performance differences?

Edit:
Proof of concept is now public on Github for anybody interested in the code:
https://github.com/Katharsas/Overclocking-Stations-OCS
My goal is to get it working well without custom graphics first.

A lot of event handlers are still missing but you can
- place OC stations (first!)
- place assember next to OC stations (power area needs to cover center of assembler)
- change modules inside OC stations (will affect assember accordingly)

Another problem:
It seems like selection_box does NOT affect how close the power area needs to be to reach the helper building... so right now the power area must cover the middle of the assembler? Am i missing something or am i wrong (i hope)?

PFQNiet
Filter Inserter
Filter Inserter
Posts: 257
Joined: Sat Sep 05, 2020 7:48 pm
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by PFQNiet »

- You can just set localised_name=something on the helper entities, setting them all to the same single name for all of them.

- I personally wouldn't use objects as table keys like that. Use the unit number instead, yes.

- Power area is handled by the collision box, not the selection box. You can make it the same size as the base building's collision box.

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Thats awesome, thanks!

collision_box works after i used rounding. For some reason, the collision_box of an assembling machine is slightly different during control.lua compared to data-updates.lua (starting at around 3rd decimal, so its not just normal float inaccuracy)^^

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

PFQNiet wrote:
Sat Jan 22, 2022 7:59 am

- I personally wouldn't use objects as table keys like that. Use the unit number instead, yes.
This is very interesting. I tried using objects as table keys, so that a table with two entities looks like this in debugger:

Code: Select all

{ [<LuaEntity>]=true, [<LuaEntity>]=true, }
And then i easily check if an entity is inside that table with

Code: Select all

if my_table[current_entity] then ... end
I thought this would work because the game would always give me the same entity reference. But that is not actually true!

Situation:
- build machine and get "entity_built" from on_built_entity event, use it as key to remember it for later: my_table[entity_built] = true
- remove same machine and get same "entity_removed" from on_player_mined_entity event

What happens:

Code: Select all

entity_built.unit_number == entity_removed.unit_number -- TRUE
entity_built == entity_removed -- TRUE
my_table[entity_built] -- TRUE
my_table[entity_removed] -- NIL
What the fuck? The equality comparison returns true, but one is found when used as key, the other is not.
This means that table keys are not defined equal by equality operator, which is weird for a Java programmer like me xD

Lesson (like your recommendation):
It is NECESSARY to use unit_number instead of entity reference itself when trying to implement entity lookup table.

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Ok, i think i have implemented pretty much all event handlers for player actions, and it seems to work fine!
Bots/blueprints are still missing but i think that will not be a big problem and EEI i will implement later.

My next priortiy is graphics, yay!

Originally i had the idea, that the OCS visually connects to the machine it affects. My original idea was to have some kind of connector arm come out of the OCS and connect to the other end. However, this looks kinda bad when the OCS is placed near the corner of a machine, example concept art:
Image

Basically, the assembly machine is not visually centered because of perspective, so when connecting to it on the upper left and right there is much less space for the arm to connect than around the bottom. And if there are multiple OCS all connected to the same machine, it think the arms will never look to be properly spaced...

Anybody has an idea how to deal with that?
Is it maybe possible to have the arm turn slightly towards the direction of the machine that the OCS is connected to?

This would mean that i need 4 different arm animations all directions, and for each arm i would need additional variations based on which direction the arm turns, sounds like a lot of work. And it would probably still not look right.

Or maybe i could pull some perspective trick to make the OCS look like its kind of underground a bit and connecting via a kind of slight trench. This might lower the connection point....
Last edited by Katharsas on Sun Jan 30, 2022 3:47 pm, edited 3 times in total.

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

I think the best way would be to have an animation that does something, but not connecting directly to the machine.

For example:
A connector arm putting some cables into the floor towards the directon of the machine like Image.

With a design similar to this, i could also make the OCS collison free because it looks like you can walk over it.

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

I managed to get my first actual 3D render ingame:
ocs_concept_art_3.png
ocs_concept_art_3.png (813.25 KiB) Viewed 425 times
Now i just need to make the model a lot better, add connection light animations (i have given up on "arm/cable connnections") and thinking about how i can get it to tile better.

If anybody has a design idea, they would be welcome^^

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

Improved sprite:
ocs_concept_art_4.png
ocs_concept_art_4.png (1.42 MiB) Viewed 392 times

Katharsas
Inserter
Inserter
Posts: 27
Joined: Sat Nov 10, 2018 1:45 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by Katharsas »

I need help:

What is the event that triggers when robots place modules into a beacon?
I don't think this mod is possible (if i want to support blueprints) if such an event does not exist. Or i would have to constantly scan all my beacons for changes due to robots inserting, removing or upgrading modules. :(

This is basically the last thing that is missing before the mod is functionally finished. Everything else left missing is just nice to have or graphics related.

robot256
Filter Inserter
Filter Inserter
Posts: 433
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: Replacing Beacons with Overclocking Stations - possible?

Post by robot256 »

Use this mod to see if there is an event that fires. I'm not sure what you will find.

https://mods.factorio.com/mod/0-event-trace

Post Reply

Return to “Modding discussion”