cloudwu/skynet: the Lua actor framework behind Chinese game servers
A lightweight online game framework
At a glance
- What is it?
- Skynet is a C and Lua framework for building multi-user services on the actor model, with a build that pulls in jemalloc and a modified Lua 5.5.0. It is a server runtime, not a library you drop into an existing app.
- Who is it for?
- Adopt cloudwu/skynet if you are building a stateful, long-running multiplayer service in Lua and you accept that the runtime owns your process model: every service is an actor, every actor is a Lua state, and the C core schedules them. Do not adopt it if you want a library to embed in an existing Python, Go or Node process, or if you need English API reference documentation, because the README points at a wiki and a Chinese-language FAQ rather than a generated reference.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- cloudwu/skynet14,197 ★ · +45
| Repository | 2026-09-22 | 2026-11-13 |
|---|---|---|
| cloudwu/skynet | 14.2k | 14.2k |
45 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What cloudwu/skynet solves, and who it is for
A multiplayer game server has an awkward shape. It holds thousands of long-lived stateful sessions, it must run timers and network I/O without blocking, and it must let different parts of the game talk to each other without a shared-memory free-for-all. Skynet's answer is the actor model: the README calls it a "multi-user Lua framework supporting the actor model, often used in games". Each actor is a service, each service runs in its own Lua state, and services exchange messages rather than touching each other's data. The README states the framework is heavily used in the Chinese game industry and is spreading to other industries and to English-centric developers, and that contributors mostly speak English, so questions in the Discussion area or issues are workable. If you are writing a turn-based or real-time backend where a single process must host many isolated game rooms, this is the shape you want. If you are writing a stateless HTTP API, it is heavier than you need.
Services, Lua states and the C scheduler
The repository layout tells you where the mechanism lives. skynet-src/ holds the C core: skynet_start.c, skynet_server.c, skynet_mq.c for message queues, skynet_timer.c for timers, skynet_socket.c and socket_server.c for networking, skynet_handle.c for service registration, and skynet_monitor.c for detecting services that block too long. service-src/ builds the C services named in the Makefile: snlua, logger, gate and harbor. snlua is the one that matters most, because it is the service that hosts a Lua state. lualib-src/ builds the Lua-facing C libraries, including lua-skynet.c, lua-socket.c, lua-cluster.c, lua-sharedata.c, lua-sharetable.c and lua-stm.c, which is how Lua code reaches the scheduler, sockets, cross-node messaging and shared data structures. lualib/ holds the Lua side. The data flow is therefore: a message arrives on a socket, the gate service accepts it, the core dispatches a message to the target service's queue, and the snlua service runs the corresponding Lua function. Because each service is a separate Lua state, a crash or a blocking loop in one service does not corrupt another's globals, which is the whole point. The Makefile also shows a sharedata and sharetable pair, so read-only data can be shared between states instead of copied.
How to install cloudwu/skynet and run a first node
The README gives the build steps directly. On Linux you need autoconf installed first, because jemalloc is built from a git submodule and its autogen.sh is invoked by the Makefile. The Makefile confirms this: the jemalloc target runs ./autogen.sh --disable-cxx --with-jemalloc-prefix=je_ --enable-prof inside 3rd/jemalloc, and the 3rd/jemalloc/autogen.sh rule is git submodule update --init. So clone with submodules in mind.
git clone https://github.com/cloudwu/skynet.git
cd skynet
make 'PLATFORM' # PLATFORM can be linux, macosx, freebsd, openbsd nowThe README also offers the environment-variable form, which is what the Makefile's platform.mk reads:
export PLAT=linux
makeOn FreeBSD the README says to use gmake instead of make. After a successful build you should have a skynet binary in the build path, plus .so files under cservice/ and luaclib/ for the services and C libraries listed in the Makefile. To see it run, the README gives a two-console test. The first console starts a node with the example config, described in the README as launching the first skynet node (Gate server) and a skynet-master, with a standalone option visible in the config file itself:
./skynet examples/configThe second console runs the bundled client and lets you type input:
./3rd/lua/lua examples/client.luaTyping hello in the client console is the README's own suggestion. The examples/ directory is the real first stop after that: config, config.c1, config.c2, config.login, config.mysql, config.mongodb and matching main*.lua files show how a node is assembled, and cluster1.lua and cluster2.lua show two nodes talking to each other.
The Lua version is modified, and that is a real constraint
The README is explicit that Skynet uses a modified version of Lua 5.5.0, hosted at ejoy/lua on the skynet55 branch, chosen for multiple Lua states. That modification is not cosmetic. The README ties it to running multiple Lua states, and it means the Lua you get from your distribution is not the Lua Skynet ships with. The README does say official Lua versions can also be used as long as the Makefile is edited, so you are not locked in, but the default path is a fork. Two consequences follow. First, any Lua C module you bring in must compile against the same headers, and the Makefile points LUA_INC at 3rd/lua by default. Second, if you depend on a Lua patch or a version-specific behaviour from upstream 5.4 or 5.5, you need to confirm it exists in this fork rather than assuming. This is a trade-off the project made deliberately, and it is the single most likely source of surprise for a team coming from stock Lua.
Documentation lives in the wiki, not in the repository
The README does not document the API. It says to read the Wiki for documents, notes that the wiki is written in both English and Chinese, and points to a wiki FAQ that is in Chinese only, suggesting a translator. The repository itself contains no generated reference for the functions exposed by lua-skynet.c, lua-socket.c or lua-cluster.c. For an engineer deciding whether to adopt this, that is the main cost: you will read C source to learn exact semantics. The presence of examples/ mitigates this, since the config and main files are working configurations rather than fragments, and the test/ directory exists as well. But if your team's adoption criteria include a complete English API reference, this project does not meet it today. The README does not document rollback or upgrade procedures between releases either, so version jumps are something you plan yourself.
When Skynet is the wrong tool
Skynet is a process runtime. You start a node, it reads a config, and it owns the process. That makes it a poor fit for embedding. If you have an existing Go or Node service and you want to add a scripting layer inside it, Skynet will not slot in; you would be running a second process and talking to it over a socket, at which point you should ask why you are using it at all. It is also a poor fit for request-response workloads where each request is independent and short, because the actor machinery, the message queues and the per-service Lua state are overhead you would not recover. And it is a poor fit for a team that cannot read C when something goes wrong in skynet_server.c or skynet_mq.c, since the documentation will not walk you through the internals. The build itself has a friction point: jemalloc is pulled as a submodule and autoconf is required for it, though the Makefile runs git submodule update --init itself when 3rd/jemalloc/autogen.sh is missing.
Alternatives and how they differ in approach
The closest comparison in the same language ecosystem is writing your own actor layer on top of stock Lua plus a socket library, which keeps you on upstream Lua and gives you full control, but leaves you implementing message queues, service registration and the monitor that detects a blocked service, all of which Skynet already builds in skynet-src/. The other direction is a general-purpose actor runtime in another language, such as an Erlang or Elixir system, where the actor model is the language's native concurrency primitive rather than a layer over Lua states. That approach gives you decades of tooling around supervision trees and hot code loading, but it means giving up Lua for game logic and retraining anyone who writes content scripts. Skynet's specific position is that game logic stays in Lua while the scheduler, networking and memory management stay in C, and the modified Lua fork exists to make the many-states model cheap. If neither of those trade-offs appeals, the honest answer is that you want a different concurrency model, not a different framework.
Maintenance, licensing and upgrade cost
The repository is not archived. The last push was on 2026-09-29, so the codebase is being touched currently. Releases are infrequent rather than continuous: v1.6.0 in November 2022, v1.7.0 in November 2023, v1.8.0 in January 2025. That cadence matters for planning. If you track master you get the recent fixes; if you track tags you wait roughly a year between versioned drops. The LICENSE file is present at the repository root and the project is MIT, which is permissive and places few obligations on how you distribute a server binary, though you should read the file itself rather than take a summary as sufficient. The upgrade cost is dominated by two things: the modified Lua fork, which can change under you between releases, and the absence of documented migration notes. HISTORY.md at the root is where change history lives, so read it before moving a production node from one tag to the next.
Editorial conclusion
Adopt cloudwu/skynet if you are building a stateful, long-running multiplayer service in Lua and you accept that the runtime owns your process model: every service is an actor, every actor is a Lua state, and the C core schedules them. Do not adopt it if you want a library to embed in an existing Python, Go or Node process, or if you need English API reference documentation, because the README points at a wiki and a Chinese-language FAQ rather than a generated reference. Before committing, verify the build on your target platform with make linux (or your PLATFORM value), confirm that jemalloc builds through the git submodule, and read examples/config to see which services a node starts by default, since that file is the real entry point rather than any doc.
Frequently asked questions
How do I install cloudwu/skynet on Linux?
Install autoconf first, because jemalloc is built from a submodule via its autogen.sh. Then clone the repository and run make 'PLATFORM' with a platform such as linux, macosx, freebsd or openbsd, or export PLAT=linux and run make.
How do I use cloudwu/skynet after building it?
The README's test runs ./skynet examples/config in one console to launch a node and a skynet-master, then runs ./3rd/lua/lua examples/client.lua in another console and lets you type input such as hello. The examples/ directory holds the config and main files that show how a node is assembled.
What is cloudwu/skynet?
It is described in its README as a multi-user Lua framework supporting the actor model, often used in games, and the README states it is heavily used in the Chinese game industry. The C core lives in skynet-src/ and the Lua-facing libraries in lualib-src/.
How do I set up a cloudwu/skynet node?
A node is started by passing a config file to the skynet binary, as in ./skynet examples/config. The examples/ directory provides several starting points, including config, config.c1, config.c2, config.login, config.mysql and config.mongodb, each paired with a main file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/cloudwu-skynet)Star history chart for your README
[](https://hysenlabs.com/projects/cloudwu-skynet)Was this useful?