diff --git a/game_core/src/entities/mod.rs b/game_core/src/entities/mod.rs
index 13037dbe39af29500d714cea5a78c818e1367c67..89dfaa7f89d9e5af74214bd9c2585387419ea181 100644
--- a/game_core/src/entities/mod.rs
+++ b/game_core/src/entities/mod.rs
@@ -1,2 +1,16 @@
 pub mod lifecycle;
 pub mod spawner;
+pub mod timing;
+
+mod __plugin {
+	use bevy::app::{PluginGroup, PluginGroupBuilder};
+
+	pub struct EntitiesPluginGroup;
+	impl PluginGroup for EntitiesPluginGroup {
+		fn build(&mut self, group: &mut PluginGroupBuilder) {
+			group.add(super::timing::TimingPlugin);
+		}
+	}
+}
+
+pub use __plugin::EntitiesPluginGroup;
diff --git a/game_core/src/entities/timing.rs b/game_core/src/entities/timing.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e6c35869ce39ec564a6877eb11b658c58da1982f
--- /dev/null
+++ b/game_core/src/entities/timing.rs
@@ -0,0 +1,95 @@
+use std::time::Duration;
+
+use bevy::prelude::*;
+use iyes_loopless::prelude::{AppLooplessStateExt, ConditionSet};
+
+use crate::system::flow::AppState;
+
+#[derive(Debug)]
+pub struct GlobalTimer {
+	internal: Duration,
+}
+
+impl Default for GlobalTimer {
+	fn default() -> Self {
+		GlobalTimer {
+			internal: Duration::ZERO,
+		}
+	}
+}
+
+impl GlobalTimer {
+	const GOAL: Duration = Duration::from_secs(10);
+	pub fn tick(&mut self, dt: Duration) {
+		self.internal += dt;
+	}
+	pub fn is_triggered(&self) -> bool {
+		self.internal >= Self::GOAL
+	}
+	pub fn settle(&mut self) {
+		while self.internal >= Self::GOAL {
+			self.internal -= Self::GOAL
+		}
+	}
+	pub fn percent_complete(&self) -> f32 {
+		self.internal.as_secs_f32() / Self::GOAL.as_secs_f32()
+	}
+}
+
+pub fn tick_global_timer(time: Res<Time>, mut timer: ResMut<GlobalTimer>) {
+	timer.settle();
+	timer.tick(time.delta());
+}
+
+#[derive(Copy, Clone, Default, Component)]
+pub struct GlobalTimerUi;
+pub fn spawn_global_timer_ui(mut commands: Commands, timer: Res<GlobalTimer>) {
+	commands
+		.spawn_bundle(NodeBundle {
+			style: Style {
+				size: Size::new(Val::Auto, Val::Px(25.0)),
+				position_type: PositionType::Absolute,
+				position: UiRect::new(
+					Val::Px(0.0),
+					Val::Percent((1.0 - timer.percent_complete()) * 100.0),
+					Val::Auto,
+					Val::Px(0.0),
+				),
+				..Default::default()
+			},
+			color: Color::ALICE_BLUE.into(),
+			..Default::default()
+		})
+		.insert(GlobalTimerUi);
+}
+
+pub fn update_global_timer_ui(
+	timer: Res<GlobalTimer>,
+	mut query: Query<&mut Style, With<GlobalTimerUi>>,
+) {
+	for mut style in &mut query {
+		style.position.right = Val::Percent((1.0 - timer.percent_complete()) * 100.0);
+	}
+}
+
+pub fn remove_global_timer_ui(mut commands: Commands, query: Query<Entity, With<GlobalTimerUi>>) {
+	for entity in &query {
+		commands.entity(entity).despawn_recursive();
+	}
+}
+
+pub struct TimingPlugin;
+impl Plugin for TimingPlugin {
+	fn build(&self, app: &mut App) {
+		app.init_resource::<GlobalTimer>()
+			.add_system_to_stage(CoreStage::First, tick_global_timer)
+			.add_enter_system(AppState::InGame, spawn_global_timer_ui)
+			.add_system_set(
+				ConditionSet::new()
+					.run_in_state(AppState::InGame)
+					.with_system(update_global_timer_ui)
+					.into(),
+			)
+			.add_exit_system(AppState::InGame, remove_global_timer_ui);
+	}
+}
diff --git a/game_core/src/main.rs b/game_core/src/main.rs
index 9e165a9060d5f313726a791cae039629f1bfe09d..4823b6c706c61a0263cd61189cb5973d49c3997a 100644
--- a/game_core/src/main.rs
+++ b/game_core/src/main.rs
@@ -22,5 +22,6 @@ fn main() {
 		.add_plugin(game_core::debug::DebugPlugin)
 		.add_plugin(game_core::world::WorldPlugin)
 		.add_plugin(game_core::control::ControlPlugin)
+		.add_plugins(game_core::entities::EntitiesPluginGroup)
 		.run();
 }
diff --git a/game_core/src/system/resources.rs b/game_core/src/system/resources.rs
index cab2bb41f4b06c203ba2eafed356374142e0d811..b684f08f0a08df34993c50af2237a907c8b2192d 100644
--- a/game_core/src/system/resources.rs
+++ b/game_core/src/system/resources.rs
@@ -11,8 +11,8 @@ impl Plugin for DefaultResourcesPlugin {
 		let (width, height) = initial_size();
 
 		app.insert_resource(WindowDescriptor {
-			width,
-			height,
+			width: width * 2.0,
+			height: height * 2.0,
 			resizable: true,
 			title: String::from("Ludum Dare 51"),
 			present_mode: PresentMode::AutoNoVsync,