Skip to content

fixed emergency protocol by removing sheduled wares requested before ... - #1961

Open
tost11 wants to merge 9 commits into
Return-To-The-Roots:masterfrom
tost11:feature/fix-emergency-protocol
Open

fixed emergency protocol by removing sheduled wares requested before ...#1961
tost11 wants to merge 9 commits into
Return-To-The-Roots:masterfrom
tost11:feature/fix-emergency-protocol

Conversation

@tost11

@tost11 tost11 commented Jul 16, 2026

Copy link
Copy Markdown

When emergency protocol is activated and many buildings are already planned, the wares already scheduled for delivery are ignoring the protocol.

So now when emergency protocol is activated, those wares get removed (if not for the sawmill or woodcutter).

This also solved the issue for AI enemies on very low resources where they're not able to start because the first sawmill never got built.

Comment thread libs/s25main/GamePlayer.cpp Outdated
Comment thread libs/s25main/GamePlayer.h Outdated
Comment thread libs/s25main/GamePlayer.cpp Outdated
Comment thread libs/s25main/GamePlayer.h Outdated
Comment thread libs/s25main/GamePlayer.cpp Outdated
Comment thread libs/s25main/GamePlayer.cpp Outdated

@Flamefire Flamefire left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM,
trivial style issue in the NULL check which I fixed directly. git pull if you need to do further changes

@Flamefire
Flamefire enabled auto-merge July 17, 2026 10:29

@Flamefire Flamefire left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to run clang-format first. If you have it installed when configuring you can run e.g. make clangFormat
Or use the diff as shown in the CI job.

Can you add a test for that? Might be a bit tricky though

auto-merge was automatically disabled July 17, 2026 22:53

Head branch was pushed to by a user without write access

@tost11
tost11 force-pushed the feature/fix-emergency-protocol branch from bc104e8 to 689112e Compare July 17, 2026 23:02
Flamefire
Flamefire previously approved these changes Jul 18, 2026
@Spikeone

Spikeone commented Jul 19, 2026

Copy link
Copy Markdown
Member

Well, this is original behavior - you were also able to store out wares to get them going anway (a tactic used with very low goods frequently). This fix breaks this original behavior, doesn't it?

This sounds reading your description more like a problem the AI has, and should be fixed for the AI instead of for players (maybe the AI can use that system which is slight cheating but I'd opt for a smarter AI instead of an AI playing only by rules)

@Flamefire

Copy link
Copy Markdown
Member

Well, this is original behavior - you were also able to store out wares to get them going anway (a tactic used with very low goods frequently). This fix breaks this original behavior, doesn't it?

What we have:

  • When emergency program is active newly built buildings don't get wares except woodcutter or sawmills
  • With this: Additionally wares ordered for such "blocked" buildings which are still in a warehouse, i.e. not carried out yet, are stopped, wares already on the way are not.

Not fully sure how the original handled that as it seems like a minor corner case happening rarely.
If in the original wares for other buildings are still carried out, then I'd also say that we guard this behavior for AI only. If it helps then I don't see an issue there as it is such a minimal QoL change for rare cases that it likely won't even be noticed in most cases.

@tost11

tost11 commented Jul 28, 2026

Copy link
Copy Markdown
Author

The issue can also occur for the player, like On low resources, start when starting with multiple buildings (but the sawmill first, but on hilly terrain) and then multiple other buildings (fast before all boards are given out). Then all boards are scheduled for building. The sawmill and woodcutter are already planed. Then some time later the Terain Blow sawmill is leveled, and it requests boards. But all boards are already given out to other buildings. That results in no boards for the sawmill.

But yes, it is an edge case, and yes, I mainly built it for the AI to start proper play on some maps where it gets stuck on low-resource starts.

But actually it's an issue in the game, not only an AI issue.

So what now? I see multiple options that could be implemented to not block fast start for players.

  • Fix it only on AI, but behavior stays broken on edge cases.
  • Check what the behavior was in the original game.
  • Improve emergency protocol with:

-- Only hold back needed boards (2 for the sawmill and 2 for the woodcutter) depending on what buildings are missing. Also maybe 1 more if the street gets removed and one is lost by the player or AI.
-- Unlock emergency protocol if the boards reach the building, not when finished (but on the other hand, without those building boards, production isn't possible anyway).
-- Map boards to exactly one needed building; for example, if two woodcutters build a target, one gets the boards. so other boards can be normally used.

What do you prefer?

For me it would be the last option, and I also would implement that more complicated but better emergency program behavior if wanted.

@Flamefire

Copy link
Copy Markdown
Member

But yes, it is an edge case, and yes, I mainly built it for the AI to start proper play on some maps where it gets stuck on low-resource starts.

But actually it's an issue in the game, not only an AI issue.

That depends on the definition of "issue". We want (at least the default) behavior to match that of S2, so if "emergency mode" there meant that only newly built buildings do not get boards/stones then that is (usually) what we want.
AI may "cheat" and that's fine as a player could invoke this behavior by removing roads, so that's a shortcut.

So what now? I see multiple options that could be implemented to not block fast start for players.

* Fix it only on AI, but behavior stays broken on edge cases.

No issue with that in any case

* Check what the behavior was in the original game.

See above: That would be the most important thing to check first although it may be difficult to get into exactly this situation. But it looks like your description above should be reasonably easy to check. Could you do that?

* Improve emergency protocol with:

I think that is too complicated to avoid such a rare issue. In the end this is a resource management game and the emergency mode already a QoL improvement only. So it could be "incomplete" leaving more responsibility to the player.

However as queued wares do not turn up for the player anywhere in the UI it might seem like emergency mode is ignored for a short time. I didn't fully understand @Spikeone

Well, this is original behavior - you were also able to store out wares to get them going anway (a tactic used with very low goods frequently). This fix breaks this original behavior, doesn't it?

What exactly does this break? You build a building, wares for this building are queued, emergency mode activates, wares for building stop being carried out as-if the building was built/connected right after the activation.
If you can "force" delivering wares in emergency mode by out-storing then this isn't blocked by this change. Not sure if it was possible in RttR before, but if it was it still will be.

So I'd lean into accepting this change to enforce the visible semantics: When emergency mode is active no ware will leave the WHs (with the purpose) of going to a "disallowed" building site.
Or what do you thing @Spikeone ?

@tost11

tost11 commented Aug 2, 2026

Copy link
Copy Markdown
Author

I have tested the behavior in the Siedler 2 Gold Edition.

It seems to be the cleverest approach. Boards are stored until only 4 are left. If a woodcutter builds it, it gets two boards. Another one would not receive any boards (like it's currently here); only the sawmill gets them (see screenshots).

When both buildings are finished, the protocol is deactivated.

I have also checked the emergency protocol for stones; if you run out of stones, you are doomed—no emergency protocol for it.

image_1 image_2

@Flamefire Flamefire left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified with the original too in various situations and you are right: They are immediately stopped in warehouses.

We do have a difference though: S2 activates at 4 boards, RTTR at 10.

Anyway, some minor polishing here and it's good to go

for(auto it = ware_list.begin(); it != ware_list.end();)
{
Ware* ware = *it;
// checks if this ware is

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incomplete comment?

Comment thread libs/s25main/GamePlayer.h
const Statistic& GetStatistic(StatisticTime time) const { return statistic[time]; };
unsigned GetStatisticCurrentValue(StatisticType idx) const { return statisticCurrentData[idx]; }

// remove all wares that are already scheduled but ignoring emergency protocol

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what "ignoring ..." means here. Maybe:

Suggested change
// remove all wares that are already scheduled but ignoring emergency protocol
// Stop wares restricted in emergency mode that are waiting in warehouse to be transported already


BOOST_FIXTURE_TEST_CASE(EmergencyProtoclActiveWoodcutterAndSawmillCanBuild, EmergencyFixture)
{
initGameRNG();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to fixture


struct EmergencyFixture : public WorldFixture<CreateEmptyWorld, 1>
{
nobHQ* HQ = world.GetPlayer(0).GetHQ();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
nobHQ* HQ = world.GetPlayer(0).GetHQ();
nobHQ* hq = world.GetPlayer(0).GetHQ();


pos = world.GetPlayer(0).GetHQPos() + MapPoint(3, 0);
world.SetBuildingSite(BuildingType::Farm, pos, 0);
world.BuildRoad(0, false, world.GetNeighbour(pos, Direction::SouthEast),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe derive from WorldWithGCExecution and use BuildRoadForBlds which checks the the roads are built. Especially in the tests it is otherwise not fully clear that the building site is actually connected. Here it is reasonably clear, but for GetHQPos() + MapPoint(-1, 2) it is a bit trickier

RTTR_EXEC_TILL(500, HQ->GetInventory()[GoodType::Boards] == 10);

// activate program (with 10 boards it should trigger)
world.GetPlayer(0).TestForEmergencyProgramm();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we test that this is done automatically? I.e. shouldn't the above activate it? Or at least in the next GF

Comment on lines +45 to +48
// wait for some more ticks to give time if not working to deliver more boards
RTTR_SKIP_GFS(200);
// check boards are still fine and protocol working
BOOST_TEST_CHECK(world.GetPlayer(0).GetHQ()->GetInventory()[GoodType::Boards] == 10);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// wait for some more ticks to give time if not working to deliver more boards
RTTR_SKIP_GFS(200);
// check boards are still fine and protocol working
BOOST_TEST_CHECK(world.GetPlayer(0).GetHQ()->GetInventory()[GoodType::Boards] == 10);
// No more boards are carried out to the farms due to emergency protocol
RTTR_SKIP_GFS(200);
BOOST_TEST_CHECK(hq->GetInventory()[GoodType::Boards] == 10);

}
};

BOOST_FIXTURE_TEST_CASE(EmergencyProtoclActiveWoodcutterAndSawmillCanBuild, EmergencyFixture)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo here and below

Suggested change
BOOST_FIXTURE_TEST_CASE(EmergencyProtoclActiveWoodcutterAndSawmillCanBuild, EmergencyFixture)
BOOST_FIXTURE_TEST_CASE(EmergencyProtocolActiveWoodcutterAndSawmillCanBuild, EmergencyFixture)

// check if inventory boards are given out
RTTR_EXEC_TILL(200, HQ->GetInventory()[GoodType::Boards] < 10);

// check if building where found

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// check if building where found
// check that buildings are built

Comment on lines +83 to +86
// wait for some more ticks to give time if not working to deliver more boards
RTTR_SKIP_GFS(500);
// check boards are still fine and protocol working
BOOST_TEST_CHECK(world.GetPlayer(0).GetHQ()->GetInventory()[GoodType::Boards] == 10);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// wait for some more ticks to give time if not working to deliver more boards
RTTR_SKIP_GFS(500);
// check boards are still fine and protocol working
BOOST_TEST_CHECK(world.GetPlayer(0).GetHQ()->GetInventory()[GoodType::Boards] == 10);
// No boards are carried out to the farms or watchtower due to emergency protocol
RTTR_SKIP_GFS(500);
BOOST_TEST_CHECK(hq->GetInventory()[GoodType::Boards] == 10);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants