diff --git a/CMakeLists.txt b/CMakeLists.txt
index 10cf0d022f51d8bdafdc0334ec3732c0780b236c..3dfd8e6f9b01d0356d12b26c1c8abb65d0f727e2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -134,7 +134,6 @@ if("${SRB2_CONFIG_SYSTEM_LIBRARIES}")
 	find_package(CURL REQUIRED)
 	find_package(OPENMPT REQUIRED)
 	find_package(GME REQUIRED)
-	find_package(DiscordRPC REQUIRED)
 endif()
 
 if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
diff --git a/cmake/Modules/FindDiscordRPC.cmake b/cmake/Modules/FindDiscordRPC.cmake
deleted file mode 100644
index 2d3c987c168edcec5c7e46252a79c1aa9bd7ec2f..0000000000000000000000000000000000000000
--- a/cmake/Modules/FindDiscordRPC.cmake
+++ /dev/null
@@ -1,33 +0,0 @@
-include(LibFindMacros)
-
-libfind_pkg_check_modules(DISCORDRPC_PKGCONF DISCORDRPC)
-
-find_path(DISCORDRPC_INCLUDE_DIR
-	NAMES discord_rpc.h
-	PATHS
-		${DISCORDRPC_PKGCONF_INCLUDE_DIRS}
-		"/usr/include"
-		"/usr/local/include"
-)
-
-find_library(DISCORDRPC_LIBRARY
-	NAMES discord-rpc
-	PATHS
-		${DISCORDRPC_PKGCONF_LIBRARY_DIRS}
-		"/usr/lib"
-		"/usr/local/lib"
-)
-
-set(DISCORDRPC_PROCESS_INCLUDES DISCORDRPC_INCLUDE_DIR)
-set(DISCORDRPC_PROCESS_LIBS DISCORDRPC_LIBRARY)
-libfind_process(DISCORDRPC)
-
-if(DISCORDRPC_FOUND AND NOT TARGET DiscordRPC::DiscordRPC)
-	add_library(DiscordRPC::DiscordRPC UNKNOWN IMPORTED)
-	set_target_properties(
-		DiscordRPC::DiscordRPC
-		PROPERTIES
-		IMPORTED_LOCATION "${DISCORDRPC_LIBRARY}"
-		INTERFACE_INCLUDE_DIRECTORIES "${DISCORDRPC_INCLUDE_DIR}"
-	)
-endif()
diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt
index ce5f585318917d44ba1651360cae8d296badf093..142bd2491c5591b67277f97ec77479b4e16e0071 100644
--- a/thirdparty/CMakeLists.txt
+++ b/thirdparty/CMakeLists.txt
@@ -88,7 +88,7 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
 			zutil.c
 		)
 		list(TRANSFORM ZLIB_SRCS PREPEND "${ZLIB_SOURCE_DIR}/")
-		
+
 		configure_file("${ZLIB_SOURCE_DIR}/zlib.pc.cmakein" "${ZLIB_BINARY_DIR}/zlib.pc" @ONLY)
 		configure_file("${ZLIB_SOURCE_DIR}/zconf.h.cmakein" "${ZLIB_BINARY_DIR}/include/zconf.h" @ONLY)
 		configure_file("${ZLIB_SOURCE_DIR}/zlib.h" "${ZLIB_BINARY_DIR}/include/zlib.h" @ONLY)
@@ -123,7 +123,7 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
 
 			png.h
 			pngconf.h
-			
+
 			pngpriv.h
 			pngdebug.h
 			pnginfo.h
@@ -472,7 +472,7 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
 			soundlib/OggStream.h
 			soundlib/Loaders.h
 			soundlib/BitReader.h
-			soundlib/opal.h			
+			soundlib/opal.h
 
 			sounddsp/AGC.cpp
 			sounddsp/EQ.cpp
@@ -501,7 +501,7 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
 		endif()
 		target_compile_features(openmpt PRIVATE cxx_std_11)
 		target_compile_definitions(openmpt PRIVATE -DLIBOPENMPT_BUILD)
-		
+
 		target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/common")
 		target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/src")
 		target_include_directories(openmpt PRIVATE "${openmpt_SOURCE_DIR}/include")
@@ -528,17 +528,81 @@ if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
 	target_link_libraries(gme PRIVATE ZLIB::ZLIB)
 endif()
 
-if(NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}")
-	CPMAddPackage(
-		NAME DiscordRPC
-		VERSION 3.4.0
-		URL "https://github.com/discord/discord-rpc/archive/refs/tags/v3.4.0.zip"
-		EXCLUDE_FROM_ALL ON
-		OPTIONS
-			"BUILD_EXAMPLES OFF"
+CPMAddPackage(
+	NAME RapidJSON
+	VERSION 1.1.0
+	URL "https://github.com/Tencent/rapidjson/archive/v1.1.0.tar.gz"
+	EXCLUDE_FROM_ALL ON
+	DOWNLOAD_ONLY ON
+)
+if(RapidJSON_ADDED)
+	add_library(RapidJSON INTERFACE)
+	add_library(RapidJSON::RapidJSON ALIAS RapidJSON)
+	target_include_directories(RapidJSON INTERFACE "${RapidJSON_SOURCE_DIR}/include")
+endif()
+
+CPMAddPackage(
+	NAME DiscordRPC
+	VERSION 3.4.0
+	URL "https://github.com/discord/discord-rpc/archive/refs/tags/v3.4.0.zip"
+	EXCLUDE_FROM_ALL ON
+	DOWNLOAD_ONLY ON
+)
+
+if(DiscordRPC_ADDED)
+	set(DiscordRPC_SOURCES
+		include/discord_rpc.h
+		include/discord_register.h
+
+		src/discord_rpc.cpp
+		src/rpc_connection.h
+		src/rpc_connection.cpp
+		src/serialization.h
+		src/serialization.cpp
+		src/connection.h
+		src/backoff.h
+		src/msg_queue.h
 	)
-	target_include_directories(discord-rpc INTERFACE "${DiscordRPC_SOURCE_DIR}/include")
+	list(TRANSFORM DiscordRPC_SOURCES PREPEND "${DiscordRPC_SOURCE_DIR}/")
+
+	# Discord RPC is always statically linked because it's tiny.
+	add_library(discord-rpc STATIC ${DiscordRPC_SOURCES})
 	add_library(DiscordRPC::DiscordRPC ALIAS discord-rpc)
+
+	target_include_directories(discord-rpc PUBLIC "${DiscordRPC_SOURCE_DIR}/include")
+	target_compile_features(discord-rpc PUBLIC cxx_std_11)
+	target_link_libraries(discord-rpc PRIVATE RapidJSON::RapidJSON)
+
+	# Platform-specific connection and register impls
+	if(WIN32)
+		target_compile_definitions(discord-rpc PUBLIC -DDISCORD_WINDOWS)
+		target_sources(discord-rpc PRIVATE
+			"${DiscordRPC_SOURCE_DIR}/src/connection_win.cpp"
+			"${DiscordRPC_SOURCE_DIR}/src/discord_register_win.cpp"
+		)
+		target_link_libraries(discord-rpc PRIVATE psapi advapi32)
+	endif()
+
+	if(UNIX)
+		target_sources(discord-rpc PRIVATE
+			"${DiscordRPC_SOURCE_DIR}/src/connection_unix.cpp"
+		)
+
+		if(APPLE)
+			target_compile_definitions(discord-rpc PUBLIC -DDISCORD_OSX)
+			target_sources(discord-rpc PRIVATE
+				"${DiscordRPC_SOURCE_DIR}/src/discord_register_osx.m"
+			)
+			target_link_libraries(discord-rpc PUBLIC "-framework AppKit")
+		endif()
+
+		if(UNIX AND NOT APPLE)
+			target_compile_definitions(discord-rpc PUBLIC -DDISCORD_LINUX)
+			target_sources(discord-rpc PRIVATE
+				"${DiscordRPC_SOURCE_DIR}/src/discord_register_linux.cpp"
+			)
+		endif()
+	endif()
 endif()
 
 add_subdirectory(tcbrindle_span)