Online multi-player first-person shooter using Castle Game Engine and RNL.
If you just want to download a ready client and play:
- get it from release on Itch.io
- or from release on GitHub
Features:
- Choose your nick,
- join a server game,
- send chat messages to everyone,
- move, shoot, die, repeat.
This is a demo of integrating
- Castle Game Engine - 3D and 2D open-source game engine using Object Pascal,
- RNL - real-time networking library, open source, using Object Pascal
... to create a simple FPS in 3D online.
Client keys:
/
to send chat (type whatever, pressEnter
to send,Escape
to cancel)Ctrl + Q
to go back to main menuEscape
to toggle mouse look on/off (esp. useful to switch to other applications while playing)- AWSD, arrow keys, rotate with mouse (when mouse look) to move/rotate
Shift
to runLeft click
to shoot
Done during our gamejam at Cat-astrophe Games on 2022-06-10. Done in 1 day.
Platforms (using GitHub actions to build everywhere):
-
Linux: client and server.
-
Windows: client and server.
-
macOS: client and server. But note that there are some critical issues with macOS client: mouse look is broken (see TODO section below).
-
Android: client. But note that there are some critical issues with Android version: it cannot connect (ERNLHost, "Empty Socket" error -- likely on RNL side), also not optimal UI on mobile (see TODO section below).
Server can run on any plaform and accept connection from client from any platform. I.e. you can run server on Linux and connect from any platform -- Linux, Windows etc.
Central server. Also developed using RNL. With some code shared with frontend (client). Each frontend is just a client to this server.
You can:
-
use the default server. It runs on https://michalis.xyz/ , I (Michalis) will keep it running throughout the gamejam and probably much longer. Ping me on Discord https://castle-engine.io/talk.php if the server seems to be down.
-
run your own server. Use the command-line parameter
--host localhost
when running the client (withlocalhost
being the name, or IP, of your own server).
You run the game, you input your nick (honestly anything), and you join the game -- essentially one common "room" for all players.
Checkout with submodules.
git clone --recurse-submodules https://github.com/castle-engine/not-quake
Build and run server:
cd not-quake/server/
castle-engine compile --mode=release
castle-engine run # or just ./not-quake-server
Build and run client:
cd not-quake/client/
castle-engine compile --mode=release
castle-engine run -- --host localhost
# or just ./not-quake --host localhost
By default it connects to server on michalis.xyz
(Michalis Kamburelis private host, see https://michalis.xyz/ ) which I will try to keep running for some time. Ping me (find me on Discord, https://castle-engine.io/talk.php ) if the server seems to be down :)
Using Castle Game Engine. You can clone it from https://github.com/castle-engine/castle-engine/ . The master
branch of CGE is OK now.
Compile by entering client
or server
and build by:
-
CGE editor. Just use menu item "Compile".
-
Or use CGE command-line build tool. Run
castle-engine compile
in this directory. -
Or use Lazarus. Open in Lazarus
not_quake_standalone.lpi
file and compile / run from Lazarus. Make sure to first register CGE Lazarus packages.
-
macOS client: broken mouse look, known CGE missing thing (Cocoa + SetMousePosition and mouse hide)
-
Use speed predictions to move other players (will allow to update state less often?). I planned this for gamejam, but didn't manage.
-
Android:
- cannot connect ("Empty Socket") - likely we miss some Android permissions
- input nick/chat requires on-screen keyboard
- 3D navigation requires TCastleTouchNavigation
- actions like "send char", "quit to menu" must be buttons, not only accessible by keys
-
Do more network performance testing.
- There are various timeouts to test. Like BroadcastTimeout, NormalTimeout,
- RNL also has easy switches to go between reliable/unreliable, ordered/unordered messages.
-
Make input on Android work too.
-
Rooms within the server. Before joining, you can list/create/join a room. Each room is a separate play.
-
Sounds of hit / miss.
-
Cut down to find source of occasional crash in server, for now workarounded:
try if PayloadData = nil then Writeln('PayloadData = nil'); if NormalPacketHeader = nil then Writeln('NormalPacketHeader = nil'); DispatchIncomingPacket(PayloadData^, PayloadDataLength, TRNLEndianness.LittleEndianToHost16(NormalPacketHeader^.SentTime)); except on E: EAccessViolation do Writeln('Caught EAccessViolation around DispatchIncomingPacket, silencing'); // TODO: reproduce, report end;
-
Big: Turn this into generic network that can auto-synchronize TCastleViewport or TCastleTransform or other TCastleComponent state "automagically" over the network.