Skip to content

Commit b6f3e56

Browse files
committed
spawning bouncy balls
1 parent 8365e35 commit b6f3e56

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

client/src/world/HeightOpacityManager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ export class HeightOpacityManager {
7070

7171

7272

73+

docs/fly-postgres-setup.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,4 @@ You should see `DATABASE_URL` in the list.
5757

5858

5959

60+

server/src/main.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ mod physics;
2323
mod websocket;
2424

2525
use db::{create_pool, save_all_entities, set_game_time_minutes};
26-
use game::GameState;
26+
use game::{Entity, EntityType, GameState, Position, Rotation};
2727
use messages::GameMessage;
28+
use rand::Rng;
29+
use uuid::Uuid;
2830
use websocket::handle_websocket;
2931

3032
/// Application state shared across all request handlers.
@@ -53,6 +55,7 @@ pub struct AppState {
5355
/// - Entity persistence (every 60 seconds)
5456
/// - Physics simulation (60 FPS)
5557
/// - World state broadcasting (10 FPS)
58+
/// - Bouncy ball spawning (every 60 seconds)
5659
/// 4. HTTP/WebSocket server
5760
#[tokio::main]
5861
async fn main() -> anyhow::Result<()> {
@@ -155,6 +158,42 @@ async fn main() -> anyhow::Result<()> {
155158
}
156159
});
157160

161+
// Background task: Spawn a new bouncy ball at a random point on the ground every real-time minute
162+
// Ground is 10000x10000 units, so random positions are within ±5000 for x and z
163+
let game_state_for_ball_spawn = app_state.game.clone();
164+
tokio::spawn(async move {
165+
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(60));
166+
loop {
167+
interval.tick().await;
168+
// Generate random position on the ground
169+
// Create RNG inside loop to avoid Send issues
170+
let x = rand::thread_rng().gen_range(-5000.0..5000.0);
171+
let z = rand::thread_rng().gen_range(-5000.0..5000.0);
172+
// Ball starts at y=500 (5 meters) for visibility, physics will handle falling
173+
let y = 500.0;
174+
175+
// Create new ball entity
176+
let ball_id = format!("ball_{}", Uuid::new_v4());
177+
let ball_entity = Entity {
178+
id: ball_id.clone(),
179+
entity_type: EntityType::Ball,
180+
position: Position { x, y, z },
181+
rotation: Rotation {
182+
x: 0.0,
183+
y: 0.0,
184+
z: 0.0,
185+
},
186+
};
187+
188+
// Add entity to game state (this will also create the physics body)
189+
let mut game = game_state_for_ball_spawn.write().await;
190+
game.add_entity(ball_entity);
191+
drop(game);
192+
193+
tracing::info!("Spawned new bouncy ball at ({x}, {z})");
194+
}
195+
});
196+
158197
// Set up HTTP routes
159198
let app = Router::new()
160199
// WebSocket endpoint for game client connections

0 commit comments

Comments
 (0)