Autodrive

by Pi-C

Car equipment for train avoidance, logistic network integration, circuit network connectivity, fuel refill, ammo reload, vehicle repair, radio control, enemy targeting, and gate control.

Content
2 months ago
0.17 - 1.1
2.98K
Transportation Combat Logistic network Circuit network

g [Fixed] High UPS consumption

5 years ago

In my game I have 2 cars with remotes, which have only enemy and gate sensors in them (using Vehicle grid mod). When I press F5, it shows, that the Autodrive mod takes 0.2 of CPU time, while even the next most greedy mod, Bottleneck, eats only 0.02. This is kinda akward... Could this be optimized, please?

5 years ago

It has been optimized, but I'm happy to check a save game if you have one, in case there's an edge case you've found.

Unfortunately the Factorio API isn't designed to do stuff like this efficiently because enemies and gates aren't detectable using events, and instead require a periodic on-tick proximity scan from Lua. Train sensor is similar.

5 years ago

Thank you for the fast answer. You are right, I should have thought about adding a sample save game for the request. This could as well be some of other mods interfering. I shall try to catch a moment with a good, distinct CPU consumption peak and prepare a save for analysis.

Meanwhile, could you please also take a look at the problem with bouncing off from the trees? I believe it should be the same for everyone.

4 years ago

Sorry to bump such an old thread, but this also caught my eye - so i went looking into your source code.

I've since pushed a merge request in Gitlab that halfs the UPS usage with zero performance penalty to the mod itself:
https://gitlab.com/aerosuidae/autodrive/merge_requests/1

4 years ago

@ AlienX: Did you look at the source in Gitlb, or directly in the downloaded mod? I'm collaborating on the mod (I take responsibility for all updates since 0.1.18), but I don't use git and I'm not sure whether dorfl merged the latest changes yet. From what I saw at the link, the line numbers are different from those in my latest version, so chances are the code on Gitlab isn't up to date yet. I'll have to see whether your changes would conflict with anything I changed -- but it may take a while until I get around to it (RL interfering a bit at the moment).

'The latest version integrates GCKI into the GUI, so it's necessary to check vehicles often enough that the GUI reflects changes like vehicles turned to inactive mode in a timely manner. If you want to check it out for yourself, you should try Autodrive together with GCKI, use the radio control for controlling a vehicle with Autodrive and the keys to first claim, then lock/unlock that vehicle with GCKI.

4 years ago
(updated 4 years ago)

Hi Pi-C, thanks for your response
Not sure if the code is updated on GitLab however, I just downloaded the 2.0 zip from the Mod Portal and the same fix can be applied from the looks of things.

There is no reason to check if a players GUI has been setup every single tick when this can simply be done once when the player connects as you're already doing in control.lua:1862, the gui_buttons() function does not actually seem to update the state of any GUI elements, it only seems to setup the required GUI elements then finish.

Perhaps I am not fully understanding, but what is the reason to destroy and totally recreate the GUI for every player in the server when only one single player joins? - this seems very strange.

I have since tested Autodrive v0.2.0 with my changes, and the UPS is still helped massively with them.

Just some tips i guess :)

4 years ago

There is no reason to check if a players GUI has been setup every single tick when this can simply be done once when the player connects as you're already doing in control.lua:1862, the gui_buttons() function does not actually seem to update the state of any GUI elements, it only seems to setup the required GUI elements then
finish.

Just checked: That call was there before I meddled with this mod. "check_state()" sounds important so I probably thought it would check the state of the vehicles. Not sure why it has been included there in the first place, but you're right: It doesn't seem to make much sense.

Perhaps I am not fully understanding, but what is the reason to destroy and totally recreate the GUI for every player in the server when only one single player joins? - this seems very strange.

Apparently you didn't read the comment above that:

--------------------------------------------------------------------------------------------
-- Reset GUI if a new player joins the game or a player returns (on_player_joined_game
-- works in multiplayer and singleplayer mode). (Pi-C)
script.on_event({defines.events.on_player_created, defines.events.on_player_joined_game}, function(event)
    GCKI = GCKI or GCKI_installed()
    check_state("init")
end)

You're right that it doesn't make much sense for multiplayer (MP) games. However, if I fire up Factorio and load a game in single player (SP) mode, on_player_joined_game will trigger as well. The thing is, all players will have to use the same configuration (same version of game and mods) -- but while nobody but the admin/host of a game in MP can add/remove mods or change global settings, "all players" IS the admin in SP games. Every time somebody loads the game in SP, some mod may have been added or removed; if that mod is GCKI, I need to rebuild the GUI for "everyone" (i.e. the only single player).

Thinking about it, it seems strange why I didn't do this in on_configuration_changed only, but it's almost a month ago since I made the last update and I can't really remember. However, I've found this comment to my own future self:

--------------------------------------------------------------------------------------------
-- This function will usually be called with just one argument (player). If there is a
-- second argument ("init"), it will force removal/rebuilding of the GUI. This is needed for
-- on_configuration_changed and on_player_joined_game to make sure the GUI will be up to
-- date if a mod has been added/removed or mod settings have changed.
local function gui_buttons(player, init)

I guess only acting in on_configuration_changed didn't work quite as expected. :-D

Also, I usually play SP. For testing, I've run MP locally, with two Factorio instances on the same computer. That's awfully slow already, and both players join only once per "game" session, so this extra call hardly mattered. However, I can see that it's probably different in a real MP game that goes on for hours, with players disconnecting/reconnecting frequently. A solution would be to separate the events for on_player_created and on_player_joined_game, and add a check for "not MP game" before calling check_state in on_player_joined_game.

Just some tips i guess :)

Thank you! If you happen to play real MP games, I'd be glad about more feedback (also regarding GCKI) -- there are things you just don't think about if you have no first-hand experience …

4 years ago

Thanks for the response, it's very detailed and helpful :)
Personally I do not think in my 3000+ hours of Factorio i have ever played on Single Player heh.

Whatever the outcome of our conversations, I hope that it has helped the mod become even better than it already is in the future :)

4 years ago
(updated 4 years ago)

Sorry, bad news! Your changes don't work. The problem is that each player's GUI shows all vehicles controlled by Autodrive (including those selected by other players). I tried to remove call check_state() from on_tick(), replacing it with just the first part of the function to sync with the global table:

local mod = global
mod.cars = mod.cars or {}

However, that caused serious lags in multiplayer mode (found lots of "Latency changed to (x)" in the client's log file). You obviously don't want this!

The on_player_created event is redundant, though. In my logs, on_player_created was called when a new game was started (MP + SP), and when a player joined the game for the first time (MP). It was immediately followed by a call to on_player_joined_game when a new game was started (MP + SP), when a player joined the game for the first time (MP), or when a player reconnected (MP). So, listening to just on_player_joined_game should be sufficient. Needless to say, the UPS gain is minimal as on_player_created is called just once for every player.

Perhaps it would help if players could see just the vehicles they control themselves in their GUI, not those of other players. I expect that to remove the need for synchronizing the GUI state on every tick. Don't know if it will work with MP, and I'm afraid that implementing and testing the changes will be a lengthy process. I've put it on my TODO list, but don't expect an update anytime soon! :-D

4 years ago

Whatever the outcome of our conversations, I hope that it has helped the mod become even better than it already is in the future :)

I've finally figured out how to do it. So in the next version, the GUI won't be rebuilt on every tick anymore, which already accounts for a lot of wasted UPS. The other factor (on every 30th or 60th tick -- not quite sure) was polling GCKI for the locked status of a vehicle. That's gone now, instead of pulling the data from Autodrive, I push them now from GCKI's end if a vehicle is locked or unlocked. Apart from saving even more UPS, there's another gain: the GUI can now be updated immediately.

4 years ago

Please try 0.1.26/0.2.6!

New response