Files
tactical-shooter/examples/forest-brawl/scenes/brawler.tscn
T
shawn b0c83af092 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>
2026-07-02 20:55:20 -04:00

163 lines
7.6 KiB
Plaintext

[gd_scene load_steps=28 format=3 uid="uid://wi4owat0bml3"]
[ext_resource type="Script" path="res://examples/forest-brawl/scripts/brawler-controller.gd" id="1_np8na"]
[ext_resource type="Script" path="res://examples/forest-brawl/scripts/brawler-input.gd" id="2_m3v43"]
[ext_resource type="Script" path="res://examples/forest-brawl/scripts/play-random-3d.gd" id="3_rcsmp"]
[ext_resource type="Script" path="res://examples/forest-brawl/scripts/brawler-weapon.gd" id="4_0hvdj"]
[ext_resource type="AudioStream" uid="uid://cih2i8xa2v2is" path="res://examples/forest-brawl/sounds/fall1.wav" id="4_mw5vb"]
[ext_resource type="PackedScene" uid="uid://8sru5hge6spx" path="res://examples/forest-brawl/scenes/bomb-projectile.tscn" id="5_a4qop"]
[ext_resource type="AudioStream" uid="uid://4oilc8k83mmt" path="res://examples/forest-brawl/sounds/fall2.wav" id="5_kqmf5"]
[ext_resource type="AudioStream" uid="uid://b03phi3tfl21k" path="res://examples/forest-brawl/sounds/whoosh.wav" id="6_gh8ps"]
[ext_resource type="AudioStream" uid="uid://cegpnj82f4gio" path="res://examples/forest-brawl/sounds/fall3.wav" id="6_jc44e"]
[ext_resource type="Script" path="res://addons/netfox/rollback/rollback-synchronizer.gd" id="7_cmfmx"]
[ext_resource type="PackedScene" uid="uid://fctd5hkxnf2y" path="res://examples/forest-brawl/models/player/bomber-guy.glb" id="7_ij3cr"]
[ext_resource type="Script" path="res://addons/netfox/tick-interpolator.gd" id="8_pj7o0"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_gdp4i"]
animation = &"Float"
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_qv2tk"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_rss6c"]
animation = &"Idle"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_7lmj4"]
animation = &"Run"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_7yjg4"]
animation = &"Strafe_L"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_v2fmc"]
animation = &"Strafe_R"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_tp0nc"]
animation = &"Backpedal"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_blhbt"]
blend_point_0/node = SubResource("AnimationNodeAnimation_rss6c")
blend_point_0/pos = Vector2(0, 0)
blend_point_1/node = SubResource("AnimationNodeAnimation_7lmj4")
blend_point_1/pos = Vector2(0, 1)
blend_point_2/node = SubResource("AnimationNodeAnimation_7yjg4")
blend_point_2/pos = Vector2(1, 0)
blend_point_3/node = SubResource("AnimationNodeAnimation_v2fmc")
blend_point_3/pos = Vector2(-1, 0)
blend_point_4/node = SubResource("AnimationNodeAnimation_tp0nc")
blend_point_4/pos = Vector2(0, -1)
min_space = Vector2(-4, -1)
max_space = Vector2(4, 1)
[sub_resource type="AnimationNodeTimeScale" id="AnimationNodeTimeScale_2k2qg"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_w05vo"]
animation = &"Throw"
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_byyqa"]
filter_enabled = true
filters = ["rig/Skeleton3D:DEF-breast.L", "rig/Skeleton3D:DEF-breast.R", "rig/Skeleton3D:DEF-forearm.L", "rig/Skeleton3D:DEF-forearm.L.001", "rig/Skeleton3D:DEF-forearm.R", "rig/Skeleton3D:DEF-forearm.R.001", "rig/Skeleton3D:DEF-hand.L", "rig/Skeleton3D:DEF-hand.R", "rig/Skeleton3D:DEF-shoulder.L", "rig/Skeleton3D:DEF-shoulder.R", "rig/Skeleton3D:DEF-spine", "rig/Skeleton3D:DEF-spine.001", "rig/Skeleton3D:DEF-spine.002", "rig/Skeleton3D:DEF-spine.003", "rig/Skeleton3D:DEF-spine.004", "rig/Skeleton3D:DEF-spine.005", "rig/Skeleton3D:DEF-spine.006", "rig/Skeleton3D:DEF-upper_arm.L", "rig/Skeleton3D:DEF-upper_arm.L.001", "rig/Skeleton3D:DEF-upper_arm.R", "rig/Skeleton3D:DEF-upper_arm.R.001"]
fadein_time = 0.2
fadeout_time = 0.2
[sub_resource type="AnimationNodeTimeScale" id="AnimationNodeTimeScale_ofns8"]
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_8to0y"]
graph_offset = Vector2(-680.797, -57.1155)
nodes/Float/node = SubResource("AnimationNodeBlend2_qv2tk")
nodes/Float/position = Vector2(-80, 0)
"nodes/Float Anim/node" = SubResource("AnimationNodeAnimation_gdp4i")
"nodes/Float Anim/position" = Vector2(-280, 120)
nodes/Move/node = SubResource("AnimationNodeBlendSpace2D_blhbt")
nodes/Move/position = Vector2(-480, -40)
nodes/MoveScale/node = SubResource("AnimationNodeTimeScale_2k2qg")
nodes/MoveScale/position = Vector2(-280, -40)
nodes/Throw/node = SubResource("AnimationNodeOneShot_byyqa")
nodes/Throw/position = Vector2(100, 20)
"nodes/Throw Anim/node" = SubResource("AnimationNodeAnimation_w05vo")
"nodes/Throw Anim/position" = Vector2(-280, 260)
nodes/ThrowScale/node = SubResource("AnimationNodeTimeScale_ofns8")
nodes/ThrowScale/position = Vector2(-100, 260)
nodes/output/position = Vector2(320, 80)
node_connections = [&"output", 0, &"Throw", &"Float", 0, &"MoveScale", &"Float", 1, &"Float Anim", &"MoveScale", 0, &"Move", &"Throw", 0, &"Float", &"Throw", 1, &"ThrowScale", &"ThrowScale", 0, &"Throw Anim"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_qgusj"]
radius = 0.25
height = 1.0
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_4cjl8"]
properties/0/path = NodePath(".:player_name")
properties/0/spawn = true
properties/0/sync = false
properties/0/watch = true
properties/1/path = NodePath(".:visible")
properties/1/spawn = true
properties/1/sync = false
properties/1/watch = true
[node name="Brawler" type="CharacterBody3D" groups=["Brawlers"]]
platform_on_leave = 2
platform_floor_layers = 0
script = ExtResource("1_np8na")
speed = 4.0
death_depth = 16.0
respawn_time = 8.0
[node name="bomber-guy" parent="." instance=ExtResource("7_ij3cr")]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5, 0)
[node name="AnimationTree" type="AnimationTree" parent="."]
tree_root = SubResource("AnimationNodeBlendTree_8to0y")
anim_player = NodePath("../bomber-guy/AnimationPlayer")
active = true
parameters/Float/blend_amount = 0.0
parameters/Move/blend_position = Vector2(0, 0)
parameters/MoveScale/scale = 1.0
parameters/Throw/active = false
parameters/Throw/internal_active = false
parameters/Throw/request = 0
parameters/ThrowScale/scale = 1.0
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CapsuleShape3D_qgusj")
[node name="Nametag" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
pixel_size = 0.0007
billboard = 1
fixed_size = true
text = "Nameless Brawler"
width = 128.0
[node name="Fall Sound" type="AudioStreamPlayer3D" parent="."]
script = ExtResource("3_rcsmp")
sounds = Array[AudioStream]([ExtResource("4_mw5vb"), ExtResource("5_kqmf5"), ExtResource("6_jc44e")])
[node name="Input" type="Node" parent="."]
script = ExtResource("2_m3v43")
[node name="Weapon" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
script = ExtResource("4_0hvdj")
projectile = ExtResource("5_a4qop")
fire_cooldown = 0.5
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="Weapon"]
stream = ExtResource("6_gh8ps")
[node name="RollbackSynchronizer" type="Node" parent="." node_paths=PackedStringArray("root")]
script = ExtResource("7_cmfmx")
root = NodePath("..")
enable_prediction = true
state_properties = Array[String]([":transform", ":velocity", ":speed", ":mass"])
full_state_interval = 24
diff_ack_interval = 4
input_properties = Array[String](["Input:movement", "Input:aim"])
enable_input_broadcast = false
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_config = SubResource("SceneReplicationConfig_4cjl8")
[node name="TickInterpolator" type="Node" parent="." node_paths=PackedStringArray("root")]
script = ExtResource("8_pj7o0")
root = NodePath("..")
properties = Array[String]([":transform"])