diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-12-18 22:49:15 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-12-18 22:49:18 +0100 |
| commit | cf3d5d44166e7214700b73d657aa10018167ae0c (patch) | |
| tree | 9b74ed9e719b44bc8f8d312cdf4bb83651b20983 | |
| parent | 6832af5ee35b9d16668e1d34f191715f3755679f (diff) | |
| download | hurrycurry-cf3d5d44166e7214700b73d657aa10018167ae0c.tar hurrycurry-cf3d5d44166e7214700b73d657aa10018167ae0c.tar.bz2 hurrycurry-cf3d5d44166e7214700b73d657aa10018167ae0c.tar.zst | |
only send movement packets if changes; bots send less inputs
| -rw-r--r-- | server/bot/src/algos/customer.rs | 60 | ||||
| -rw-r--r-- | server/bot/src/pathfinding.rs | 69 | ||||
| -rw-r--r-- | server/bot/src/step.rs | 10 | ||||
| -rw-r--r-- | server/src/entity/player_portal.rs | 5 | ||||
| -rw-r--r-- | server/src/entity/player_portal_pair.rs | 6 | ||||
| -rw-r--r-- | server/src/server.rs | 24 |
6 files changed, 106 insertions, 68 deletions
diff --git a/server/bot/src/algos/customer.rs b/server/bot/src/algos/customer.rs index fe665f47..ebc6e64a 100644 --- a/server/bot/src/algos/customer.rs +++ b/server/bot/src/algos/customer.rs @@ -17,7 +17,7 @@ */ use crate::{ BotAlgo, PacketSink, - pathfinding::{Path, find_path}, + pathfinding::{HoldLocation, Path, find_path}, random_float, }; use hurrycurry_game_core::Game; @@ -50,19 +50,19 @@ enum CustomerState { ticks: usize, }, Waiting { + hold_location: HoldLocation, demand: DemandIndex, chair: IVec2, - facing: Vec2, timeout: f32, origin: IVec2, check: u8, pinned: bool, }, Eating { + hold_location: HoldLocation, demand: DemandIndex, table: IVec2, progress: f32, - chair: IVec2, origin: IVec2, }, Finishing { @@ -148,10 +148,10 @@ impl CustomerState { chair: *chair, timeout, demand, - facing, origin: *origin, check: 0, pinned: false, + hold_location: HoldLocation::new(chair.as_vec2(), facing), }; let message_item = if !game.data.flags.disable_unknown_orders { game.data @@ -182,22 +182,17 @@ impl CustomerState { } else { #[cfg(feature = "debug_events")] out.push(PacketS::Debug(path.debug(me))); - out.push(PacketS::Movement { - player: me, - dir: path.next_direction(pos, dt) * 0.6, - boost: false, - pos: None, - }); + path.update(out, me, pos, dt, 0.6, false); } } CustomerState::Waiting { + hold_location, chair, demand, timeout, origin, check, pinned, - facing, } => { *timeout -= dt; *check += 1; @@ -271,7 +266,7 @@ impl CustomerState { None } }); - if let Some(pos) = demand_pos { + if let Some(table) = demand_pos { debug!("{me:?} -> eating"); let points = game.data.demands[demand.0].points; out.push(PacketS::Communicate { @@ -291,7 +286,7 @@ impl CustomerState { player: me, }); out.push(PacketS::Interact { - target: Some(ItemLocation::Tile(pos)), + target: Some(ItemLocation::Tile(table)), player: me, hand: Hand(0), }); @@ -306,28 +301,26 @@ impl CustomerState { hand: Hand(0), }); *self = CustomerState::Eating { + hold_location: HoldLocation::new( + chair.as_vec2(), + (table - *chair).as_vec2(), + ), demand: *demand, - table: pos, + table, progress: 0., - chair: *chair, origin: *origin, }; return; } } - out.push(PacketS::Movement { - player: me, - dir: dir_input(pos, *chair, *facing), - boost: false, - pos: None, - }); + hold_location.update(out, me, pos); } CustomerState::Eating { + hold_location, demand, table, progress, - chair, origin, } => { let demand = &game.data.demands[demand.0]; @@ -346,12 +339,7 @@ impl CustomerState { }); return; } - out.push(PacketS::Movement { - player: me, - dir: dir_input(pos, *chair, (*table - *chair).as_vec2()), - boost: false, - pos: None, - }); + hold_location.update(out, me, pos); } CustomerState::Finishing { table, @@ -398,24 +386,10 @@ impl CustomerState { } else { #[cfg(feature = "debug_events")] out.push(PacketS::Debug(path.debug(me))); - out.push(PacketS::Movement { - player: me, - dir: path.next_direction(pos, dt) * 0.6, - boost: false, - pos: None, - }); + path.update(out, me, pos, dt, 0.6, false); } } CustomerState::Exited => (), } } } - -fn dir_input(pos: Vec2, target: IVec2, facing: Vec2) -> Vec2 { - let diff = (target.as_vec2() + 0.5) - pos; - (if diff.length() > 0.3 { - diff.normalize() - } else { - diff * 0.5 - }) + facing.clamp_length_max(1.) * 0.3 -} diff --git a/server/bot/src/pathfinding.rs b/server/bot/src/pathfinding.rs index 4aa7c2ff..f9f213fa 100644 --- a/server/bot/src/pathfinding.rs +++ b/server/bot/src/pathfinding.rs @@ -15,10 +15,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ +use crate::PacketSink; use hurrycurry_game_core::Game; -use hurrycurry_protocol::glam::{IVec2, Vec2}; #[cfg(feature = "debug_events")] -use hurrycurry_protocol::{DebugEvent, DebugEventDisplay, PlayerID}; +use hurrycurry_protocol::{DebugEvent, DebugEventDisplay}; +use hurrycurry_protocol::{ + PacketS, PlayerID, + glam::{IVec2, Vec2}, +}; use log::{debug, trace}; use std::{ cmp::Ordering, @@ -30,13 +34,39 @@ use std::{ pub struct Path { segments: Vec<Vec2>, seg_time: f32, + last_dir: Vec2, + last_boost: bool, } impl Path { pub const EMPTY: Path = Path { seg_time: 0., segments: Vec::new(), + last_boost: false, + last_dir: Vec2::ZERO, }; + pub fn update( + &mut self, + out: &mut PacketSink, + player: PlayerID, + position: Vec2, + dt: f32, + speed: f32, + allow_boost: bool, + ) { + let dir = speed * self.next_direction(position, dt); + let boost = allow_boost && self.is_stuck(0.5); + if dir.distance(self.last_dir) > 0.1 || boost != self.last_boost { + self.last_dir = dir; + self.last_boost = boost; + out.push(PacketS::Movement { + player, + dir, + boost, + pos: None, + }); + } + } pub fn next_direction(&mut self, position: Vec2, dt: f32) -> Vec2 { if let Some(next) = self.segments.last().copied() { trace!("next {next}"); @@ -171,5 +201,40 @@ pub fn find_path(game: &Game, from: IVec2, to: IVec2) -> Option<Path> { Some(Path { segments, seg_time: 0., + last_boost: false, + last_dir: Vec2::ZERO, }) } + +#[derive(Debug, Clone)] +pub struct HoldLocation { + target: Vec2, + facing: Vec2, + last_dir: Vec2, +} +impl HoldLocation { + pub fn new(target: Vec2, facing: Vec2) -> Self { + Self { + facing, + target, + last_dir: Vec2::ZERO, + } + } + pub fn update(&mut self, out: &mut PacketSink, player: PlayerID, pos: Vec2) { + let diff = (self.target + 0.5) - pos; + let dir = match diff.length() { + x if x < 0.3 => self.facing.clamp_length_max(1.) * 0.4, // TODO rotation not updating + x if x < 1.0 => diff.normalize() * 0.6, + _ => diff.normalize(), + }; + if dir.distance(self.last_dir) > 0.1 { + self.last_dir = dir; + out.push(PacketS::Movement { + player, + dir, + boost: false, + pos: None, + }); + } + } +} diff --git a/server/bot/src/step.rs b/server/bot/src/step.rs index 6031439f..75e5d427 100644 --- a/server/bot/src/step.rs +++ b/server/bot/src/step.rs @@ -144,17 +144,9 @@ impl StepState { .map(|p| p.movement.position) .unwrap_or_default(); - let dir = self.path.next_direction(position, dt); - #[cfg(feature = "debug_events")] out.push(PacketS::Debug(self.path.debug(self.me))); - - out.push(PacketS::Movement { - player: self.me, - dir, - boost: self.path.is_stuck(0.5), - pos: None, - }); + self.path.update(out, self.me, position, dt, 1., true); } } } diff --git a/server/src/entity/player_portal.rs b/server/src/entity/player_portal.rs index a2653900..35733ca3 100644 --- a/server/src/entity/player_portal.rs +++ b/server/src/entity/player_portal.rs @@ -18,7 +18,7 @@ use super::{Entity, EntityContext}; use anyhow::Result; use hurrycurry_locale::TrError; -use hurrycurry_protocol::{PacketC, glam::Vec2}; +use hurrycurry_protocol::glam::Vec2; #[derive(Debug, Default, Clone)] pub struct PlayerPortal { @@ -40,8 +40,7 @@ impl Entity for PlayerPortal { .get_mut(&pid) .ok_or(TrError::Plain("Player is missing".to_string()))?; p.movement.position = self.to; - c.packet_out - .push_back(PacketC::MovementSync { player: pid }); + p.movement_must_sync = true; } Ok(()) diff --git a/server/src/entity/player_portal_pair.rs b/server/src/entity/player_portal_pair.rs index 9691ca05..fd28b774 100644 --- a/server/src/entity/player_portal_pair.rs +++ b/server/src/entity/player_portal_pair.rs @@ -19,7 +19,7 @@ use super::{Entity, EntityContext}; use anyhow::Result; use hurrycurry_locale::TrError; use hurrycurry_protocol::{ - PacketC, TileIndex, + TileIndex, glam::{IVec2, Vec2, vec2}, }; @@ -104,7 +104,7 @@ impl Entity for PlayerPortalPair { && let Some(p) = c.game.players.get_mut(&player) { p.movement.position = self.b_f; - c.packet_out.push_back(PacketC::MovementSync { player }); + p.movement_must_sync = true; } if self.state == -1 @@ -113,7 +113,7 @@ impl Entity for PlayerPortalPair { && let Some(p) = c.game.players.get_mut(&player) { p.movement.position = self.a_f; - c.packet_out.push_back(PacketC::MovementSync { player }); + p.movement_must_sync = true; } Ok(()) diff --git a/server/src/server.rs b/server/src/server.rs index b925a577..be5fee3f 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -528,7 +528,7 @@ impl Server { let diff = pos - pd.movement.position; pd.movement.position += diff.clamp_length_max(dt.as_secs_f32()); if diff.length() > 1. { - replies.push(PacketC::MovementSync { player }); + pd.movement_must_sync = true; } } } @@ -698,13 +698,21 @@ impl Server { }); for (&pid, player) in &mut self.game.players { - self.packet_out.push_back(PacketC::Movement { - player: pid, - pos: player.movement.position, - dir: player.movement.input_direction, - boost: player.movement.boosting, - rot: player.movement.rotation, - }); + if player.movement_input_changed || player.movement_must_sync { + player.movement_input_changed = false; + self.packet_out.push_back(PacketC::Movement { + player: pid, + pos: player.movement.position, + dir: player.movement.input_direction, + boost: player.movement.boosting, + rot: player.movement.rotation, + }); + if player.movement_must_sync { + player.movement_must_sync = false; + self.packet_out + .push_back(PacketC::MovementSync { player: pid }); + } + } } let mut players_auto_release = Vec::new(); |