How do I make my entity load new chunks?

Place to get help with not working mods / modding interface.
Post Reply
User avatar
Ohead
Burner Inserter
Burner Inserter
Posts: 5
Joined: Sun Sep 03, 2023 11:35 pm
Contact:

How do I make my entity load new chunks?

Post by Ohead »

So y'know how artillery shells load the chunk they're in? I wanna do that with a custom entity. How might I go about doing that?

Pi-C
Smart Inserter
Smart Inserter
Posts: 1654
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: How do I make my entity load new chunks?

Post by Pi-C »

If you have a LuaEntity, you can read its force, position and surface, and then chart an area around the position:

Code: Select all

DISTANCE = 32 	-- side length of 1 chunk

local function chart_area(entity) 
	if not (entity and entity.valid) then return end
	
	local half_size = DISTANCE/2
	local pos = entity.position
	local area = { {pos.x - half_size, pos.y - half_size}, {pos.x + half_size, pos.y + half_size} }
	
	entity.force.chart(entity.surface, area)
end
Of course, this only charts a static area. If you want to chart the surface along the path of the entity, you must call that function in regular intervals. This seems to be an ideal job for defines.events.on_tick or script.on_nth_tick, which should be activated as soon as the first of your entities is placed. You should also make sure to stop listening to these events once the last entity has been removed from the game. For this, you need to keep track of your entities:

Code: Select all

require("util)
local on_tick = function(event)
	if not (global.entities and next(global.entities)) then
		script.on_event(defines.events.on_tick, nil)
		return
	end
	
	local entity, last_pos
	for e, e_data in pairs(global.entities) do
		entity, last_pos = e_data.entity, e_data.position
		
		if entity and entity.valid then
			if util.distance(entity.position, last_pos) > DISTANCE then
				chart_area(entity) 
				e_data.position = entity.position
			end
		else
			global.entities[e] = nil
		end
	end
end


local function add_entity(event)
	local entity = event.created_entity or 	-- on_built_entity, on_robot_built_entity
	                     event.entity or 			-- script_raised_built, script_raised_revive
	                     event.destination			-- on_entity_cloned
	
	if entity.name == "YOUR_ENTITY_NAME" then
		-- Enable on_tick handler if this is the entity list is empty!
		if not next(global.entities) then
			script.on_event(defines.events.on_tick, on_tick)
		end
		
		-- Add entity to list
		global.entities[entity.unit_number] = { ["entity"] = entity, ["position"] = entity.position}
	end
end

script.on_init(function()
	global.entities = {}
end)

script.on_load(function()
	if (global.entities and next(global.entities) then
		script.on_event(defines.events.on_tick, on_tick)
	end
end)

-- Register handler for events that create entities
local listen_to = {
	"on_built_entity", "on_robot_built_entity", "on_entity_cloned",
	"script_raised_built", "script_raised_revive"
}
for e, event in pairs(listen_to) do 
	script.on_event(defines.events[event], add_entity)
end
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

User avatar
Ohead
Burner Inserter
Burner Inserter
Posts: 5
Joined: Sun Sep 03, 2023 11:35 pm
Contact:

Re: How do I make my entity load new chunks?

Post by Ohead »

Incredibly helpful, many thanks! :D

Post Reply

Return to “Modding help”