Bouncing units and alliance break

What would you like to see in Freeciv? Do you have a good idea what should be improved or how?
Post Reply
Wahazar
Elite
Posts: 362
Joined: Mon Jul 02, 2018 1:49 pm

Bouncing units and alliance break

Post by Wahazar »

I'm trying to understand, how stack conflicts are resolved in case of unit being transported on allied ships, while alliance was broken.
There are two functions (freeciv 2.6) in server/unittools.c: throw_units_from_illegal_cities and resolve_stack_conflicts.
First function is using unit_transport_unload_send to handle units on transports, while second units is using bounce_unit function,
which move unit at no movement points cost.

If second function is called for units outside cities, there are at least 3 exploits possible:
1. teleport unit from land tile to adjacent land tile at no mp cost
2. unload any unit from transport at no mp cost - this unit can attack instantly, in same turn
3. unload unit, which is not provided for unloading (no disembark flag for unreachable transport).

Is it possible to fix above exploits by:
a) changing unit_move(punit, ptile, 0, NULL) to unit_move(punit, ptile, punit->moves_left, NULL)
b) adding iteration of unit unloading inresolve_stack_conflicts, similar to throw_units_from_illegal_cities?
Augmented2 ruleset/modpack for freeciv2.6: http://forum.freeciv.org/f/viewtopic.php?f=11&t=91047
Wahazar
Elite
Posts: 362
Joined: Mon Jul 02, 2018 1:49 pm

Re: Bouncing units and alliance break

Post by Wahazar »

Correction to above fix: deducting all mp is too harsh and also doesn't resolve all issues (bounce exploit can be still used to move units with 0 moves left).
1 mp should be used, if unit have some mp left, if there is no moves left, unit is killed - bad luck.

So instead of

Code: Select all

unit_move(punit, ptile, 0, NULL);
should be

Code: Select all

unit_move(punit, ptile, 1, NULL);
and additional check of punit->moves_left>0 before square_iterate
Augmented2 ruleset/modpack for freeciv2.6: http://forum.freeciv.org/f/viewtopic.php?f=11&t=91047
Ignatus
Elite
Posts: 644
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: Bouncing units and alliance break

Post by Ignatus »

I have once made a workaround for slowing invasions, and also to not reset UWT:Ihnatus/LT2_6 branch.

Maybe bouncing is not a good solution at all - just let's leave wrong stacks as they are, just block the units from any action except leaving their position for a right one.
Wahazar
Elite
Posts: 362
Joined: Mon Jul 02, 2018 1:49 pm

Re: Bouncing units and alliance break

Post by Wahazar »

Ignatus wrote: Maybe bouncing is not a good solution at all - just let's leave wrong stacks as they are, just block the units from any action except leaving their position for a right one.
It would be optimal, but I'm not sure if some assertions will strike back?
Augmented2 ruleset/modpack for freeciv2.6: http://forum.freeciv.org/f/viewtopic.php?f=11&t=91047
Wahazar
Elite
Posts: 362
Joined: Mon Jul 02, 2018 1:49 pm

Re: Bouncing units and alliance break

Post by Wahazar »

After some discussion on discord, conclusion is that disbanding all units from conflicting stack is the most elegant and simple method of handling such problem, because:
  • teleporting units to nearest city/capital creates another exploit
  • leaving stack as is - you can't break alliance with bad guy effectively, he may still sit inside your stack
  • fixing existing bounce function is over-complicated and doesn't solve problem of back-stabbing - bad guy who breaks alliance can arrange situation when your units will be disbanded anyway
  • hijacking transport is also bad idea - create exploit of units transfer
Thus my proposal of handling on-field stack with mixed nationality is:
  • disband all conflicting players units standing on enemy land
  • disband all conflicting enemy units standing on player's land
  • disband all conflicting units on transports
  • disband units one-by-one until stack on neutral land is coherent.
Above consideration is valid for resolving on-field conflicting stacks function in unittools.c: resolve_stack_conflicts.
City conflicting units are resolved differently with use of throw_units_from_illegal_cities() and it can stay as is, because is not as abusive as resolve_stack_conflicts.
Augmented2 ruleset/modpack for freeciv2.6: http://forum.freeciv.org/f/viewtopic.php?f=11&t=91047
ilkkachu
Posts: 5
Joined: Tue Jul 07, 2020 11:38 am

Re: Bouncing units and alliance break

Post by ilkkachu »

Ignatus wrote:I have once made a workaround for slowing invasions, and also to not reset UWT:
Do I get it right that the idea of not counting bounce as a move for UWT is so that you can't move at end of turn, and then arrange a bounce just after TC to reset the timer and be able to immediately move again?

That seems to leave the opposite problem, that if you disembark via a bounce at end of turn, you can move immediately after TC since the landing didn't update UWT. Of course the transport would need to stay in place for the UWT duration before TC, but if the enemy only has land forces and can't touch the transport, then it could be exploited.

I would try to avoid disbanding units if possible, to avoid any surprising sharp edges that especially new players can trip on. But things like this make me think that any bounce moves really should follow all the rules regular moves do, i.e. not moving if UWT doesn't allow it, not moving if you don't have enough MP left, not disembarking if it's not allowed, using at least as many MP as the move would regularly require, and updating UWT after it's done. Plus whatever I forgot. Failing those, disbanding seems the only option to avoid potentially exploitable holes. Is there any single function that could be used here to check all that and tell if the move would be possible?

And sure, it's impossible to prevent all backstabbing opportunities when breaking an alliance. Just move troops to position past any defenders, avoiding mixed stacks; or if you hold foreign troops in a transport, move the ship to open waters and let the guys fall in the sea when the alliance breaks. But right now, the code also dumps all transported units overboard even if it could resolve the situation by just moving the transport, and that seems a bit too harsh, esp. since there's no warning.
Ignatus wrote:Maybe bouncing is not a good solution at all - just let's leave wrong stacks as they are, just block the units from any action except leaving their position for a right one.
That would bring a lot of questions. If A and B have units in a mixed stack after their alliance breaks, can they bring new units in the tile? What happens if C is still allied with A and wants to bring units in? Do they get to enter, just get blocked, or attack just B's units? What if C is still allied with A _and_ B, ...? What about D in war with A but at peace with B, and so on...
Post Reply