Fresh start: replace with naxIO/netfox-cs-sample foundation

Complete replacement of the tactical-shooter project with the
netfox-cs-sample (MIT) — a CS 1.6 inspired multiplayer FPS built
with Godot 4 and netfox.

## What's new
- Full CS-style gameplay: teams (T/CT), rounds, economy, buy menu
- 6 weapons: Knife, Glock, USP, AK-47, M4A1, AWP
- Bomb plant/defuse with 2 bombsites
- Flashbang & smoke grenades
- Proper netfox rollback netcode at 64 tick
- Network popup UI for host/join
- HUD, crosshair, round timer, scoreboard
- All netfox singletons registered as autoloads (works in exported builds)

## Architecture
- Listen-server (host from client, no dedicated server binary)
- Multiplayer-fps game lives at examples/multiplayer-fps/
- Netfox addons registered as autoloads for exported build compat
- Godot 4.7 with Forward+ renderer

## Removed
- Old headless-server architecture (client_main, server_main, player.gd, etc.)
- Custom netfox bootstrap with ENet fallback
- Old ChaffGames FPS template (2,420 lines, 844 KB)
- SimulationServer GDExtension stub
- Godot-jolt physics (netfox sample uses default Godot physics)
- Duplicate weapon_data.gd, anti_cheat.gd, round_manager.gd, etc.
- Server browser API Python venv (87 MB)
- test_range map and modular assets

## Preserved
- Git history
- Server config at config/default_server_config.cfg
- Windows export preset
- Build directory (gitignored)

Co-authored-by: naxIO <naxIO@users.noreply.github.com>
This commit is contained in:
2026-07-02 20:55:20 -04:00
parent ce39b237c3
commit b0c83af092
4416 changed files with 57418 additions and 902676 deletions
@@ -0,0 +1,64 @@
# Authoritative servers
The idea behind multiplayer servers is replicating state. As long each player
sees approximately the same things happening on their screen, the illusion of a
shared world works.
## Naive replication
To implement state replication, we could say that each player is responsible
for their own state. Players see the effects of their input instantly, as they
own their state and thus their avatar.
The issue is that clients can't be trusted. Your game client is distributed to
players, who run it in various environments. These environments are out of the
developer's control, and provide an attack surface for cheats.
For example, a modified game client might always report full HP no matter how
many hits the player takes. If each player is responsible for their own state,
the cheating player's full-HP state will be replicated to everyone else.
## Server as the source of truth
What can be controlled is the server, with dedicated hosting. Thus, the server
can be the single source of truth - or in other words, authoritative. Clients
send their inputs to the server, and the server responds with the updated game
state.
This makes cheating difficult, as players have limited influence over the game
world.
Game code can also be simplified - everything that affects the gameplay is run
on the server, while other things such as visual effects are run on the
clients.
The tradeoff is that it takes time for the updated game state to arrive from
the server. This necessitates techniques that mask this delay, such as
[Client-side prediction and Server reconciliation].
## Other approaches
Server-authoritative gameplay with CSP is not a silver bullet unfortunately,
and different games may require different approaches to network state
replication.
One good example is RTS games. These games can have 50+ or even hundreds of
units navigating the map and interacting. Broadcasting all of their state to
all of the players from the server may not always be feasible.
Instead, players broadcast their actions ( inputs ) to each other and update
their game state in lockstep. While this approach can scale up to hundreds of
units, it has other drawbacks. One of these is developing the game in such a
way that the simulation is exactly the same across multiple CPU architectures
down to each bit.
For more on this approach, see: [1500 Archers on a 28.8: Network Programming in
Age of Empires and Beyond]
For more approaches, see: [Networking for Physics Programmers]
[1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond]: https://www.gamedeveloper.com/programming/1500-archers-on-a-28-8-network-programming-in-age-of-empires-and-beyond
[Networking for Physics Programmers]: https://www.gdcvault.com/play/1022195/Physics-for-Game-Programmers-Networking
[Client-side prediction and Server reconciliation]: https://www.gabrielgambetta.com/client-side-prediction-server-reconciliation.html
@@ -0,0 +1,35 @@
# Servers, clients, and ownership
Much of this documentation discusses things in context of servers and clients.
This page is intended to clear up how this translates to Godot's concept of
multiplayer ownership.
## Ownership in Godot
In Godot's multiplayer system, each node belongs to a multiplayer peer, i.e. a
player. This can be set from scripts, and is not replicated. This means that
the logic assigning ownership to nodes must produce the same result on every
machine for things to work consistently.
## Ownership in netfox
To mesh better with Godot's existing conventions, *netfox* doesn't work in
terms of server and client, but uses ownership instead.
Whenever *the server* is mentioned, it refers to a given node's owner.
In practice, this means that nodes representing game state are and should be
owned by the server.
## Limitations
At the time of writing, ownership is hard-coded in some cases. One such case is
*NetworkTime*, which is always owned by the host peer and always takes the host
peer's time as reference.
This means that peer-to-peer games are not officially supported by *netfox*,
but might be able to work with some workarounds. If feasible, you can build
self-hosted games by including *netfox.noray*.
In theory, multiple players can own different parts of the game state, but
*netfox* is not tested for such use cases.