Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
Skynet 启发的 Lua 优先游戏服务器运行时
Translation pending
GamesC++ · CMakeGitHub @cuihairuOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Shield is being redesigned as a single-node-first, actor-based, Lua-first game server runtime.
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Shield is an actively refactored single-node-first, Skynet-inspired,
actor-based, Lua-first game server runtime.
The per-module suites under tests/coverage/ keep src/ at 98%+ line
coverage (measured with gcc --coverage + gcovr). The CI Coverage job
reruns them on every push, uploads the report to
Codecov, and fails when coverage
drops below 97%:Read the full README ↗English | 简体中文
Shield is a single-node-first, Skynet-inspired,
actor-based, Lua-first game server runtime (roadmap Phases 0-4 are landed;
Phase 5 capabilities are partly implemented, with operational features still
compiled in shield_bootstrap while the shield_ops CMake target is empty).
In a local GCC --coverage run with gcovr 8.6, src/ measured 99% line
coverage (17,130/17,131 lines). The command below checks only src/; that
run measured 58.1% branch and 99.9% function coverage, so its 100% branch and
function thresholds did not pass. CI uses a different configuration: it runs
all tests, includes include/shield/, and excludes unreachable and throw
branches. The analyzed local optional-modules-enabled build measured 99.3%
branch and 99.1% function coverage with those CI parameters; those results also
miss the 100% thresholds and do not establish that the CI gate passed. The CI
Coverage job runs on main pushes and pull requests, runs all tests, and uploads
its report to Codecov. The badge above
reports the uploaded Codecov status; it is not a separate local measurement.
The commands below show the README-local suite and gcovr configuration, which
differs from CI as described above:
cmake -S . -B build-cov -G Ninja \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DCMAKE_BUILD_TYPE=Debug -DSHIELD_BUILD_TESTS=ON \
-DSHIELD_BUILD_EXAMPLES=OFF -DSHIELD_ENABLE_COVERAGE=ON
cmake --build build-cov
ctest --test-dir build-cov -L coverage --output-on-failure
cd build-cov && gcovr -r . --exclude-directories '^\.(?!$)' --filter '\.\./src/' --fail-under-line 98 --fail-under-branch 100 --fail-under-function 100
This repository is not a stable release yet, but the minimal single-node runtime
path is runnable: configuration loading, Lua service startup, local service
registry, send / call, timers, TCP listener startup validation, and plugin
host discovery are covered by smoke tests.
The fastest path (with environment preflight, ~10 minutes after the first dependency build — see docs/quickstart.md for the full linear guide):
./build.sh release # preflight + configure + build (vcpkg deps: 20-40 min first time)
./build/bin/shield --config config/app.yaml # starts the echo listener on :7900
python3 scripts/client_demo.py # in another terminal: one RPC round trip
./scripts/new_project.sh ~/my_game # scaffold your own minimal project
The long way, with the test suite:
cmake -S . -B build \
-G Ninja \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_SCAN_FOR_MODULES=OFF \
-DSHIELD_BUILD_TESTS=ON \
-DSHIELD_BUILD_EXAMPLES=ON
cmake --build build --config Release
ctest --test-dir build --build-config Release --output-on-failure
Prerequisites: CMake 3.30+, a C++23 compiler (gcc 13 / clang 17 / MSVC
19.38+), vcpkg via VCPKG_ROOT (Ninja recommended on Linux and macOS).
./build.sh checks all of these and prints a one-line fix for anything
missing.
Config validation without booting:
./build/bin/shield --check-config --config config/app.yaml
./build/bin/shield --check-config --config examples/hello_world/config/app.yaml
The default config/app.yaml intentionally declares no plugin instances, so a
fresh checkout can boot without provider DLLs; it does declare an observable
echo service (TCP :7900) so a fresh run has something to talk to. For an
optional SQLite-backed example, build with
-DSHIELD_BUILD_DB_PLUGIN_SQLITE=ON and use config/app-with-sqlite.yaml.
Authentication/token semantics belong to the Lua business layer, not C++
plugins: scripts/lib/jwt.lua (HS256 and EdDSA signing with JWKS key sets
over the shield.crypto primitives, API table in docs/lua-api.md) is the
reference implementation and plugins/auth_jwt is deprecated pending
removal.
The plugin system (manifest-first discovery, explicit instances + bindings,
stable C ABI) is specified in docs/plugin-system.md, including the matrix of
all 16 official plugin packages. To run the full stack in one process — a Lua
business script writing to SQLite plus live /health and Prometheus
endpoints — see examples/kickstart/ (three commands, ~10 minutes). To start
a new plugin package, run tools/new_plugin.sh <name>: it scaffolds the
manifest, CMake wiring, a v1 ABI stub, and a passing lifecycle test.
shield.* API.shield_core boundary.Shield core does not provide:
These capabilities may be built by users or evaluated later as optional extensions. They are not part of the current core contract.
shield.event is a deliberately small Lua helper for decoupling modules inside
one service VM. It is not a mailbox, not serialized, not visible across
services or VMs, and not used for application lifecycle events.
shield_core is intentionally narrow. It only owns the actor/service semantics
wrapped around CAF:
| Core piece | Responsibility |
|---|---|
| service lifecycle | create, name, stop, and inspect services |
| message semantics | send / call routing and timeout behavior |
| coroutine scheduling | suspend and resume Lua-facing calls without blocking runtime threads |
| timer semantics | timeout primitives attached to service execution |
| CAF adapter | keep CAF hidden behind Shield service handles |
First-party runtime modules are built around that core, but are not part of the core semantics:
| Module | Responsibility |
|---|---|
shield_base | Shared value types such as Result, Error, ByteBuffer, time, and IDs |
shield_lua | Lua VM management and shield.* bindings |
shield_net | Client connections (TCP in Phase 1; UDP/KCP/WebSocket deferred), Session management |
shield_transport | Protocol pipeline (envelope framing, body codecs, route validation) and RPC descriptor table |
shield_plugin | Plugin manifest/catalog, instances, bindings, C ABI, and plugin Lua registration |
shield_config | YAML configuration loading |
shield_log | Runtime logging |
shield_bootstrap | Compose selected modules into a runnable server |
Optional official extensions live outside the minimal main path:
| Module | Responsibility |
|---|---|
shield_cluster | Cross-process/machine communication, service discovery, node heartbeat |
shield_global | Distributed data, locks, queue/rank/rate limiting |
shield_player | PlayerSession, PlayerRef, login/logout, reconnect, player-ready lifecycle |
shield_server | Server state, maintenance mode, shutdown coordination |
shield_ops | Diagnostics, metrics, console, profile |
local M = {}
function M.on_init()
shield.log.info("echo started")
end
function M.on_shutdown(ctx)
shield.log.info("echo draining: " .. ctx.reason)
end
function M.ping()
local src = shield.sender()
shield.send(src, "pong", { time = shield.now() })
end
return M
Player/avatar/client lifecycle is not a core service hook. When enabled,
shield_player owns PlayerSession, PlayerRef, player-ready state, login,
disconnect, reconnect, logout, and save hooks. avatar or character remains
game data attached to a player session, not a Shield core object.
Authoritative design contracts:
shield.* user API.Supplemental documents such as CMake refactor notes, ops design, schema drafts,
and historical refactor summaries are under docs/. If they conflict with the
authoritative contracts above, the authoritative contracts win.
Roadmap Phases 0-4 are landed; Phase 5 capabilities are partly implemented. The runtime can load config, start Lua module-table services, validate TCP listener startup, run local registry and messaging smoke tests, and initialize the plugin host without linking provider libraries into the core executable.
Some documented APIs remain target contracts or partial implementations. The
hello-world TCP gateway verifies listener startup and gateway event routing;
the runtime also registers read-only shd.ClientContext and shd.ClientRef
Lua userdata for client identity. These userdata expose selected identity
fields and binding methods, while the socket and internal SessionBinding
remain in C++.
The repository includes a multi-stage Dockerfile for production
image builds. When building from a git checkout, pass the current commit hash as
a build argument so shield --version inside the image keeps the source
revision:
docker build \
--build-arg SHIELD_GIT_COMMIT_HASH="$(git rev-parse HEAD)" \
-t shield:latest .
If the build runs outside a git checkout, the image falls back to Unknown for
the embedded commit hash.