DivOresity

by Mylon

Ores are all mixed up! Adds a small logistical challenge dealing with impure ores. AKA "Diversity".

Content
25 days ago
0.16 - 2.0
1.71K
Mining

i Allow black-/whitelisting of surfaces

1 year, 8 months ago
(updated 1 year, 8 months ago)

Hi! Would you mind adding an interface that other mods could use to black- or whitelist their surfaces with your mod?

Reason: My mod miniMAXIme allows players to switch between different characters (provided by third-party mods) on the fly. Each player gets a GUI with previews of the available characters. To better organize things, I create a surface for each selectable character prototype and place one entity of this prototype for each player on each of these preview-surfaces. The surfaces are not meant to be explored by players, they are just meant as a storage place for entities created by my mod. Therefore, creating ores on preview-surfaces does not make sense.

Currently, considering all character mods I'm aware of, there are almost 40 characters players could choose from (provided they've installed all character mods). This means you'd create ores on almost 40 surfaces unnecessarily. There may be other mods that also create new surfaces for private purposes. Providing a way to black-/and whitelist surface names with your mod would make your mod more efficient (I assume generating ores isn't trivial), and would make sure that your mod doesn't mess with what's expected by other mods.

If you have any questions regarding this, please feel free to PM me on the forum, or just answer here. :-)

1 year, 8 months ago

This sounds like an interesting mod. DivOresity only swaps existing ores on the surface. It only creates ores as replacements for other ores. If those ores are disabled, they should not be valid candidates to be used as replacements. And if no ores spawn at all, then there won't be anything for divOresity to do! If you remove ores via script, those ores will be removed before divOresity does its thing, or after divOresity does its thing. DivOresity won't trigger again and re-add them.

For purpose of helper surfaces, you can set the map size to 1x1. This is how I designed AAI-Signal-Transmission's helper surface.

I hope this addresses your concerns!

1 year, 7 months ago
(updated 1 year, 7 months ago)

This sounds like an interesting mod. DivOresity only swaps existing ores on the surface. It only creates ores as replacements for other ores. If those ores are disabled, they should not be valid candidates to be used as replacements. And if no ores spawn at all, then there won't be anything for divOresity to do!

Thanks for the explanation! I haven't played around with the advanced things one can do with surfaces yet because I just needed a place to hide my entities. So the way I create surfaces is rather simple, very roughly like this:

if not game.surfaces[name] and game.surfaces[name].valid then
  surface = game.create_surface(name, {width = 1, height = 1, peaceful_mode = true}) 
  surface.always_day = true
  surface.show_clouds = false
end

Shouldn't this be sufficient?

For purpose of helper surfaces, you can set the map size to 1x1. This is how I designed AAI-Signal-Transmission's helper surface.

That's the size I set on creating surfaces. But I need more space because I must place an entity for each player there, spaced 10 tiles apart from each other so the different entities won't overlap on camera. (I can't use the same entity for all players because each preview character will wear the same armor as the player it belongs to.) Yet it seems I can create entities anywhere on the surface, and I can also teleport player.character to any position on this surface, but I can't move it beyond the limits set by surface.width and surface.height -- is that correct?

I hope this addresses your concerns!

Actually, I get some crashes:

On adding your mod to a game where my preview surfaces already existed:

Error while running event DivOresity::on_init()
__DivOresity__/control.lua:33: attempt to index field 'autoplace_controls' (a nil value)  
stack traceback:
    __DivOresity__/control.lua:33: in function 'enrich_surface'
    __DivOresity__/control.lua:17: in function <__DivOresity__/control.lua:13>

You can fix that by adding a check for autoplace_controls:

for resource_name, resource in pairs(game.entity_prototypes) do
    if resource.type == "resource"
    --and resource.resource_category == "basic-solid"
    --and resource.autoplace_specification
    and surface.map_gen_settings.autoplace_controls and           -- ADDED LINE
    and surface.map_gen_settings.autoplace_controls[resource_name]
    and surface.map_gen_settings.autoplace_controls[resource_name].size > 0 then

You could even improve this by looping over a list of just the resources instead of all entities:

  local resources = game.get_filtered_entity_prototypes({ {filter = "type", type = "resource"} })
  for resource_name, resource in pairs(resources) do
    if surface.map_gen_settings.autoplace_controls and
        surface.map_gen_settings.autoplace_controls[resource_name] and
        surface.map_gen_settings.autoplace_controls[resource_name].size > 0 then

I also get a crash when I start a new game:

Error while running event minime::on_init()
The mod DivOresity (1.2.0) caused a non-recoverable error.
Please report this error to the mod author.

Error while running event DivOresity::on_surface_created (ID 63)
__DivOresity__/control.lua:26: attempt to index local 'surface' (a nil value)
stack traceback:
  __DivOresity__/control.lua:26: in function <__DivOresity__/control.lua:24>
stack traceback:
  [C]: in function 'create_surface'
  __minime__/control.lua:239: in function 'init'
  __minime__/control.lua:328: in function <__minime__/control.lua:325>

You try to get the surface using

    local surface = event.surface

This doesn't work because the events on_surface_created, on_surface_imported, and on_surface_deleted pass on event.surface_index instead of event.surface, so you should use

local surface = event.surface or (event.surface_index and game.surfaces[event.surface_index])
1 year, 7 months ago
(updated 1 year, 7 months ago)

That's the size I set on creating surfaces. But I need more space because I must place an entity for each player there, spaced 10 tiles apart from each other so the different entities won't overlap on camera. (I can't use the same entity for all players because each preview character will wear the same armor as the player it belongs to.) Yet it seems I can create entities anywhere on the surface, and I can also teleport player.character to any position on this surface, but I can't move it beyond the limits set by surface.width and surface.height -- is that correct?

You can create entities anywhere! By default entities do not check if their placement respects their collision boxes, and barring some special cases (transport belts) they can even be stacked on top of one another.

But if I understand correctly, you want players to interact with this surface directly including move around. You can either generate the surface normally, copy how some other mod does it (like one of the design-surface mods), or use the map-limit and generate patches of walkable or pretty tiles as needed.

As for the crash report, thanks for the report. I'll get right on fixing it.

1 year, 7 months ago
(updated 1 year, 7 months ago)

You can create entities anywhere! By default entities do not check if their placement respects their collision boxes, and barring some special cases (transport belts) they can even be stacked on top of one another.

I know, some of my mods use "composite entities" where different prototypes are placed on top of each other for certain effects. I've rather been wondering about the implications for surfaces: Somehow, I had the impression that placing an entity out of the surface's bounds would enlarge that surface. But apparently chunks won't be generated until a player comes near them, so there shouldn't be a problem with tiles or ores getting placed beneath my preview characters.

But if I understand correctly, you want players to interact with this surface directly including move around.

Sorry, that was a misunderstanding. Players should never get onto the preview surfaces. I've just used commands to teleport my character to another surface (which happened to be one of my secret surfaces because I've already created them) for testing purposes. :-)

As for the crash report, thanks for the report. I'll get right on fixing it.

You're welcome! But I've found another error: You call your cleanup function in response to on_surface_deleted. But the surface has already been deleted when the event is triggered, so after

local surface = game.surfaces[event.surface_index]

surface will be nil and you can't index it to read surface.name anymore (but you could still clean up your tables at this point if they were indexed by surface.index instead of surface.name). You can fix this by listening to on_pre_surface_deleted instead of on_surface_deleted.

1 year, 7 months ago

Good catch! Thank you!

New response