My Quick Start

by nm9311

Simple almost minimalistic Quick Start Mod: Start with one of 9 startup kits (Empty, Default, Default-militant, Tiny, Small, Medium, Big, Huge or CUSTOM) to improve or decrease your Factorio experience. The kit can be selected in the mod config settings. You can also choose to put items from kit to your quickbar or to do some research in advance (big, huge or custom kit). Now you can select what to put in which quickbar slot. Multiplayer ready.

Content
a day ago
0.17 - 2.0
18.0K
Cheats

b Doesn't work in multiplayer except for first player

a month ago
(updated a month ago)

This mod is great, but it seems to fail in multiplayer for anyone who isn't the first player. I looked through control.lua and I believe I found and fixed the problem. There are two events being listened to - on_player_created and on_cutscene_canceled. When these events happen, the player inventory is set. But it seems like this does not work consistently in multiplayer. I think on_player_created is called before the player is ready, and on_cutscene_canceled happens only for the first player to join the server. This causes every player other than the first to not have inventory set.

I fixed it by changing the events to not directly update the inventory, but instead to add the player to a table, and use an on_tick function to monitor that player table. Once a player is ready, their inventory is set.

Here's my modifications to control.lua:

newPlayers = {}

-- fires on player join (multiplayer)
script.on_event(defines.events.on_player_created, function(event)
    -- record this player_index to update inventory once the player has an avatar
    newPlayers[event.player_index] = event
    game.print("New player joined the game: " .. event.player_index)
end)

-- fires on the end of the cutscene (singleplayer)
script.on_event(defines.events.on_cutscene_cancelled, function(event)
    -- record this player_index to update inventory once the player has an avatar
    newPlayers[event.player_index] = event
    game.print("New player joined the game: " .. event.player_index)
end)

script.on_event(defines.events.on_tick, function(event)
    for player_index, event in pairs(newPlayers) do
        if event ~= nil and game.players[player_index] ~= nil then
            local player = game.players[event.player_index]
            on_player_creation(player)

            game.print("Setting inventory for " .. player.name)
            newPlayers[player_index] = nil
        end
    end
end)
a month ago

Thank you for your suggestion and code provided. I never played multiplayer factorio so I very much appreciate your effort to make this mod better.
There was a slight problem (maybe it just seams like) but code in function on_player_creation(player) looks like executing 2x in single and multiplayer new game. So I did little correction but I'm not sure is that right so let me put code here:

newPlayers = {}
isPrinted = false

-- fires on player join (multiplayer)
script.on_event(defines.events.on_player_created, function(event)
-- record this player_index to update inventory once the player has an avatar
newPlayers[event.player_index] = event
if not isPrinted then
game.print("New player joined the game: " .. event.player_index)
end
end)

-- fires on the end of the cutscene (singleplayer)
script.on_event(defines.events.on_cutscene_cancelled, function(event)
-- record this player_index to update inventory once the player has an avatar
newPlayers[event.player_index] = event
if not isPrinted then
game.print("New player joined the game: " .. event.player_index)
end
end)

script.on_event(defines.events.on_tick, function(event)
for player_index, event in pairs(newPlayers) do
if event ~= nil and game.players[player_index] ~= nil then
local player = game.players[event.player_index]
on_player_creation(player)

        if not isPrinted then   
            game.print("Setting inventory for " .. player.name)
        end 
        isPrinted = true

        newPlayers[player_index] = nil
    end
end

end)
...
and so it the rest of the code where game.print is used.

a month ago

Thanks for checking out the code!

As far as it running twice in multiplayer, that is semi-intended (or at least seems required to avoid a different bug). I initially had the code only run in on_player_created, but that seemed to have the exact opposite problem - it worked only in multiplayer and only for subsequent players. I added some logging and followed what it was doing, and it seems like calling it at on_player_created would set the inventory, but then on_cutscene_canceled would revert the inventory.

Running it twice seemed harmless, though. It does set the inventory twice, but because of the inventory revert in on_cutscence_canceled, it sets, clears, then sets again. Or at least that's what I gathered. This is my first time working with Factorio mods so I may not have been looking at it right.

a month ago

It looks like the code is running well and I will leave it like this for now. I thought that running the code twice is harmless. Thank you so much for this.

New response