v0.5.5 · AGPL-3.0

Query any game server.
Zero dependencies.

GameQuery reads player counts, map, hostname, ping and rules from one server or hundreds at once. It ships as two parallel libraries that stay in lockstep — PHP and Node/TypeScript — with the same protocols, the same API, and the same results.

PHP 8.1+ Node 18+ 0 runtime deps ESM + CJS Published with provenance
53
Games mapped
23
Protocol families
33
Registered keys
0
Dependencies

Try it on a real server

Pick a game, paste an address, and this page runs the actual library against it — same code you'd install.

Uses each game's default query port unless you set one.
Public demo, so it's deliberately fenced in. Queries are rate limited per visitor, private and link-local address ranges are refused, and the two games needing a credential (Palworld, Terraria) are disabled here — a demo has no business handling your admin password. Self-hosting has none of these limits.

Built for real fleets

Everything here exists because a production Discord bot polls thousands of servers with it.

Concurrent by design

One event loop drives every query at once, so polling 25 servers takes about as long as the single slowest one — not the sum of all of them.

🛡️ Never throws when offline

Every query returns a Result. Unreachable servers come back with online = false and a typed ErrorCode — no try/catch gymnastics.

🔗 Two ports, one behaviour

The PHP and Node libraries change together in the same commit, with matching tests and an automated parity check that fails CI on drift.

🎯 Normalized results

name(), map(), players(), maxPlayers(), playerNames() read the right field regardless of protocol, and stay stable across releases.

🌊 Streaming results

processStream() yields each result the moment its server answers — an async iterator in Node, a Generator in PHP.

🧪 Fuzzed parsers

Every parser is thrown 132,000 malformed buffers in CI. A hostile or broken server reply cannot crash your process.

Quick start

Install, then query. Both ports expose the same surface.

PHP · Composer
composer require t0xicvybez/gamequery
Node · npm
npm install @t0xicvybez/gamequery
import { GameQuery } from '@t0xicvybez/gamequery';

// One server, by protocol
const r = await GameQuery.queryOne('source', '1.2.3.4:27015');
console.log(r.online, r.name(), r.players(), r.maxPlayers());

// Or by game id — protocol + port resolved for you
const rust = await GameQuery.queryGame('rust', 'my-server.com');

// A whole fleet, concurrently
const results = await new GameQuery(2000, 1)
  .addGame('cs2', 'a.example.com')
  .addGame('minecraft', 'b.example.com')
  .addServer('source', 'c.example.com:28015')
  .process();

for (const s of results) {
  console.log(s.server.label(), s.online ? s.players() : s.errorCode);
}
Query port ≠ join port. Some games answer status queries on a different port than players connect on — Killing Floor 2 is queried on 27015 but joined on 7777. The game database exposes both, so you can show a correct connect address without ever pointing a query at it.

Protocol coverage

23 families behind 33 registered keys. Pass a key to addServer(), or skip it entirely and use a game id.

KeyFamily / gamesTransport
source (source-players, source-full)Source / A2S — CS2, TF2, Rust, ARK, GMod, SCUM, most Steamworks gamesUDP
minecraft (minecraft-ping)Minecraft: Java Edition SLP (-ping adds 0x01 ping latency)TCP
minecraft-legacyMinecraft: Java Edition (≤1.6 legacy ping)TCP
minecraft-queryMinecraft: Java enable-query (full player list)UDP
bedrock (minecraft-bedrock)Minecraft: Bedrock Edition (RakNet)UDP
fivem (fivem-info)FiveM / CFX (GTA V multiplayer)TCP/HTTP
palworld (palworld-info)Palworld REST APITCP/HTTP
quakeworld (quake1)QuakeWorld / Quake 1UDP
quake2id Tech 2 / Quake 2UDP
quake3id Tech 3 — Quake 3, CoD 1/2/4, OpenArena, Xonotic, ETUDP
gamespy1GameSpy 1 — Unreal, early UT, Tribes 2, older titlesUDP
gamespy2GameSpy 2 — Battlefield 1942/Vietnam, Halo, UT2004UDP
gamespy3GameSpy 3 — Battlefield 2, Crysis, UT3, later titlesUDP
unreal2 (unreal2-info)Unreal Engine 2 — UT2003/2004, Killing FloorUDP
doom3id Tech 4 — Doom 3, Quake 4, ET: Quake Wars, PreyUDP
aseAll-Seeing Eye — Multi Theft Auto (MTA:SA)UDP
mumbleMumble / Murmur voice serversUDP
teamspeak3TeamSpeak 3 / TeaSpeak (ServerQuery)TCP
frostbiteBattlefield 3/4, Bad Company 2, Medal of HonorTCP
assettocorsaAssetto Corsa (HTTP /INFO)TCP/HTTP
terrariaTerraria via TShock RESTTCP/HTTP
samp (openmp, samp-info)SA-MP / open.mp (GTA: San Andreas)UDP
satisfactorySatisfactory Lightweight Query (name/state/build)UDP

Game database

53 games map straight to a protocol and port, so queryGame('rust', host) just works. Amber marks a different join port.