A Java Swing multiplayer game project created to learn Java Swing, networking, and multithreading concepts.
java -jar 'Fireball Client.jar'java -jar 'Fireball Server.jar'- Open the Client project in IntelliJ IDEA.
- Right-click the
resdirectory. - Select Mark Directory As -> Resources Root.
- Run
Main.java.
Note: If the
resfolder is not marked as a Resources Root, image resources will not be found and the game will throw aNullPointerExceptionwhen loading assets.
javac -d out $(find src -name "*.java")
java -cp "out;res" main.Mainjavac -d out src/**/*.java
java -cp "out:res" main.Main- Built using Java Swing.
- Designed as a multiplayer game with a dedicated server architecture.
- Client and server are packaged separately for convenience.
- The client can be launched and explored without a running server.
- Developed and tested using JDK 21.0.8.
Java Downloads:
https://www.oracle.com/java/technologies/downloads/#jdk21-windows
When the game launches, players are prompted to enter a username.
The username is used to identify and route network packets between connected clients during gameplay.
- Protocol: TCP
- Port:
6682
To host a dedicated server:
- Launch the server application.
- Configure port forwarding for TCP port
6682on your router. - Determine the server machine's public IP address.
- Have clients connect using that public IP and port
6682.
| Action | Control |
|---|---|
| Move | WASD |
| Shoot Fireball | Left Mouse Button |
| Open In-Game Menu | ESC |
| Navigate Menus | Left Mouse Button |
| Respawn | Left Mouse Button |
Fireballs have a 0.5-second cooldown to reduce projectile spam and encourage more strategic multiplayer gameplay.
Projectiles can collide with and destroy one another before detonating. Shooting an incoming fireball is therefore a viable defensive tactic.
Exploding fireballs leave behind a burning area that deals damage over time. Standing directly in the flames increases the damage rate.
Players have 100 health.
Health is represented visually using blood droplets that display health in 10-point increments, rounded down.
Examples:
| Health | Droplets Displayed |
|---|---|
| 100 | 10 |
| 30 | 3 |
| 29 | 2 |
| 9 | 0 |
This means a player may still be alive even when no droplets are displayed.
Projectiles currently use ArrayList collections.
A ConcurrentHashMap-based approach would likely provide:
- Better collision lookup performance
- Improved thread safety
- Better scalability under heavier multiplayer loads
This project was developed while learning networking concepts and prioritizing functionality before implementing a fully authoritative server model.
As a result, some game logic remains client-side, including:
- Collision detection
- Damage calculations
- Position validation
Under higher network latency, clients may occasionally disagree on player state.
For example:
- One client may show a player as dead while another still shows them alive.
- Position updates can become temporarily desynchronized.
If a desynchronization occurs:
- Press
ESC. - Return to the main menu.
- Rejoin the game lobby.
This will resynchronize player state.
Because player collision handling is not fully server-authoritative, players may occasionally be repositioned unexpectedly when colliding with one another under higher latency conditions.
This behavior was implemented to prevent players from becoming permanently stuck inside one another but can sometimes result in visible teleportation.