Team Starts for Multiplayer

by RedRafe

Embark on an epic cooperative journey in the Space Age DLC! This mod organizes players into smaller teams on separate planets, ensuring a balanced early game experience while battling enemies together. Enjoy maximum freedom as your team collaborates, shares resources, and explores the cosmos—without the chaos of competing for resources!

Tweaks
a month ago
2.0
771
Environment

g [Todo] Pause specific area or planets

2 months ago

feat request: pause 'areas'/planets in game, when a specific player is not connected

Would be awesome to pause the area or planets, where no players are online.

We want to have seperated teams, but want to avoid biters to destroyed inactive bases.

Awesome Mod! Looking forward!

2 months ago

Hi, I dont think I can pause the game only on certain surfaces. However, other planets are not created until first player goes there. This should guarantee that even players who join later will have a new surface that has not been covered with biters.

Then yes, if players leave for days after joining, they'll probably get overrun... I cannot promise, but I will look into a solution to avoid this happens

a month ago
(updated a month ago)

We want to have seperated teams, but want to avoid biters to destroyed inactive bases.

I think the closest to it would to set the different Planet Layers to peaceful when none of the effected team members are online and enable it if any of them is connected.
That way it would stop active expansion and attacks while the specified teams are offline if not actively provoked due to turrets close to enemies.
Checks for such could be done through the player events when joining / disconnecting or triggered every x minutes/hours.

a month ago

Yes, I would also have to save evolution% when last player gets off and reapply that when they join again. Would this meet the requirements? @Ismoh

  • Set surface on peaceful while 0 players
  • Freeze evolution while 0 players
a month ago
(updated a month ago)

I think you could get close to "pausing":

  • Set all of team entities active variable to false (Pausing the factory)
  • Iterate through chunks to get the pollution, and later reset it ("Disable" pollution spread/dissipation)
  • Disable team evolution factors as well as set the entities to inactive (Pausing the enemies)
  • Set ai_controllable for the enemy force to false (Disable biter expansion)

You'd likely have to create separate enemy forces for each team to effectively disable them, and there are numerous caveats for this to work with multiplayer, for example, what to do when another teams players are on the same surface, or their buildings are there, or similar. On-top of that, I'm not particularly experienced with modding factorio, but I am a developer, and am just providing some information that I could find in the documentation.

a month ago
(updated a month ago)

I think you could get close to "pausing":

  • Set all of team entities active variable to false (Pausing the factory)
  • Iterate through chunks to get the pollution, and later reset it ("Disable" pollution spread/dissipation)

Those would indeed resolve the issue with the factory running while no one of the team is online.

  • Disable team evolution factors as well as set the entities to inactive (Pausing the enemies)

Its simpler to set the surface value to be peaceful. That way it would be savegame compatible since no new forces have to be created and each planet already has separate evolution factors and biter settings.

what to do when another teams players are on the same surface, or their buildings are there, or similar.

not sure but wasn't it that the forces get merged to the "player" faction when reaching the requirements?

a month ago
(updated a month ago)

Its simpler to set the surface value to be peaceful. That way it would be savegame compatible since no new forces have to be created and each planet already has separate evolution factors and biter settings.

Afaik, setting a surface to peaceful doesn't stop biters from evolving, nor expanding.
Also, could you elaborate what you mean by savegame compatible? I don't quite see how having multiple enemy forces would cause it to not be savegame compatible. Then again, I'm in no way an expert at modding factorio.

not sure but wasn't it that the forces get merged to the "player" faction when reaching the requirements?

It might not have been the best example, and I had somewhat missed that fact. Albeit I do wonder if there will eventually be an option to not merge forces, since personally I'd prefer that.. That's a different topic though.

a month ago
(updated a month ago)

Afaik, setting a surface to peaceful doesn't stop biters from evolving, nor expanding.

It is refering as the Peaceful mode option (as in the worldgen settings) that one can be set per surface. That one disables the expansion too but does not effect evolution
(https://lua-api.factorio.com/latest/classes/LuaSurface.html#peaceful_mode)

Also, could you elaborate what you mean by savegame compatible? I don't quite see how having multiple enemy forces would cause it to not be savegame compatible. Though again, I'm in no way an expert at modding factorio.

Existing biters have either be transfered to the new faction when updating the mod. Its easier in to just store the evolution settings of the surface (which still has to be done) than migrating each biter to the new faction on a update.

a month ago
(updated a month ago)

It is refering as the Peaceful mode option (as in the worldgen settings) that one can be set per surface. That one disables the expansion too but does not effect evolution
(https://lua-api.factorio.com/latest/classes/LuaSurface.html#peaceful_mode)

Information about peaceful mode is a bit iffy, but even if expansion is disabled while in peaceful mode, enabling peaceful mode doesn't immediately prevent biters from attacking as mentioned in the wiki (I doubt it would be different for controlling it by other means than commands).
https://wiki.factorio.com/console#Enable/Disable_peaceful_mode

Existing biters have either be transfered to the new faction when updating the mod. Its easier in to just store the evolution settings of the surface (which still has to be done) than migrating each biter to the new faction on a update.

Fair enough (albeit migrating each surfaces enemies to their own force when updating wouldn't be hard), but due to the rising evolution factor while offline (since you only would reset it once someone comes online) more dangerous enemies could potentially spawn.

So my conclusion is that you could possibly substitute setting ai_controllable with peaceful mode (I can't find concise information about peaceful mode expansion), but you still need to deactivate enemies due to the mentioned "side-effects".

a month ago

It is refering as the Peaceful mode option (as in the worldgen settings) that one can be set per surface. That one disables the expansion too but does not effect evolution
(https://lua-api.factorio.com/latest/classes/LuaSurface.html#peaceful_mode)

Information about peaceful mode is a bit iffy, but even if expansion is disabled while in peaceful mode, enabling peaceful mode doesn't immediately prevent biters from attacking as mentioned in the wiki (I doubt it would be different for controlling it by other means than commands).
https://wiki.factorio.com/console#Enable/Disable_peaceful_mode

Existing biters have either be transfered to the new faction when updating the mod. Its easier in to just store the evolution settings of the surface (which still has to be done) than migrating each biter to the new faction on a update.

Fair enough (albeit migrating each surfaces enemies to their own force when updating wouldn't be hard), but due to the rising evolution factor while offline (since you only would reset it once someone comes online) more dangerous enemies could potentially spawn.

So my conclusion is that you could possibly substitute setting ai_controllable with peaceful mode (I can't find concise information about peaceful mode expansion), but you still need to deactivate enemies due to the mentioned "side-effects".

a month ago

Accidentally pressed the wrong button..

a month ago

Information about peaceful mode is a bit iffy, but even if expansion is disabled while in peaceful mode, enabling peaceful mode doesn't immediately prevent biters from attacking as mentioned in the wiki (I doubt it would be different for controlling it by other means than commands).
https://wiki.factorio.com/console#Enable/Disable_peaceful_mode

yeah peaceful mode itself doesn't stop them directly from attacking, they only act defensive rather offensive.If they are already engaging in hostile actions (like attacking base defenses). If the players/turrets are not directly involved or by other means at that time its rather risk free to go offline. The Evolution factors itself still have to be saved separately and restored to prevent time/pollution based increase in evolution.

a month ago

yeah peaceful mode itself doesn't stop them directly from attacking, they only act defensive rather offensive.If they are already engaging in hostile actions (like attacking base defenses). If the players/turrets are not directly involved or by other means at that time its rather risk free to go offline. The Evolution factors itself still have to be saved separately and restored to prevent time/pollution based increase in evolution.

That's not what I mean. If you switch into peaceful mode, the currently existing enemies keep their hostile behavior and could still attack the factory without being provoked.
And as for evolution factor, the problem is that it's still rising during "paused" time, meaning that enemies with higher evolution levels can spawn while you are offline. Restoring the evolution factor afterwards doesn't despawn the enemies. You still need to change active status on the entities when "pausing".

a month ago

That's not what I mean. If you switch into peaceful mode, the currently existing enemies keep their hostile behavior and could still attack the factory without being provoked.

Another possibility is to the "enemy" to friendly to prevent damage for the time, while peaceful mode on the surface should prevent biter expansions.

And as for evolution factor, the problem is that it's still rising during "paused" time, meaning that enemies with higher evolution levels can spawn while you are offline. Restoring the evolution factor afterwards doesn't despawn the enemies. You still need to change active status on the entities when "pausing".

The Idea was to reset the evolution factor to 0 on the surface while offline and restore it to the original of the surface when any one is there. The only progress that would basically effect it would be Time due to all player structures beeing set to inactive and therefore not producing any form of pollution that would increase the evolution on the surface. If someone is not setting the evolution rate for time to a relatively high amount it would have almost no effect (Some even turn that the Rate Setting to 0 for MP Servers).
In terms of Biter spawns there is a soft cap nests have which is only exceeded by pollution causing it to produce new biters. Since the plan was to save pollution state (if needed) and restore it you wouldnt get any new higher tier biter spawns due to that.

a month ago

Just to compact the current thoughts:

  • Set all of team entities active variable to false
  • Iterate through chunks to get the pollution and save them for restoration (or similar solutions)
  • Disable evolution factors of the surface (is set inside the enemy force https://lua-api.factorio.com/latest/classes/LuaForce.html#set_evolution_factor ) and restore it later
  • setting surface to peaceful (to stop expansions)
  • set the enemy faction to be non hostile towards that team while the team is offline (halting enemy attacks towards that faction)
a month ago

That pretty much sums it up.
The only other thing I can think of is that when saving pollution, we should also clear it while the team is offline, so trees don't die since also saving trees would be harder.

a month ago

I didnt read everything, but I found this one, which might help:

function get_force_entities(surface, force)
    return surface.find_entities_filtered{
        force = force.name
    }
end

function are_force_players_online(force)
    local count = #force.connected_players
    return 0 ~= count
end

script.on_event(defines.events.on_player_joined_game, function(event)
    local player = game.players[event.player_index]
    local force = player.force

    local setting_debug = settings.global["protect-offline-forces-debug"].value

    if setting_debug then
        for _, p in pairs(game.players) do
            p.print('Unprotecting force ' .. force.name)
        end
    end

    local setting_indestructible = settings.global["protect-offline-forces-indestructible"].value
    local setting_inactive = settings.global["protect-offline-forces-inactive"].value

    for _, surface in pairs(game.surfaces) do
        for _, entity in pairs(get_force_entities(surface, force)) do
            if setting_indestructible then
                entity.destructible = true
            end
            if setting_inactive then
                entity.active = true
            end
        end
    end
end)

script.on_event(defines.events.on_player_left_game, function(event)
    local player = game.players[event.player_index]
    local force = player.force

    local setting_debug = settings.global["protect-offline-forces-debug"].value

    local setting_indestructible = settings.global["protect-offline-forces-indestructible"].value
    local setting_inactive = settings.global["protect-offline-forces-inactive"].value

    if not(are_force_players_online(force)) then
        if setting_debug then
            for _, p in pairs(game.players) do
                p.print('Protecting force ' .. force.name)
            end
        end

        for _, surface in pairs(game.surfaces) do
            for _, entity in pairs(get_force_entities(surface, force)) do
                if setting_indestructible then
                    entity.destructible = false
                end
                if setting_inactive then
                    entity.active = false
                end
            end
        end
    end
end)

I am not 100% sure, if deactivating entities is enough regarding polution, but it works fine regarding biters.

a month ago
(updated a month ago)

I am also interested in creating a PR on github, if you might give me a quick discord call with introtuctions. Discord: ismoh

a month ago

Iterating all the entities on a surface (or multiple surfaces) is pretty heavy on performance.
Besides, you're not accounting for other forces on the surface, or on players switching teams/forces to re-enable/disable all of that too

New response