Merge lp:~widelands-dev/widelands/bug-1827033-shipping-algorithm into lp:widelands

Proposed by Benedikt Straub
Status: Merged
Merged at revision: 9127
Proposed branch: lp:~widelands-dev/widelands/bug-1827033-shipping-algorithm
Merge into: lp:widelands
Diff against target: 68 lines (+18/-8)
2 files modified
src/economy/portdock.cc (+16/-7)
src/logic/map_objects/tribes/ship.cc (+2/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug-1827033-shipping-algorithm
Reviewer Review Type Date Requested Status
GunChleoc Approve
Review via email: mp+366959@code.launchpad.net

Commit message

Fix an assert fail because of nullptr destinations in the shipping algorithm

Description of the change

I have a feeling that this only masks the real issue. Portdock code first removes items that don´t have a portdock as destination and implicitly re-adds them at once. This causes *nullptr to be passed as an argument, resulting in the assert fail.
This branch simply prevents this situation by skipping something that doesn´t work anyway, so it shouldn´t have undesired side-effects. Someone who knows (or wrote) that code should check why the unallowed elements are adressed to a portdock when they should not be and therefore re-add themselves...

To post a comment you must log in.
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4896. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/528437763.
Appveyor build 4677. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1827033_shipping_algorithm-4677.

Revision history for this message
kaputtnik (franku) wrote :

I am in favor to revert the changes that caused this failure... although the 'old' shipping algorithm isn't perfect.

Revision history for this message
Benedikt Straub (nordfriese) wrote :

Apart from this bug, which happens quite often, no unusual behaviour was observed in shipping so far. I would vote to merge this symptomatic fix, and if more problems are found, to revert or rewrite the algorithm.

Revision history for this message
kaputtnik (franku) wrote :

> no unusual behaviour was observed in shipping so far.

I think it is very unusual that a ship navigate to a port, unload all wares and immediately load the same wares again to navigate the wares to the destination port. In the end this means the time a ware is transported will grow with the number of ports.

Shouldn't the question be: Does the new shipping algorithm add any features?

But i agree that this bug should fixed very soon. Test games on seafaring maps makes no fun until this is fixed.

Revision history for this message
GunChleoc (gunchleoc) wrote :

I have added a tiny code style tweak. I'll let some AIs dish it out on this branch now.

Sorry for dragging my heels on this one.

review: Approve
Revision history for this message
GunChleoc (gunchleoc) wrote :

> I think it is very unusual that a ship navigate to a port, unload all wares and immediately load the same wares again to navigate the wares to the destination port. In the end this means the time a ware is transported will grow with the number of ports.

This should definitely be fixed too

> Shouldn't the question be: Does the new shipping algorithm add any features?

The goal was to make ship transportation more efficient overall

Revision history for this message
Benedikt Straub (nordfriese) wrote :

> I think it is very unusual that a ship navigate to a port, unload all wares and immediately load the same wares again to navigate the wares to the destination port.

Wasn´t aware of that one yet, but that has to be fixed of course.
I think this won´t be possible without rewriting most of the shipping algorithm due to the sometimes strange and potentially very buggy codeflow. I will try that out soon.
This branch should be considered a provisional fix to make seafaring games on debug builds possible again without a crash every two minutes, and hopefully I can provide a more stable algorithm (with a different approach) to replace it sometime soon.

Revision history for this message
kaputtnik (franku) wrote :

This behavior applies also for workers (soldiers), as mentioned in the bug report at #3 (4. paragraph) and comment #6 (replay).

Lets have this then and create another bug report?

Revision history for this message
GunChleoc (gunchleoc) wrote :

@bunnybot merge

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 5062. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/537402325.
Appveyor build 4842. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1827033_shipping_algorithm-4842.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/economy/portdock.cc'
2--- src/economy/portdock.cc 2019-04-24 15:11:23 +0000
3+++ src/economy/portdock.cc 2019-05-26 10:11:35 +0000
4@@ -368,26 +368,34 @@
5 }
6 }
7
8+ // Decide where the arrived ship will go next
9+ PortDock* next_port = fleet_->find_next_dest(game, ship, *this);
10+ if (next_port) {
11+ // Unload any wares/workers onboard the departing ship which are not favored by next dest
12+ ship.unload_unfit_items(game, *this, *next_port);
13+ }
14+#ifndef NDEBUG
15+ else {
16+ assert(ship.get_nritems() == 0);
17+ }
18+#endif
19+
20 // Check for items with invalid destination. TODO(ypopezios): Prevent invalid destinations
21 for (auto si_it = waiting_.begin(); si_it != waiting_.end(); ++si_it) {
22 if (!si_it->get_destination(game)) {
23 // Invalid destination. Carry the item back into the warehouse
24+ // TODO(Nordfriese): This readds the invalid item to the list
25 si_it->set_location(game, warehouse_);
26 si_it->end_shipping(game);
27 si_it = waiting_.erase(si_it);
28 }
29 }
30
31- // Decide where the arrived ship will go next
32- PortDock* next_port = fleet_->find_next_dest(game, ship, *this);
33 if (!next_port) {
34- ship.set_destination(next_port);
35+ ship.set_destination(nullptr);
36 return; // no need to load anything
37 }
38
39- // Unload any wares/workers onboard the departing ship which are not favored by next dest
40- ship.unload_unfit_items(game, *this, *next_port);
41-
42 // Then load the remaining capacity of the departing ship with relevant items
43 uint32_t remaining_capacity = ship.descr().get_capacity() - ship.get_nritems();
44
45@@ -402,7 +410,8 @@
46
47 // Then load any wares/workers favored by the chosen destination
48 for (auto si_it = waiting_.begin(); si_it != waiting_.end() && remaining_capacity > 0; ++si_it) {
49- if (fleet_->is_path_favourable(*this, *next_port, *si_it->get_destination(game))) {
50+ const PortDock* dest = si_it->get_destination(game);
51+ if (dest && fleet_->is_path_favourable(*this, *next_port, *dest)) {
52 ship.add_item(game, *si_it);
53 si_it = waiting_.erase(si_it);
54 --remaining_capacity;
55
56=== modified file 'src/logic/map_objects/tribes/ship.cc'
57--- src/logic/map_objects/tribes/ship.cc 2019-05-11 13:48:12 +0000
58+++ src/logic/map_objects/tribes/ship.cc 2019-05-26 10:11:35 +0000
59@@ -788,7 +788,8 @@
60 void Ship::unload_unfit_items(Game& game, PortDock& here, const PortDock& nextdest) {
61 size_t dst = 0;
62 for (ShippingItem& si : items_) {
63- if (fleet_->is_path_favourable(here, nextdest, *si.get_destination(game))) {
64+ const PortDock* dest = si.get_destination(game);
65+ if (dest && fleet_->is_path_favourable(here, nextdest, *dest)) {
66 items_[dst++] = si;
67 } else {
68 here.shipping_item_returned(game, si);

Subscribers

People subscribed via source and target branches

to status/vote changes: