Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Ships yield when passing through one another #8574

Closed
wants to merge 1 commit into from

Conversation

@2TallTyler
Copy link
Member

@2TallTyler 2TallTyler commented Jan 14, 2021

Motivation / Problem

Because ships have no collisions, they have infinite capacity with minimal infrastructure. This does not match the rest of the game, where designing and upgrading infrastructure is a large part of the gameplay.

Description

Various ideas have been floated to solve this, but most have to do with pathfinding. JGR’s patchpack includes such a patch, but it’s possible to create gridlock in tight areas.

This PR takes a more permissive approach, allowing ships to clip through each other, but only allowing one ship on each tile to move while stopping the rest. Railroad Tycoon 3 used this to allow trains to pass on single track or overtake slower trains (thanks to andythenorth for suggesting this).

In this implementation, the priority goes to the fastest ship, with a primary tiebreaker of the ship carrying the most cargo and a fallback of the ship index. I chose speed because it allows fast ships to overtake slow ships traveling in the same direction, and because speed is a reasonably accurate surrogate for priority. I initially tried prioritizing cargo for ships traveling in opposite directions, but it allowed a feedback loop in locks where three ships would take turns moving one tick at a time.

With this change, players are not required to change their gameplay, however with moderate to heavy traffic, docks, locks, and single-tile bidirectional canals become clogged and inefficient. This gives players an incentive to build multiple docks in busy harbors, construct two-tile canals and docks, and use buoys to route ships in multiple sea lanes. This is more in line with gameplay for trains, road vehicles, and aircraft (and is also fun, I think!).

There is an additional visual improvement, since ships traveling in the same direction are often unbunched by disruptions in harbors and locks, and even when traveling a single tile apart, don’t clip nearly as much.

I have created a savegame which demonstrates how this change affects old designs, and how they can be fixed with more interesting and realistic infrastructure: ShipDemo.zip

This feature is controlled by a setting, so players can choose to disable it.

Limitations

When many ships overlap, there has always been some flickering of the sprites. This seems to be slightly increased in this PR, mostly at docks which many ships are trying to reach at once. I suspect it’s because the ship sprite is being marked dirty each time it is stopped.

Checklist for review

Some things are not automated, and forgotten often. This list is a reminder for the reviewers.

  • The bug fix is important enough to be backported? (label: 'backport requested')
  • This PR affects the save game format? (label 'savegame upgrade')
  • This PR affects the GS/AI API? (label 'needs review: Script API')
    • ai_changelog.hpp, gs_changelog.hpp need updating.
    • The compatibility wrappers (compat_*.nut) need updating.
  • This PR affects the NewGRF API? (label 'needs review: NewGRF')
@2TallTyler 2TallTyler force-pushed the 2TallTyler:boat_phasing branch from 066f93b to 8004c36 Jan 15, 2021
@2TallTyler 2TallTyler changed the title Feature: Ships stop to be passed by another ship Feature: Ships yield when passing through one another Jan 15, 2021
@DorpsGek DorpsGek temporarily deployed to preview-pr-8574 Jan 15, 2021 Inactive
@ldpl
Copy link
Contributor

@ldpl ldpl commented Jan 15, 2021

Noclip is like the only advantage ships have, removing it will make them completely useless :p
But most importantly, ships have no avoidance mechanism so they keep bumping into each other needlessly even in the open sea which can't be good for a player's mental health ;)
Also, there seems to be some bug with ships being unable to leave depot if there is another ship stopped there.

@2TallTyler
Copy link
Member Author

@2TallTyler 2TallTyler commented Jan 15, 2021

Also, there seems to be some bug with ships being unable to leave depot if there is another ship stopped there.

This is actually a bug in the base game, which I can reproduce in 1.10.3. See #8578 for a fix.

@LC-Zorg
Copy link

@LC-Zorg LC-Zorg commented Jan 15, 2021

This is a change that can break previous games - adapting ship routes to new conditions may be impossible or extremely time-consuming, so the player may lose the ability to play older saves on the newer versions.

In general, I am in favor of changes in the subject of ships, but I am not convinced if this form will be appropriate. If ships slow down by penetrating through each other, this would be at least acceptable (for players) - it will affect older games but won't break them. In new games, it will encourage you to build wider channels where there is more traffic, which is also not bad. However, if ships were to lock up, this is wrong.

What I think you should also pay attention to is the load generated by the ship's pathfinder. From my observations now pathfinder updates the routes of all ships at the same time, every 7 days. With a small number of ships and short distances between the buoys, it doesn't matter. But when there are a lot of ships and the distance between the buoys is considerable, the game starts cutting very clearly. The problem here, I believe, is that the computation is performed for all ships at the same time.
>Here< I have included tests showing the problem

Multiple docks ports - I would prefer an option that would explicitly allow only one ship to be moored at one quay.

Buoys - Their biggest drawback is that they simply litter the waters, especially their labels. In addition, their use can be cumbersome - it is easy to overlook one which can cause problems. I would be in favor of a direction of changes that would restrict the placement of buoys as much as possible, and not encourage the player to use them even more often.

Some time ago on the tt-forum I posted a proposal to create invisible buoys (Shipping Lanes), which, placed one after the other by pathfinder, could solve several problems at once. Without going into details:

  • Significant pathfinder relief - would not have to update ship routes as long as the ship is moving away from the destination port, the player will not change orders or the ship's route will not be blocked
  • No more blocking of ship routes - invisible buoys could only be removed / built up by the player using them
  • Ships in both directions would follow separate lanes - the rule would be to avoid the buoys on the right side if possible
  • Ships would still pass through each other (flaw / advantage) - it would still be possible to avoid this, but it would make it impossible to put the pathfinder to sleep during the voyage (I write as a theorist).
    More details on the forum >here<
    I don't insist that this is the best solution, I am just giving it for consideration.
@2TallTyler
Copy link
Member Author

@2TallTyler 2TallTyler commented Jan 16, 2021

I'm not aware of any way this can "lock up" ships, but I encourage anybody to try to create one using the deployment preview.

In the test savegame included in my PR, impact on ships out at sea was minimal, even with heavy traffic. The most noticeable change is at docks, locks, and canals. I agree that buoys are a clumsy method of control, but the clutter isn't bad if you turn off their labels in transparency settings.

A one-ship-per-dock restriction is out of scope of this PR, but there are significant problems with this because ships cannot be controlled as tightly as trains or road vehicles with one-way roads or signals, depot overflows, etc.

Pathfinder changes have been proposed and tried, but I talked with JGR recently and he said his implementation produced too many lockups to be suitable for trunk. This PR is an alternative proposal which does not preclude future changes.

@2TallTyler 2TallTyler force-pushed the 2TallTyler:boat_phasing branch from 8004c36 to da5953b Mar 26, 2021
@DorpsGek DorpsGek temporarily deployed to preview-pr-8574 Mar 26, 2021 Inactive
@2TallTyler
Copy link
Member Author

@2TallTyler 2TallTyler commented Mar 26, 2021

I added a setting to allow users to toggle this setting. Maybe that makes this feature more palatable, since it won't be forced on anybody. I'm open to suggestions about the setting's location and category level (currently it's Advanced and in Vehicles > Routing), but I do think it should be on by default.

(Also, yes, my renewed interest in this PR was sparked by recent events...)

@JGRennison
Copy link
Contributor

@JGRennison JGRennison commented Mar 26, 2021

Pathfinder changes have been proposed and tried, but I talked with JGR recently and he said his implementation produced too many lockups to be suitable for trunk. This PR is an alternative proposal which does not preclude future changes.

Incidentally this turned out to be an implementation bug. With that fixed there don't appear to be any problems with it.

@LC-Zorg
Copy link

@LC-Zorg LC-Zorg commented Mar 29, 2021

The "Ship avoid collisions" function that is available in the JGR version can be cumbersome. This one is - sorry - but even worse. Of the two bad things, I would prefer JGR's solution. At least on a straight way, they don't flow on each other.

@2TallTyler 2TallTyler force-pushed the 2TallTyler:boat_phasing branch from da5953b to 0cd33a5 Apr 8, 2021
@DorpsGek DorpsGek temporarily deployed to preview-pr-8574 Apr 8, 2021 Inactive
@2TallTyler 2TallTyler marked this pull request as draft Apr 8, 2021
@2TallTyler
Copy link
Member Author

@2TallTyler 2TallTyler commented Apr 8, 2021

Bumping this back to draft status because I failed to check aqueducts properly. Ships pile up thinking they're on the same tile, since aqueducts are wormholes. I will need to fix this before it is ready for review.

I also hope to do some pathfinder improvements for collision avoidance which would make this ship nerf more palatable.

@2TallTyler 2TallTyler force-pushed the 2TallTyler:boat_phasing branch from 0cd33a5 to a17f104 Apr 8, 2021
@LC-Zorg
Copy link

@LC-Zorg LC-Zorg commented Apr 11, 2021

2TallTyler: Bumping this back to draft status because I failed to check aqueducts properly. Ships pile up thinking they're on the same tile, since aqueducts are wormholes. I will need to fix this before it is ready for review.

There is also another problem when a group of ships is withdrawn to the depot - it takes a long time to get in and stop.

  • send 20 or more ships to some buoy
  • retreat all ships to the depot

2TallTyler: I also hope to do some pathfinder improvements for collision avoidance which would make this ship nerf more palatable.

The nice thing in JGRPP is that a ship that is faster can't overtake a slower one when no enought space for this and follows it. This is a good solution, because why should a large container ship stop for a small, fast boat? Ships also always travel at a distance from each other.

There is, however, a significant error in the way of passing ships: ships always turn left when passing each other, i.e. the traffic is left-hand. The problem is that all over the world, including England, there is always right-hand traffic, so ships should turn right when passing each other. It can usually be overtaken from either side.

In general this passing mechanism is very cumbersome on narrow routes (2 tiles).

Something that can help to avoid a collision without a direction change mechanism is the principle of passing the buoy on the right if possible (even if it is not written in the orders) - it would be a very beneficial change even after turning off this function. Sufficient for straight trails, but a problem on winding rivers still appear. Putting a lot of buoys and adding them all to the orders would be very entertaining, tiring over time and cluttering the game with a lot of buoy labels. :(

I have three ideas (probably not going to be easy):
1. Buoys-objects - a special type of buoy, which is not added to orders, but ships also try to pass them on the right - for the player, placing such objects in problematic places would be very easy.
2. Invisible buoys - (I know, I repeat myself, but I think it may be a good solution) they would be placed by a pathfinder one by one between the designated points of the route. Here, ships have always traveled on separate tracks, if track width permits. A great advantage of this solution would be a significant reduction in calculations for determining the path for ships. The second, equally great advantage would be to prevent malicious or inattentive players from interrupting the waterways.
3. Water routes - something that can be seen on the real maps. In the game, they would be a clue for the pathfinder. If available and close to the route, ships would go along these lines (construction like rails). The ships would also move on the right side of the line, or if that was not possible on the line. Again, it would be impossible for a malicious player to break the trail. Perhaps the burden on pathfinder could also be reduced.

I also think that this PR would be more friendly and less annoying for players if the ships, instead of stopping, would slow down (both when sailing in opposite directions), for example to 50-70% of their speed - a player would still see that it is worth building wider routes, reducing speed would also be logical. Perhaps instead of On/Off, you could add a setting for ships to slow down when passing 0-100%?

Another important thing related to this PR are also the costs of building canals, locks and viaducts. Currently they are very expensive and if a player is to be persuaded with this PR to build wider channels, these should be correspondingly cheaper. Of course, only after enabling this option.

@2TallTyler
Copy link
Member Author

@2TallTyler 2TallTyler commented Apr 19, 2021

Ship collision avoidance in JGRPP can be tuned to favor passing on the right. I think this pathfinding improvement will be needed to make this PR palatable to players, so I will close it (keeping the code in my branch) to avoid cluttering the PR list with unfinished drafts.

@2TallTyler 2TallTyler closed this Apr 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants