diff --git a/rrserver/packets/SRB2/__init__.py b/rrserver/packets/SRB2/__init__.py
index cde3b8880e965eb2c3420ccd23c4fece8df7c7d7..aacc8fe6b8237c62c324b621162c4e46bd39bc9c 100644
--- a/rrserver/packets/SRB2/__init__.py
+++ b/rrserver/packets/SRB2/__init__.py
@@ -1,6 +1,6 @@
-# Copyright (C) 2024, James R.
+# Copyright (C) 2025, James R.
 # GNU General Public License, version 2 (see the 'licenses/gpl-2.0.txt' file)
 
 from rrserver.packets import _lib
 
-by_modversion = _lib.VersionMap(__name__, [51])
+by_modversion = _lib.VersionMap(__name__, [51, 55])
diff --git a/rrserver/packets/SRB2/v51/__init__.py b/rrserver/packets/SRB2/v51/__init__.py
index 9ce099d2c40dea578ba95ea7d2321056cc2e5005..c19a6ce9b9d6f070af4bf581b555931809287336 100644
--- a/rrserver/packets/SRB2/v51/__init__.py
+++ b/rrserver/packets/SRB2/v51/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2024, James R.
+# Copyright (C) 2025, James R.
 # Copyright (C) 1999-2023, Sonic Team Junior
 # Copyright (C) 1998-2000, DooM Legacy Team
 # GNU General Public License, version 2 (see the 'licenses/gpl-2.0.txt' file)
@@ -38,16 +38,6 @@ FileNeeded = Struct(
 	),
 )
 
-# netcode/server_connection.c, SV_SendServerInfo
-# g_game.c, G_BuildMapTitle
-def _get_map_title(ctx):
-	s = ctx._map_title_raw
-	if ctx._map_zone:
-		s += ' ZONE'
-	if ctx._map_act:
-		s += f' {ctx._map_act}'
-	return s
-
 # netcode/protocol.h, serverinfo_pak
 ServerInfo = Struct(
 	#
@@ -114,7 +104,7 @@ ServerInfo = Struct(
 	# Read-only fields
 	#
 	'dedicated' / Computed(this._flags.dedicated),
-	'map_title' / Computed(_get_map_title),
+	'map_title' / Computed(get_map_title),
 	'_next_filesneeded' / Computed(
 		lambda ctx: ctx._num_files
 		if ctx._flags.lotsofaddons
diff --git a/rrserver/packets/SRB2/v51/_adapters.py b/rrserver/packets/SRB2/v51/_adapters.py
index 8f64b265b5913e2b3b1db79502c567946e150bc3..339be4cfcdec3abd1f9924947db7945ed0c0422e 100644
--- a/rrserver/packets/SRB2/v51/_adapters.py
+++ b/rrserver/packets/SRB2/v51/_adapters.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2024, James R.
+# Copyright (C) 2025, James R.
 # GNU General Public License, version 2 (see the 'licenses/gpl-2.0.txt' file)
 
 from rrserver.packets._construct import *
@@ -15,3 +15,13 @@ class VersionAdapter(Adapter):
 			'major_minor': (int(ver[0]) * 100) + int(ver[1]),
 			'patch': ver[2],
 		}
+
+# netcode/server_connection.c, SV_SendServerInfo
+# g_game.c, G_BuildMapTitle
+def get_map_title(ctx):
+	s = ctx._map_title_raw
+	if ctx._map_zone:
+		s += ' ZONE'
+	if ctx._map_act:
+		s += f' {ctx._map_act}'
+	return s
diff --git a/rrserver/packets/SRB2/v55/__init__.py b/rrserver/packets/SRB2/v55/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..ad6cdfeb5aeacd728b309f38b345ad124fcf82d2
--- /dev/null
+++ b/rrserver/packets/SRB2/v55/__init__.py
@@ -0,0 +1,88 @@
+# Copyright (C) 2025, James R.
+# Copyright (C) 1999-2024, Sonic Team Junior
+# Copyright (C) 1998-2000, DooM Legacy Team
+# GNU General Public License, version 2 (see the 'licenses/gpl-2.0.txt' file)
+
+from rrserver.packets._construct import *
+from rrserver.packets.SRB2.v51 import *
+from rrserver.packets.SRB2.v51 import __all__, FileNeeded, _base, _packet_switch, Summary
+from rrserver.packets.SRB2.v51._adapters import *
+
+# netcode/protocol.h, serverinfo_pak
+ServerInfo = Struct(
+	#
+	# Packet identity
+	#
+	Const(b'\xFF'),
+	'_packet_version' / Const(5, u8),
+	'_application' / Const(
+		'SRB2',
+		PaddedString(16, 'ascii')
+	),
+
+	#
+	# Server version
+	#
+	'version' / VersionAdapter(
+		Struct(
+			'major_minor' / u8,
+			'patch' / u8,
+		),
+	),
+
+	#
+	# Player count
+	#
+	'num_humans' / u8,
+	'max_connections' / u8,
+	'joinable_state' / Enum(
+		u8,
+		joinable = 0,
+		joins_disabled = 1,
+		full = 2,
+		banned = 3,
+	),
+
+	#
+	# Gameplay
+	#
+	'gametype' / PaddedString(24, 'ascii'),
+	'modified' / Flag,
+	'cheats' / Flag,
+	'_flags' / FlagsEnum(
+		u8,
+		dedicated = 0x40,
+		lotsofaddons = 0x20,
+	),
+	'_num_files' / u8,
+	'_askinfo_time' / u32,
+	'map_time' / TicrateAdapter(u32),
+	'server_name' / PrettyNameAdapter(PaddedCString(32)),
+
+	# netcode/server_connection.c, SV_SendServerInfo
+	# This is an 8-byte field, however only 7 bytes are
+	# ever written to it.
+	'map_lump' / PaddedString(7, 'ascii'), Padding(1),
+
+	'_map_title_raw' / PaddedString(33, 'ascii'),
+	'map_md5' / HexBytes(16),
+	'_map_act' / u8,
+	'_map_zone' / Flag,
+	'http_source' / PaddedString(256, 'utf-8'),
+	'files' / FileNeeded[this._num_files],
+
+	#
+	# Read-only fields
+	#
+	'dedicated' / Computed(this._flags.dedicated),
+	'map_title' / Computed(get_map_title),
+	'_next_filesneeded' / Computed(
+		lambda ctx: ctx._num_files
+		if ctx._flags.lotsofaddons
+		else None
+	),
+)
+
+_packet_switch['ServerInfo'] = (13, ServerInfo)
+
+Packet = _base.make_packet(_packet_switch)
diff --git a/rrserver/packets/SRB2/v55/flow.py b/rrserver/packets/SRB2/v55/flow.py
new file mode 100644
index 0000000000000000000000000000000000000000..f28fb83a8cbc0d2a671292f638bcd83ac6b6fd22
--- /dev/null
+++ b/rrserver/packets/SRB2/v55/flow.py
@@ -0,0 +1,5 @@
+# Copyright (C) 2025, James R.
+# GNU General Public License, version 2 (see the 'licenses/gpl-2.0.txt' file)
+
+from rrserver.packets.SRB2.v51.flow import *
+from rrserver.packets.SRB2.v51.flow import __all__