aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-10-20 20:58:14 +0200
committermetamuffin <metamuffin@disroot.org>2025-10-21 00:18:11 +0200
commiteaed442578c3b1765ec48c84489a122096b6a08f (patch)
treebd5eeb82ea6f49691a4c5bad91a1b1614f0948a8
parenta3b0879a98bf5a0881b426913d7dd4cb9010e327 (diff)
downloadhurrycurry-eaed442578c3b1765ec48c84489a122096b6a08f.tar
hurrycurry-eaed442578c3b1765ec48c84489a122096b6a08f.tar.bz2
hurrycurry-eaed442578c3b1765ec48c84489a122096b6a08f.tar.zst
Send paths as debug events
-rw-r--r--server/bot/Cargo.toml1
-rw-r--r--server/bot/src/algos/customer.rs5
-rw-r--r--server/bot/src/pathfinding.rs26
-rw-r--r--server/bot/src/step.rs26
-rw-r--r--server/protocol/src/lib.rs13
-rw-r--r--test-client/main.ts8
-rw-r--r--test-client/protocol.ts10
-rw-r--r--test-client/visual.ts24
8 files changed, 95 insertions, 18 deletions
diff --git a/server/bot/Cargo.toml b/server/bot/Cargo.toml
index 8a841843..64b0f028 100644
--- a/server/bot/Cargo.toml
+++ b/server/bot/Cargo.toml
@@ -13,4 +13,5 @@ rustls = { version = "0.23.31", features = ["ring"] }
clap = { version = "4.5.47", features = ["derive"] }
[features]
+# default = ["debug_events"]
debug_events = []
diff --git a/server/bot/src/algos/customer.rs b/server/bot/src/algos/customer.rs
index 6ae67f69..fa10410b 100644
--- a/server/bot/src/algos/customer.rs
+++ b/server/bot/src/algos/customer.rs
@@ -180,6 +180,8 @@ impl CustomerState {
*self = CustomerState::Exiting { path };
}
} 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,
@@ -380,6 +382,7 @@ impl CustomerState {
hand: Hand(0),
});
}
+
out.push(PacketS::Movement {
player: me,
dir: (table.as_vec2() + 0.5) - pos,
@@ -393,6 +396,8 @@ impl CustomerState {
debug!("{me:?} -> leave");
*self = CustomerState::Exited
} 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,
diff --git a/server/bot/src/pathfinding.rs b/server/bot/src/pathfinding.rs
index ec098495..5c5551dd 100644
--- a/server/bot/src/pathfinding.rs
+++ b/server/bot/src/pathfinding.rs
@@ -16,7 +16,12 @@
*/
use hurrycurry_game_core::Game;
-use hurrycurry_protocol::glam::{IVec2, Vec2};
+#[cfg(feature = "debug_events")]
+use hurrycurry_protocol::{DebugEvent, PlayerID};
+use hurrycurry_protocol::{
+ DebugEventDisplay,
+ glam::{IVec2, Vec2},
+};
use log::{debug, trace};
use std::{
cmp::Ordering,
@@ -57,6 +62,25 @@ impl Path {
pub fn remaining_segments(&self) -> usize {
self.segments.len()
}
+
+ #[cfg(feature = "debug_events")]
+ pub fn debug(&self, id: PlayerID) -> DebugEvent {
+ use std::f32::consts::TAU;
+
+ use hurrycurry_protocol::glam::Vec3;
+ let a = id.0 as f32;
+ DebugEvent {
+ key: format!("path-{id}"),
+ color: Vec3::new(
+ (a + TAU / 3. * 0.).sin(),
+ (a + TAU / 3. * 1.).sin(),
+ (a + TAU / 3. * 2.).sin(),
+ ),
+ display: DebugEventDisplay::Path {
+ points: self.segments.clone(),
+ },
+ }
+ }
}
pub fn find_path_to_neighbour(game: &Game, from: IVec2, to: IVec2) -> Option<Path> {
diff --git a/server/bot/src/step.rs b/server/bot/src/step.rs
index 001935ac..34793466 100644
--- a/server/bot/src/step.rs
+++ b/server/bot/src/step.rs
@@ -26,7 +26,8 @@ use hurrycurry_protocol::{Hand, ItemIndex, ItemLocation, PacketS, PlayerID, glam
pub struct StepState {
path: Path,
interact_position: IVec2,
- destination_item: Option<ItemIndex>,
+ item_expected: Option<ItemIndex>,
+ item_current: Option<ItemIndex>,
hand: Hand,
wait_timer: f32,
interact_start_pending: bool,
@@ -40,12 +41,13 @@ impl StepState {
}
pub fn new_wait(me: PlayerID, timer: f32) -> Self {
Self {
- destination_item: None,
+ item_expected: None,
interact_position: IVec2::ZERO,
hand: Hand(0),
interact_start_pending: false,
interact_stop_pending: false,
me,
+ item_current: None,
path: Path::EMPTY,
wait_timer: timer,
}
@@ -59,6 +61,10 @@ impl StepState {
) -> Option<Self> {
let own_pos = game.players.get(&me)?.movement.position.as_ivec2();
let path = find_path_to_neighbour(game, own_pos, pos)?;
+ let destination_item = game
+ .tiles
+ .get(&pos)
+ .and_then(|t| t.item.as_ref().map(|i| i.kind));
Some(Self {
me,
path,
@@ -67,15 +73,14 @@ impl StepState {
interact_stop_pending: true,
interact_start_pending: true,
interact_position: pos,
- destination_item: game
- .tiles
- .get(&pos)
- .and_then(|t| t.item.as_ref().map(|i| i.kind)),
+ item_expected: destination_item,
+ item_current: None,
})
}
pub fn is_busy(&self) -> bool {
self.wait_timer >= 0. || self.interact_stop_pending
+ // && self.item_current == self.item_expected
}
pub fn tick(&mut self, out: &mut PacketSink, game: &Game, dt: f32) {
@@ -103,6 +108,11 @@ impl StepState {
}
}
+ self.item_current = game
+ .tiles
+ .get(&self.interact_position)
+ .and_then(|t| t.item.as_ref().map(|i| i.kind));
+
let position = game
.players
.get(&self.me)
@@ -111,6 +121,10 @@ impl StepState {
.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,
diff --git a/server/protocol/src/lib.rs b/server/protocol/src/lib.rs
index a89d9c30..2d9aa0f0 100644
--- a/server/protocol/src/lib.rs
+++ b/server/protocol/src/lib.rs
@@ -16,7 +16,7 @@
*/
use crate::book::Book;
-use glam::{IVec2, Vec2};
+use glam::{IVec2, Vec2, Vec3};
use helpers::deser::*;
use serde::{Deserialize, Serialize};
use std::{
@@ -381,12 +381,13 @@ pub enum ItemLocation {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DebugEvent {
- key: String,
- display: Vec<DebugEventDisplay>,
- timeout: Option<f32>,
+ pub key: String,
+ pub color: Vec3,
+ pub display: DebugEventDisplay,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case", tag = "ty")]
pub enum DebugEventDisplay {
- Path(Vec<Vec2>),
- Label(Vec2, String),
+ Path { points: Vec<Vec2> },
+ Label { pos: Vec2, text: String },
}
diff --git a/test-client/main.ts b/test-client/main.ts
index fd2e733a..091e0535 100644
--- a/test-client/main.ts
+++ b/test-client/main.ts
@@ -20,7 +20,7 @@
import { init_locale } from "./locale.ts";
import { MovementBase, collide_player_player, update_movement } from "./movement.ts";
import { particle_splash, tick_particles } from "./particles.ts";
-import { Gamedata, ItemIndex, ItemLocation, Message, MessageTimeout, PacketC, PacketS, PlayerClass, PlayerID, Score, TileIndex } from "./protocol.ts";
+import { DebugEvent, Gamedata, ItemIndex, ItemLocation, Message, MessageTimeout, PacketC, PacketS, PlayerClass, PlayerID, Score, TileIndex } from "./protocol.ts";
import { V2, lerp_exp_v2_mut, normalize, lerp_exp } from "./util.ts";
import { draw_ingame, draw_wait } from "./visual.ts";
@@ -116,6 +116,7 @@ export const players = new Map<PlayerID, PlayerData>()
export const tiles = new Map<string, TileData>()
export const items_removed = new Set<ItemData>()
export const server_hints = new Map<string, MessageData>()
+export const debug_events: Map<string, DebugEvent & { timeout: number }> = new Map()
export let data: Gamedata = {
item_names: [],
@@ -158,7 +159,7 @@ function send(p: PacketS) {
ws.send(JSON.stringify(p))
}
function packet(p: PacketC) {
- if (!["movement", "update_map"].includes(p.type))
+ if (!["movement", "update_map", "debug"].includes(p.type))
console.log(p);
switch (p.type) {
case "version":
@@ -334,6 +335,9 @@ function packet(p: PacketC) {
default: console.warn("unknown menu");
}
break;
+ case "debug":
+ debug_events.set(p.key, { timeout: 0.1, ...p })
+ break;
default:
console.warn("unknown packet", p);
}
diff --git a/test-client/protocol.ts b/test-client/protocol.ts
index b43646a9..d0789376 100644
--- a/test-client/protocol.ts
+++ b/test-client/protocol.ts
@@ -74,6 +74,7 @@ export type PacketC =
| { type: "tutorial_ended", item: ItemIndex, player: PlayerID, success: boolean }
| { type: "set_ingame", state: boolean, lobby: boolean } // Set to false when entering the game or switching maps
| { type: "pause", state: boolean } // Set game paused so clients dont increment timers
+ | { type: "debug" } & DebugEvent // Set game paused so clients dont increment timers
export interface Character {
color: number,
@@ -153,3 +154,12 @@ export type NodeStyle =
| "process_active"
| "process_passive"
| "process_instant"
+
+export interface DebugEvent {
+ key: string,
+ color: [number, number, number]
+ display: DebugEventDisplay
+}
+export type DebugEventDisplay =
+ { ty: "path", points: Vec2[] }
+ | { ty: "label", pos: Vec2, text: string } \ No newline at end of file
diff --git a/test-client/visual.ts b/test-client/visual.ts
index d75f90f5..20bd7ae2 100644
--- a/test-client/visual.ts
+++ b/test-client/visual.ts
@@ -16,7 +16,7 @@
*/
import { tr } from "./locale.ts";
-import { ItemData, MessageData, MessageStyle, PlayerData, TileData, camera, camera_scale, canvas, ctx, data, get_interact_target, global_message, interact_active_anim, interact_possible_anim, interact_target_anim, is_lobby, items_removed, keys_down, my_id, overlay_vis_anim, players, score, server_hints, tiles } from "./main.ts";
+import { ItemData, MessageData, MessageStyle, PlayerData, TileData, camera, camera_scale, canvas, ctx, data, debug_events, get_interact_target, global_message, interact_active_anim, interact_possible_anim, interact_target_anim, is_lobby, items_removed, keys_down, my_id, overlay_vis_anim, players, score, server_hints, tiles } from "./main.ts";
import { PLAYER_SIZE } from "./movement.ts";
import { draw_item_sprite, draw_tile_sprite, ItemName, TileName } from "./tiles.ts";
import { V2, ceil_v2, floor_v2 } from "./util.ts";
@@ -78,6 +78,8 @@ export function draw_ingame() {
for (const [_, message] of server_hints)
draw_message(message, true)
+ draw_debug_events()
+
ctx.restore()
ctx.save()
ctx.translate(50, 50)
@@ -94,7 +96,23 @@ export function draw_ingame() {
draw_score()
if (keys_down.has("KeyP"))
- draw_debug()
+ draw_info_overlay()
+}
+
+function draw_debug_events() {
+ for (const ev of debug_events.values()) {
+ if (ev.display.ty == "path") {
+ ctx.lineWidth = 0.1
+ ctx.lineCap = "round"
+ ctx.strokeStyle = `rgb(${ev.color[0] * 100}%,${ev.color[1] * 100}%,${ev.color[2] * 100}%)`
+ ctx.beginPath()
+ if (ev.display.points.length)
+ ctx.moveTo(...ev.display.points[0])
+ for (let i = 1; i < ev.display.points.length; i++)
+ ctx.lineTo(...ev.display.points[i])
+ ctx.stroke()
+ }
+ }
}
function draw_score() {
@@ -110,7 +128,7 @@ function draw_score() {
ctx.fillText(`${tr("c.score.demands_failed")}: ${score.demands_failed}`, 10, canvas.height - 10)
}
-function draw_debug() {
+function draw_info_overlay() {
ctx.fillStyle = "white"
ctx.textAlign = "left"
ctx.textBaseline = "bottom"