on_player_selected_area

Place to get help with not working mods / modding interface.
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

on_player_selected_area

Post by evandro_6565 »

-- I want to get the selection area.. I did some tests to know which event does this but it didn't work. :?:

Code: Select all

script.on_event(defines.events.on_player_selected_area, function(event) print("on_player_selected_area") end) 

function print(text, color)
	color = color or {r = 1, g = 1, b = 1}
	if game then
		for _, p in pairs(game.players) do
			game.players[_].print(text, color)
		end
	end
end
User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 416
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: on_player_selected_area

Post by Stringweasel »

Why didn't it work? What output did you get? What input did you give? What do you want to achieve? :)

Oh you're the one with the Damage Effect mod. It looks really cool! There's some discussions that popped up on your mod page, don't know if you noticed :)
Alt-F4 Author | Factorio Modder
My Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby
Official Contributor to Space Exploration
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

:lol: :lol: I found the event: on_player_setup_blueprint :lol: :lol:
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

Stringweasel wrote: Sun Oct 02, 2022 5:48 pm Why didn't it work? What output did you get? What input did you give? What do you want to achieve? :)

Oh you're the one with the Damage Effect mod. It looks really cool! There's some discussions that popped up on your mod page, don't know if you noticed :)
yes i noticed that. my "Damage Effect" mod is having entity-ghost issues
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

Stringweasel wrote: Sun Oct 02, 2022 5:48 pm Why didn't it work? What output did you get? What input did you give? What do you want to achieve? :)

Oh you're the one with the Damage Effect mod. It looks really cool! There's some discussions that popped up on your mod page, don't know if you noticed :)
I'm having problems with "surface.find_entity_filtered" I thought it would return all entities from a specific area... for example, I have two entities assembling-machine-1 and stone-wall and it only returns stone-wall and an assembling- machine-1 instead of two :|

if it's two equal entities with the same name, it only returns one.. in the loop
User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 416
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: on_player_selected_area

Post by Stringweasel »

evandro_6565 wrote: Mon Oct 03, 2022 7:00 am I'm having problems with "surface.find_entity_filtered" I thought it would return all entities from a specific area... for example, I have two entities assembling-machine-1 and stone-wall and it only returns stone-wall and an assembling- machine-1 instead of two :|

if it's two equal entities with the same name, it only returns one.. in the loop
Can you show your code? Did you possibly specify `limit = 1` by accident?
Alt-F4 Author | Factorio Modder
My Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby
Official Contributor to Space Exploration
User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 531
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: on_player_selected_area

Post by Silari »

And how are you checking what it returns? Note that if you're using print to print the results, print will not output the same string twice. So even if you find two assembling machines if you loop over the results and print the type, it'll only print "assembling-machine-1" ONCE.
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

Silari wrote: Mon Oct 03, 2022 3:54 pm And how are you checking what it returns? Note that if you're using print to print the results, print will not output the same string twice. So even if you find two assembling machines if you loop over the results and print the type, it'll only print "assembling-machine-1" ONCE.
there is a condition before the print function that checks if the entity is a ghost and another parameter is the ghost_name to check which ghost contains the entity

Code: Select all

for _, entity in pairs(entities) do
			if entity.name:find "entity-ghost" and entity.ghost_name:find "-damaged" then
				print("replace_entity_ghost: "..entity.name)
			end
		end
when there is this condition: entity.ghost name:find "-damaged"
nothing... when you only have: entity.name:find "entity-ghost" in this condition print works..

The result I got is that I can't find the ghost of the entity I'm looking for
FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: on_player_selected_area

Post by FuryoftheStars »

Try putting a % symbol in front of those dashes within the find strings.

Code: Select all

if entity.name:find("entity%-ghost") and entity.ghost_name:find("%-damaged") then
I ran into this same issue with the Tree Sapling (Redux) mod.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics
Pi-C
Smart Inserter
Smart Inserter
Posts: 1728
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: on_player_selected_area

Post by Pi-C »

FuryoftheStars wrote: Mon Oct 03, 2022 9:00 pm Try putting a % symbol in front of those dashes within the find strings.

Code: Select all

if entity.name:find("entity%-ghost") and entity.ghost_name:find("%-damaged") then
I ran into this same issue with the Tree Sapling (Redux) mod.
From the Lua manual:
string.find (s, pattern [, init [, plain]])
Looks for the first match of pattern in the string s. If it finds a match, then find returns the indices of s where this occurrence starts and ends; otherwise, it returns nil. A third, optional numerical argument init specifies where to start the search; its default value is 1 and can be negative. A value of true as a fourth, optional argument plain turns off the pattern matching facilities, so the function does a plain "find substring" operation, with no characters in pattern being considered magic. Note that if plain is given, then init must be given as well.

If the pattern has captures, then in a successful match the captured values are also returned, after the two indices.
In this case, you could simply write

Code: Select all

if entity.name:find("entity-ghost", 1, true) and entity.ghost_name:find("-damaged", 1, true) then
When your string may be either a regular expression or plain text, you should use

Code: Select all

if (entity.name:find(pattern, 1, true) or entity.name:find(pattern)) and 
   (entity.ghost_name:find(other_pattern, 1, true) or entity.ghost_name:find(other_pattern)) then
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

Code: Select all

if (entity.name:find(pattern, 1, true) or entity.name:find(pattern)) and 
   (entity.ghost_name:find(other_pattern, 1, true) or entity.ghost_name:find(other_pattern)) then
:D ok, my script worked... but i will test this one.

Code: Select all

if entity.name == "entity-ghost" and entity.ghost_name:find "-damaged" then
but the problem I don't know if it was in the condition. I changed this "find_entities_filtered"
instead of "area" I used "radius" with a manual number of 200 to test.
with "area" nothing was returned.

Code: Select all

surface.find_entities_filtered{position = position, radius = 200}
User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 416
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: on_player_selected_area

Post by Stringweasel »

evandro_6565 wrote: Tue Oct 04, 2022 2:32 am but the problem I don't know if it was in the condition. I changed this "find_entities_filtered"
instead of "area" I used "radius" with a manual number of 200 to test.
with "area" nothing was returned.
Can you show the code that's not working?

If it works with `radius` and not `radius` then it sounds like you might be using the `area` keyword incorrectly maybe. Did you ensure the first position of the bounding box is the top left position? This means it's the smaller x and y values. An example for the docs. Or possibly you added `position` too, which will taken precidence over `area`.

Code: Select all

{{-2, -3}, {5, 8}}
or even better

Code: Select all

{left_top = {x = -2, y = -3}, right_bottom = {x = 5, y = 8}}
Alt-F4 Author | Factorio Modder
My Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby
Official Contributor to Space Exploration
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

Code: Select all

{{-2, -3}, {5, 8}}
or even better

Code: Select all

{left_top = {x = -2, y = -3}, right_bottom = {x = 5, y = 8}}

I was analyzing this code to find the area... I noticed that {{-x, -y} {x, y}} mine was positive {{x, y} {x, y}}
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

I found a big problem how to loop through the global variable without slowing it down... I think I'm using more of a loop inside the TICK

Code: Select all

script.on_event(defines.events.on_tick, function() 
	run_tick() 

	turret.on_tick()
	entity.on_tick()
	car.on_tick()
	stone.on_tick()
end)
have a problem using "FOR" loop inside the event_tick... if I use just one it can relieve the game's FPS that is dropping a lot.... I didn't know that... any ideas

every on_tick() function has a loop I think this must be crashing and lowering fps
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

the ghost entity was like the damaged entity I didn't want it because the player doesn't build this entity so it replaces the ghost of the entity of my mod with the original but in the undo tool CTRL Z doesn't work because this entity was placed by the script and not by the player staying for him to do manually

Image
Attachments
test.png
test.png (4.23 MiB) Viewed 2561 times
User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 416
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: on_player_selected_area

Post by Stringweasel »

evandro_6565 wrote: Thu Oct 06, 2022 7:54 am I found a big problem how to loop through the global variable without slowing it down... I think I'm using more of a loop inside the TICK
Oof, UPS optimization is a tough one. A few ideas, although there are many people who know much more than me:
  • What many people do is stagger the checks, for example instead of updating every tick only do it every 10th tick. Or every second. For example, Space Exploration's cargo rockets only update their signals every second.
  • You can even improve that idea even more by only updating n entities in your table, instead of all of them every single time. See this handy functio for_n_of from flib you could mimic for example. This is done very nicely in Nixie Tubes for example. If you have one nixie, then the numbers update super fast, but the more you place down, the longer they take to update - but never at the cost of the game slowing down.
  • The best on_tick is no on_tick. If you can get around not using on_tick, and rather listening for other events, then it's almost always better.
Some more specific notes about your code:
  • Correct use of tables. For example, instead of using the `#` operator to get the length of a table that changes length often, keep track of it yourself. Everytime you call `#` the the game must iterate over every item in the list to count the elements. For example, I see in your code you have a function where `radius[random(#radius)` is called 6 times, and every time it will count all the elements. Count it yourself beforehand, and rather use that stored value.
  • You could break your `global.entities` into different lists, e.g. `global.entities.cars = {}` so you can send car entities to only cars. That way you don't have to send every entity every tick to every damage check, just for the `stone` code to do a string::find to check if it's a car or not.
  • I see you pass the entity-tag between functions, and then use `e = global.entities[tag]` everytime. This is very expensive, rather send the entity object itself. You're only sending a reference so there's no issues. That a lot of unneccesary table lookups.
Then finally, you could use Factorio's Debugger which has a built-in profiler. You could see exactly which function are taking the most time. Very handy to improve performance. I've used it quite a bit to improve the performance of some of my mods.

You definitely know how to code though, I'm sure you'll get the performance better :)
Alt-F4 Author | Factorio Modder
My Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby
Official Contributor to Space Exploration
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

Code: Select all

event.on_tick(function()
  global.from_k = table.for_n_of(extremely_large_table, global.from_k, 10, function(v) game.print(v) end)
end)

this code for_n_of improved the performance... :) but I didn't understand what exactly this function returns besides the inner function I inserted. {from_k}


Factorio's Debugger, I don't know how to use it.. it seems that you have to configure the launch
User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 416
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: on_player_selected_area

Post by Stringweasel »

evandro_6565 wrote: Mon Oct 10, 2022 7:43 pm this code for_n_of improved the performance
Great! I haven't had a close look at that function, but pretty sure `from_k` keeps track of which entries you updated last.

As for the Debugger, yes. You need two files in a folder called ".vscode". For example, this is how it looks in my mod folder.

As a side note: If I was you I would seriously considering improving performance even more, because your mod seems that it will attempt to keep track of every single entity in the world! That's massive! You will easily have to store, and loop over 10 thousands of entities every time. That will bloat the save files, and (with your new `for_n_of` code) every entity might only get updated like once every 10 minutes.

I would make main changes that would greatly increase performance:
  1. As I mentioned earlier, store your different entities in seperate lists, like `global.entities.cars`, etc.
  2. More importantly, only start keeping track of entities once they're damaged by listening to `on_entity_damaged`, and then forget about the entity again if it reaches full health.
Optimizing mods like this in Lua is all about reducing the amount of table lookups. And point 2 above will decrease the amount of entities you need to update by something like 90%!

If you want I could help you out. You could host your code on GitHub (like many mods do), and I can make Pull-Requests (like this) to your code and you can add it. I think this is a really cool project, and would love to see it reach it's full potential. :)
Alt-F4 Author | Factorio Modder
My Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby
Official Contributor to Space Exploration
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

I got it, good idea to ignore entities in the table to optimize the mod this lessens the effort in the loop. :)

I'm still learning to use github...

in the debugger where exactly the location of the launch file would be. in the mod folder.. :

it generated this I have to change something..

Code: Select all

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "factoriomod",
            "request": "launch",
            "name": "Factorio Mod Debug"
        },
        {
            "type": "factoriomod",
            "request": "launch",
            "name": "Factorio Mod Debug (Settings & Data)",
            "hookSettings": true,
            "hookData": true
        },
        {
            "type": "factoriomod",
            "request": "launch",
            "name": "Factorio Mod Debug (Profile)",
            "hookMode": "profile"
        }
    ]
}
User avatar
evandro_6565
Inserter
Inserter
Posts: 35
Joined: Sat Mar 28, 2020 1:04 pm
Contact:

Re: on_player_selected_area

Post by evandro_6565 »

I have a question, do you know of a tool to visualize this code: shift = util.by_pixel(x, y) I have to keep opening and closing the game to test the positioning
Post Reply

Return to “Modding help”