let the bot borrow the player's deck to split the model question

the account ids check out end to end: the player's avatar carries the
profile account, the bot carries 0-0, LogicBattle::account_ids takes
both from the avatars, and the client's getAccountIndex therefore finds
the player at index 0 and makes them the bottom avatar. so
isOwnedByBottomPlayer is right, and it is right in a way that matters:
the player's units take the blue export names in Character::Character
and the bot's take the red ones. red draws, blue does not.

that leaves two candidates - an empty blue prefix on the row, or a data
reference pointing at the wrong row whose blue prefix happens to be
empty - and one run tells them apart. SCROLL_BOT_MIRRORS_DECK=1 hands
the bot the player's cards; if its knight draws and ours does not, the
rows are fine and the blue branch is the fault.
This commit is contained in:
WiseDev 2026-08-23 15:28:52 +03:00
parent 81d6fe3922
commit 73de62794a

View file

@ -64,7 +64,16 @@ impl BotPlayer {
avatar.name_change_state = -1; avatar.name_change_state = -1;
Self { avatar, deck } Self { avatar, deck }
} }
pub fn mirrors_deck() -> bool {
std::env::var("SCROLL_BOT_MIRRORS_DECK")
.map(|value| value == "1")
.unwrap_or(false)
}
pub fn against(player: &LogicClientAvatar, fallback: &LogicSpellDeck) -> Self { pub fn against(player: &LogicClientAvatar, fallback: &LogicSpellDeck) -> Self {
if Self::mirrors_deck() {
tracing::info!("the bot is playing the player's deck for this battle");
return Self::matching(player.arena.clone(), player.score, fallback.clone());
}
let deck = predefined_deck() let deck = predefined_deck()
.filter(|deck| deck.filled_slot_count() == DECK_SLOT_COUNT) .filter(|deck| deck.filled_slot_count() == DECK_SLOT_COUNT)
.unwrap_or_else(|| fallback.clone()); .unwrap_or_else(|| fallback.clone());