Skip to content

Commit adb3479

Browse files
bors[bot]zicklag
andauthored
Merge #498
498: Sync Network Pause State r=zicklag a=zicklag Reset and map selection buttons won't sync over the network for now. Co-authored-by: Zicklag <[email protected]>
2 parents bc99414 + 9233592 commit adb3479

File tree

18 files changed

+156
-82
lines changed

18 files changed

+156
-82
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "jumpy"
3-
version = "0.4.3"
3+
version = "0.5.0-dev"
44
description = "A tactical 2D shooter"
55
authors = ["The Fish Fight Game & Spicy Lobster Developers"]
66
license = "MIT OR Apache-2.0"

src/main.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use crate::{
7676
random::RandomPlugin,
7777
session::SessionPlugin,
7878
ui::UiPlugin,
79-
utils::{is_in_game_run_criteria, UtilsPlugin},
79+
utils::{run_criteria_game_not_paused, UtilsPlugin},
8080
workarounds::WorkaroundsPlugin,
8181
};
8282

@@ -94,17 +94,21 @@ pub enum GameState {
9494
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9595
pub enum InGameState {
9696
Playing,
97-
Editing,
9897
Paused,
9998
}
10099

100+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
101+
pub enum GameEditorState {
102+
Hidden,
103+
Visible,
104+
}
105+
101106
#[derive(StageLabel)]
102107
pub enum RollbackStage {
108+
Input,
103109
First,
104110
PreUpdate,
105-
PreUpdateInGame,
106111
Update,
107-
UpdateInGame,
108112
PostUpdate,
109113
Last,
110114
}
@@ -154,44 +158,40 @@ pub fn main() {
154158

155159
// Set initial game state
156160
app.add_loopless_state(GameState::LoadingPlatformStorage)
157-
.add_loopless_state(InGameState::Playing);
161+
.add_loopless_state(InGameState::Playing)
162+
.add_loopless_state(GameEditorState::Hidden);
158163

159164
// Create the GGRS rollback schedule and plugin
160165
let mut rollback_schedule = Schedule::default();
161166
let rollback_plugin = GGRSPlugin::<GgrsConfig>::new();
162167

163168
// Add fixed update stagesrefs/branchless/2fd80952e26d905aa258ebb7e6175a7cfc4cb76f
164169
rollback_schedule
165-
.add_stage(RollbackStage::First, SystemStage::parallel())
170+
.add_stage(RollbackStage::Input, SystemStage::parallel())
166171
.add_stage_after(
172+
RollbackStage::Input,
167173
RollbackStage::First,
168-
RollbackStage::PreUpdate,
169-
SystemStage::parallel(),
174+
SystemStage::parallel().with_run_criteria(run_criteria_game_not_paused),
170175
)
171176
.add_stage_after(
177+
RollbackStage::First,
172178
RollbackStage::PreUpdate,
173-
RollbackStage::Update,
174-
SystemStage::parallel(),
179+
SystemStage::parallel().with_run_criteria(run_criteria_game_not_paused),
175180
)
176181
.add_stage_after(
177182
RollbackStage::PreUpdate,
178-
RollbackStage::PreUpdateInGame,
179-
SystemStage::parallel().with_run_criteria(is_in_game_run_criteria),
180-
)
181-
.add_stage_after(
182183
RollbackStage::Update,
183-
RollbackStage::PostUpdate,
184-
SystemStage::parallel(),
184+
SystemStage::parallel().with_run_criteria(run_criteria_game_not_paused),
185185
)
186186
.add_stage_after(
187187
RollbackStage::Update,
188-
RollbackStage::UpdateInGame,
189-
SystemStage::parallel().with_run_criteria(is_in_game_run_criteria),
188+
RollbackStage::PostUpdate,
189+
SystemStage::parallel().with_run_criteria(run_criteria_game_not_paused),
190190
)
191191
.add_stage_after(
192192
RollbackStage::PostUpdate,
193193
RollbackStage::Last,
194-
SystemStage::parallel(),
194+
SystemStage::parallel().with_run_criteria(run_criteria_game_not_paused),
195195
);
196196

197197
// Add the rollback schedule and plugin as resources, temporarily.

src/map/elements/grenade.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ impl Plugin for GrenadePlugin {
3838
fn build(&self, app: &mut App) {
3939
app.extend_rollback_schedule(|schedule| {
4040
schedule
41-
.add_system_to_stage(RollbackStage::PreUpdateInGame, pre_update_in_game)
41+
.add_system_to_stage(RollbackStage::PreUpdate, pre_update_in_game)
4242
.add_system_to_stage(
43-
RollbackStage::UpdateInGame,
43+
RollbackStage::Update,
4444
update_lit_grenades.before(update_idle_grenades),
4545
)
46-
.add_system_to_stage(RollbackStage::UpdateInGame, update_idle_grenades);
46+
.add_system_to_stage(RollbackStage::Update, update_idle_grenades);
4747
})
4848
.extend_rollback_plugin(|plugin| {
4949
plugin

src/map/elements/player_spawner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ impl Plugin for PlayerSpawnerPlugin {
77
fn build(&self, app: &mut App) {
88
app.init_resource::<CurrentPlayerSpawner>()
99
.extend_rollback_schedule(|schedule| {
10-
schedule.add_system_to_stage(RollbackStage::PreUpdateInGame, pre_update_in_game);
10+
schedule.add_system_to_stage(RollbackStage::PreUpdate, pre_update_in_game);
1111
})
1212
.extend_rollback_plugin(|plugin| {
1313
plugin

src/map/elements/sproinger.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ impl Plugin for SproingerPlugin {
77
fn build(&self, app: &mut App) {
88
app.extend_rollback_schedule(|schedule| {
99
schedule
10-
.add_system_to_stage(RollbackStage::PreUpdateInGame, pre_update_in_game)
11-
.add_system_to_stage(RollbackStage::UpdateInGame, update_in_game);
10+
.add_system_to_stage(RollbackStage::PreUpdate, pre_update_in_game)
11+
.add_system_to_stage(RollbackStage::Update, update_in_game);
1212
})
1313
.extend_rollback_plugin(|plugin| plugin.register_rollback_type::<Sproinger>());
1414
}

src/map/elements/sword.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ impl Plugin for SwordPlugin {
55
fn build(&self, app: &mut App) {
66
app.extend_rollback_schedule(|schedule| {
77
schedule
8-
.add_system_to_stage(RollbackStage::PreUpdateInGame, pre_update_in_game)
9-
.add_system_to_stage(RollbackStage::UpdateInGame, update_in_game);
8+
.add_system_to_stage(RollbackStage::PreUpdate, pre_update_in_game)
9+
.add_system_to_stage(RollbackStage::Update, update_in_game);
1010
})
1111
.extend_rollback_plugin(|plugin| plugin.register_rollback_type::<SwordState>());
1212
}

src/networking.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,51 @@
1-
use crate::prelude::*;
1+
use bevy_ggrs::ggrs::P2PSession;
2+
3+
use crate::{
4+
prelude::*, session::SessionManager, ui::main_menu::MenuPage, utils::ResetManager, GgrsConfig,
5+
};
6+
7+
use self::{
8+
client::NetClient,
9+
proto::{match_setup::MatchSetupMessage, ReliableGameMessageKind},
10+
};
211

312
pub mod client;
413
pub mod proto;
5-
// pub mod server;
614

715
pub struct NetworkingPlugin;
816

917
impl Plugin for NetworkingPlugin {
10-
fn build(&self, _app: &mut App) {}
18+
fn build(&self, app: &mut App) {
19+
app.add_system(listen_for_map_changes.run_if_resource_exists::<P2PSession<GgrsConfig>>());
20+
}
21+
}
22+
23+
// TODO: Map changes aren't working on network games for now.
24+
fn listen_for_map_changes(
25+
mut commands: Commands,
26+
client: Res<NetClient>,
27+
mut reset_manager: ResetManager,
28+
mut session_manager: SessionManager,
29+
mut menu_page: ResMut<MenuPage>,
30+
mut ridp: ResMut<RollbackIdProvider>,
31+
) {
32+
while let Some(message) = client.recv_reliable() {
33+
match message.kind {
34+
ReliableGameMessageKind::MatchSetup(setup) => match setup {
35+
MatchSetupMessage::SelectMap(map_handle) => {
36+
info!("Other player selected map, starting game");
37+
*menu_page = MenuPage::Home;
38+
reset_manager.reset_world();
39+
40+
commands
41+
.spawn()
42+
.insert(map_handle)
43+
.insert(Rollback::new(ridp.next_id()));
44+
commands.insert_resource(NextState(GameState::InGame));
45+
session_manager.start_session();
46+
}
47+
other => warn!("Unexpected message during match: {other:?}"),
48+
},
49+
}
50+
}
1151
}

src/networking/proto.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ pub enum ReliableGameMessageKind {
77
MatchSetup(match_setup::MatchSetupMessage),
88
}
99

10+
impl From<match_setup::MatchSetupMessage> for ReliableGameMessageKind {
11+
fn from(x: match_setup::MatchSetupMessage) -> Self {
12+
Self::MatchSetup(x)
13+
}
14+
}
15+
1016
#[derive(Serialize, Deserialize, Debug, Clone)]
1117
pub struct RecvReliableGameMessage {
1218
pub from_player_idx: usize,
@@ -30,12 +36,6 @@ pub struct RecvUnreliableGameMessage {
3036
pub kind: UnreliableGameMessageKind,
3137
}
3238

33-
impl From<match_setup::MatchSetupMessage> for ReliableGameMessageKind {
34-
fn from(x: match_setup::MatchSetupMessage) -> Self {
35-
Self::MatchSetup(x)
36-
}
37-
}
38-
3939
/// A resource indicating which player this game client represents, and how many players there are
4040
/// in the match.j
4141
#[derive(Serialize, Deserialize, Debug, Clone)]

src/player/input.rs

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@ impl Plugin for PlayerInputPlugin {
2525
.add_system_to_stage(CoreStage::Last, clear_input_buffer)
2626
.extend_rollback_plugin(|plugin| plugin.register_rollback_type::<PlayerInputs>())
2727
.extend_rollback_schedule(|schedule| {
28-
schedule.add_system_to_stage(RollbackStage::PreUpdate, update_user_input);
29-
// .add_system_to_stage(FixedUpdateStage::Last, reset_input);
28+
schedule.add_system_to_stage(RollbackStage::Input, update_user_input);
3029
});
3130
}
3231
}
3332

33+
/// This is a resource that gets inserted every time the menu wants to modify the pause state of the
34+
/// game.
35+
///
36+
/// The resource is removed every time it is read, so it will only be present in the world when
37+
/// there is an intent to change the pause state.
38+
pub struct WantsGamePause(pub bool);
39+
3440
/// A buffer holding the player inputs until they are read by the game simulation.
3541
#[derive(Reflect, Default)]
3642
pub struct LocalPlayerInputBuffer {
@@ -79,10 +85,20 @@ fn clear_input_buffer(mut buffer: ResMut<LocalPlayerInputBuffer>) {
7985
/// The GGRS input system
8086
pub fn input_system(
8187
player_handle: In<PlayerHandle>,
88+
mut commands: Commands,
8289
mut buffer: ResMut<LocalPlayerInputBuffer>,
90+
wants_game_pause: Option<Res<WantsGamePause>>,
8391
) -> DensePlayerControl {
8492
buffer.has_been_read = true;
85-
buffer.players[player_handle.0]
93+
let mut input = buffer.players[player_handle.0];
94+
95+
if let Some(wants_game_pause) = wants_game_pause {
96+
commands.remove_resource::<WantsGamePause>();
97+
input.set_wants_to_set_pause(true);
98+
input.set_pause_value(wants_game_pause.0);
99+
}
100+
101+
input
86102
}
87103

88104
/// The control inputs that a player may make.
@@ -100,7 +116,7 @@ pub enum PlayerAction {
100116
#[reflect(Default, Resource)]
101117
pub struct PlayerInputs {
102118
/// This will be `true` if _all_ of the inputs for all players for this frame have been
103-
/// confirmed and will not be rolled back.
119+
/// confirmed ( so presumably will not be rolled back ).
104120
pub is_confirmed: bool,
105121
pub players: Vec<PlayerInput>,
106122
}
@@ -157,21 +173,24 @@ bitfield::bitfield! {
157173
/// This is used when sending player inputs across the network.
158174
#[derive(bytemuck::Pod, bytemuck::Zeroable, Copy, Clone, PartialEq, Eq, Reflect)]
159175
#[repr(transparent)]
160-
pub struct DensePlayerControl(u16);
176+
pub struct DensePlayerControl(u32);
161177
impl Debug;
162178
jump_pressed, set_jump_pressed: 0;
163179
shoot_pressed, set_shoot_pressed: 1;
164180
grab_pressed, set_grab_pressed: 2;
165181
slide_pressed, set_slide_pressed: 3;
166182
from into DenseMoveDirection, move_direction, set_move_direction: 15, 4;
183+
/// This bit will be set if this player wants to try and pause or un-pause the game
184+
wants_to_set_pause, set_wants_to_set_pause: 16;
185+
/// This value is only relevant if `wants_to_set_pause` is true, and it indicates whether the
186+
/// player wants to pause or unpause the game.
187+
pause_value, set_pause_value: 17;
167188
}
168189

169190
impl Default for DensePlayerControl {
170191
fn default() -> Self {
171192
let mut control = Self(0);
172-
173193
control.set_move_direction(default());
174-
175194
control
176195
}
177196
}
@@ -183,10 +202,10 @@ struct DenseMoveDirection(pub Vec2);
183202

184203
/// This is the specific [`Quantized`] type that we use to represent movement directions in
185204
/// [`DenseMoveDirection`].
186-
type MoveDirQuant = Quantized<IntRange<u16, 0b111111, -1, 1>>;
205+
type MoveDirQuant = Quantized<IntRange<u32, 0b111111, -1, 1>>;
187206

188-
impl From<u16> for DenseMoveDirection {
189-
fn from(bits: u16) -> Self {
207+
impl From<u32> for DenseMoveDirection {
208+
fn from(bits: u32) -> Self {
190209
// maximum movement value representable, we use 6 bits to represent each movement direction.
191210
let max = 0b111111;
192211
// The first six bits represent the x movement
@@ -208,7 +227,7 @@ impl From<u16> for DenseMoveDirection {
208227
}
209228
}
210229

211-
impl From<DenseMoveDirection> for u16 {
230+
impl From<DenseMoveDirection> for u32 {
212231
fn from(dir: DenseMoveDirection) -> Self {
213232
let x_bits = MoveDirQuant::from_f32(dir.x).raw();
214233
let y_bits = MoveDirQuant::from_f32(dir.y).raw();
@@ -219,6 +238,7 @@ impl From<DenseMoveDirection> for u16 {
219238

220239
/// Updates the [`PlayerInputs`] resource from input collected from GGRS.
221240
fn update_user_input(
241+
mut commands: Commands,
222242
inputs: Res<Vec<(DensePlayerControl, InputStatus)>>,
223243
mut player_inputs: ResMut<PlayerInputs>,
224244
) {
@@ -227,6 +247,19 @@ fn update_user_input(
227247
.map(|x| x.1)
228248
.all(|x| x == InputStatus::Confirmed);
229249

250+
let someone_wants_to_pause = inputs
251+
.iter()
252+
.any(|x| x.0.wants_to_set_pause() && x.0.pause_value());
253+
let someone_wants_to_unpause = inputs
254+
.iter()
255+
.any(|x| x.0.wants_to_set_pause() && !x.0.pause_value());
256+
257+
if someone_wants_to_pause {
258+
commands.insert_resource(NextState(InGameState::Paused));
259+
} else if someone_wants_to_unpause {
260+
commands.insert_resource(NextState(InGameState::Playing));
261+
}
262+
230263
for (player_idx, (input, _)) in inputs.iter().enumerate() {
231264
let PlayerInput {
232265
control,

0 commit comments

Comments
 (0)