ultimate-game-server

module
v1.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: MIT

README

Ultimate Game Engine — Game Server Framework

Ultimate Game Engine (UGE) is a distributed, high-performance, authoritative multiplayer game server framework built in Go (go 1.25). It is designed to be fully compatible with reference-shaped multiplayer API contracts and runtime interfaces, extending them with configurable Single-Instance (in-memory local state) or Multi-Instance Cluster modes (shared PostgreSQL and Redis Pub/Sub) for horizontal scale-out.

This repository containing the UGE server engine can be used as an open-source framework by other game projects to run game logic, manage player sessions, validate in-app purchases, and execute custom server-side runtimes.


Key Features

  • Modular Server Architecture: Plug-and-play modules (pkg/modules/*) including Authentication, Storage Engine, Matchmaking, Economy/IAP, Social Systems, and Leaderboards.
  • Multi-Runtime Extensibility: Write game logic in native Go (embedded or .so plugins), sandboxed Lua (gopher-lua VM), or sandboxed JavaScript (goja ES6 VM).
  • Authoritative Multiplayer: Tick-rate based game loops executing inside authoritative match processes, supporting asynchronous join attempts, custom state transitions, opcode dispatching, and deferred broadcast flushes.
  • Real-Time & RPC Communications: Dual HTTP/WebSocket (0.0.0.0:7350) and gRPC (0.0.0.0:7349) connection pipelines for low-latency client-server messaging, presences, and RPC dispatching.
  • Built-in Game Services:
    • Storage Engine: Full object storage with ACL permissions, optimistic concurrency control (OCC), and Bluge indexing & querying.
    • Authentication: Device, Custom, Email, Google, Apple, Facebook Instant, Huawei, and Samsung login; JWT session token issuance and verification; session registry and revocation.
    • Economy & IAP: Multi-currency wallet operations (nk.WalletUpdate) and receipt validation for Apple App Store, Google Play Store, Huawei AppGallery, Facebook Instant Games, and Samsung Galaxy Store.
    • Social Systems: Friends, Chat channels, Parties, Groups, and User Presences.
    • Leaderboards & Tournaments: Ranking tables, score submissions, reset schedules, and rewards.
    • Fleet & Satori Integration: Local stub FleetManager and optional Satori telemetry client integration.
    • Cron Scheduler: Distributed background job runner with optional Redis cluster locking.
  • Flexible Deployment Modes:
    • Single-Instance Mode (Default): Zero Redis dependency, zero pub/sub overhead, pure in-memory local state execution.
    • Multi-Instance Cluster Mode: Redis Pub/Sub coordinates stream messages, match routing, and distributed locks across nodes.

Architecture Overview

+-----------------------------------------------------------------------------------+
|                            Ultimate Game Server Engine                            |
|                                (pkg/engine.Server)                                |
+-----------------------------------------------------------------------------------+
|  [HTTP/WS Listener :7350]   [gRPC Listener :7349]    [Admin Console :7351]       |
+-----------------------------------------------------------------------------------+
|  Built-in Modules:                                                                |
|  - Auth Module           - Storage Module           - Matchmaker Module           |
|  - Economy Module        - Social Module            - Leaderboard Module          |
+-----------------------------------------------------------------------------------+
|  Runtime Scripting & Handlers:                                                    |
|  - Native Go Handlers    - Lua VM (Gopher-Lua)      - JavaScript VM (Goja ES6)   |
|  - Dynamic .so Plugins   - Cron Scheduler           - Bluge Storage Indexing      |
+-----------------------------------------------------------------------------------+
|  Persistence & Cluster Layer:                                                     |
|  - PostgreSQL / CockroachDB (SQL Storage & Migrations)                             |
|  - Optional Redis Pub/Sub (Multi-Instance Cluster Scaling)                        |
+-----------------------------------------------------------------------------------+

Standalone Project Initialization Guide

To build a custom game server using UGE, create a completely separate, standalone Go project.

1. Initialize Your Go Module

Create a new directory for your game server and run go mod init:

mkdir my-game-server
cd my-game-server
go mod init my-game-server
2. Add UGE Dependency

Add UGE directly to your project using go get:

go get github.com/BornToBuildGame/ultimate-game-server@v1.1.0

(Replace v1.1.0 with the specific release tag or commit hash target.)

Local Development Setup

If developing locally alongside the UGE source code directory, add a replace directive to your go.mod:

module my-game-server

go 1.25

require github.com/BornToBuildGame/ultimate-game-server v0.0.0

replace github.com/BornToBuildGame/ultimate-game-server => ../ultimate-game-engine/ultimate-game-server

After updating go.mod, run go mod tidy to download dependencies:

go mod tidy
3. Create Your Main Server Entrypoint

Create a main.go file inside your project root using UGE as an embeddable engine:

package main

import (
	"context"
	"database/sql"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/BornToBuildGame/ultimate-game-server/pkg/config"
	"github.com/BornToBuildGame/ultimate-game-server/pkg/engine"
	"github.com/BornToBuildGame/ultimate-game-server/pkg/modules/auth"
	"github.com/BornToBuildGame/ultimate-game-server/pkg/modules/economy"
	"github.com/BornToBuildGame/ultimate-game-server/pkg/modules/leaderboard"
	"github.com/BornToBuildGame/ultimate-game-server/pkg/modules/matchmaker"
	"github.com/BornToBuildGame/ultimate-game-server/pkg/modules/social"
	"github.com/BornToBuildGame/ultimate-game-server/pkg/modules/storage"
	"github.com/BornToBuildGame/ultimate-game-server/pkg/runtime"
)

func main() {
	// Parse CLI flags, environment variables, or config YAML file
	cfg, err := config.Parse(os.Args)
	if err != nil {
		log.Fatalf("failed to parse config: %v", err)
	}

	// 1. Initialize UGE Server Engine
	srv, err := engine.NewServer(cfg)
	if err != nil {
		log.Fatalf("failed to create server instance: %v", err)
	}

	// 2. Register modular features
	srv.Use(auth.NewModule())
	srv.Use(storage.NewModule())
	srv.Use(matchmaker.NewModule())
	srv.Use(economy.NewModule())
	srv.Use(social.NewModule())
	srv.Use(leaderboard.NewModule())

	// 3. Register native Go custom game logic (typed hooks use pkg/runtime DTOs)
	srv.RegisterInit(func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.RuntimeModule, initializer runtime.Initializer) error {
		logger.Info("Standalone MyGameServer initialized successfully!")

		if err := initializer.RegisterAfterAuthenticateDevice(func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.RuntimeModule, out *runtime.Session, in *runtime.AuthenticateDeviceRequest) error {
			userID, _ := ctx.Value(runtime.CtxUserID).(string)
			logger.Info("device auth ok user=%s device=%s", userID, in.ID)
			return nil
		}); err != nil {
			return err
		}

		// Untyped AfterRt remains available when you only need JSON/interface{} payloads
		_ = initializer.RegisterAfterRt

		return initializer.RegisterRpc("ping", func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.RuntimeModule, payload string) (string, error) {
			return `{"status":"ok"}`, nil
		})
	})

	// 4. Launch server in a background goroutine
	ctx := context.Background()
	go func() {
		if err := srv.Start(ctx); err != nil {
			log.Fatalf("server crash: %v", err)
		}
	}()

	// 5. Handle graceful shutdown
	shutdownChan := make(chan os.Signal, 1)
	signal.Notify(shutdownChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
	<-shutdownChan

	teardownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := srv.Stop(teardownCtx); err != nil {
		log.Printf("error during server shutdown: %v", err)
	}
}
4. Build and Run Your Game Server

Compile and launch your custom binary:

go build -o my_game_server main.go
./my_game_server --config config.yaml

Custom Module Development

UGE supports both embedded Go code registration and dynamically loaded .so shared object plugins.

1. InitModule Entrypoint

Custom runtime modules export an InitModule entrypoint signature:

package main

import (
	"context"
	"database/sql"

	"github.com/BornToBuildGame/ultimate-game-server/pkg/runtime"
)

// InitModule is invoked by Ultimate Game Engine when initializing the module.
func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.RuntimeModule, initializer runtime.Initializer) error {
	logger.Info("Initializing custom game logic...")

	// Register RPCs, Intercept Hooks, and Authoritative Matches
	return nil
}
2. Component Registration Examples
Custom RPC Handlers
initializer.RegisterRpc("claim_daily_reward", func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.RuntimeModule, payload string) (string, error) {
	userID, _ := ctx.Value(runtime.RUNTIME_CTX_USER_ID).(string)
	logger.Info("Processing reward claim for user %s", userID)
	return `{"success": true, "reward": 500}`, nil
})
Before & After Interceptor Hooks
// Intercept Email Authentication request before execution
initializer.RegisterBeforeAuthenticateEmail(func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.RuntimeModule, in *runtime.AuthenticateEmailRequest) (*runtime.AuthenticateEmailRequest, error) {
	if in.Email == "" {
		return nil, runtime.ErrBadRequest("email cannot be empty")
	}
	return in, nil
})

// React asynchronously after storage objects are written
initializer.RegisterAfterWriteStorageObjects(func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.RuntimeModule, out *runtime.StorageObjectAcks, in *runtime.WriteStorageObjectsRequest) error {
	logger.Info("Successfully wrote %d storage objects", len(out.Acks))
	return nil
})
3. Dynamic .so Plugin Compilation

To compile plugins for runtime loading via runtime.path:

go build --buildmode=plugin -o data/modules/my_plugin.so main.go

Note: Because Go's standard plugin package enforces binary safety, the compiled .so plugin and target UGE server binary must be built with the exact same Go toolchain version, OS/architecture targets (GOOS, GOARCH), and matching dependency module versions.


Lua & JavaScript VM Runtime Support

In addition to Go native modules, UGE automatically loads Lua (*.lua) and JavaScript (*.js) script modules placed in the directory configured by runtime.path (default data/modules).

Lua Runtime Scripting

Lua scripts run inside a sandboxed gopher-lua VM state. They have access to the global nk object for engine services:

-- data/modules/test_rpc.lua
local nk = require("nk")

local function echo_rpc(context, payload)
    nk.logger_info("Lua RPC invoked with payload: " .. tostring(payload))
    return nk.json_encode({ status = "success", received = payload })
end

nk.register_rpc(echo_rpc, "lua_echo")
JavaScript Runtime Scripting

JavaScript scripts execute inside a sandboxed ES6 goja JS runtime context:

// data/modules/test_rpc.js
function handleRpc(ctx, logger, nk, payload) {
    logger.info("JS RPC executed!");
    return JSON.stringify({ message: "Hello from JavaScript VM!" });
}

nk.registerRpc("js_echo", handleRpc);

Sample Game Module (Tài-Xỉu / Sic Bo)

UGE includes a complete, production-ready sample authoritative game module under examples/taixiu.

Features Demonstrated
  • Authoritative Match Loop: Tick-rate game loop (MatchLoop) managing a 4-phase state machine (BETTING -> ROLLING -> RESULT -> INTERMISSION).
  • Economy Integration: Real-time bet validation and payout credits using nk.WalletUpdate.
  • WebSocket Messaging: Dual-way binary/JSON opcode messages (OpCodeBet, OpCodeStateUpdate, OpCodeBetAck, OpCodeRoundResult).
  • Automated Testing: Comprehensive unit and integration test suite (taixiu_test.go and taixiu_integration_test.go).

Run the sample tests with:

go test -v ./examples/taixiu/...

Configuration Reference

UGE options can be provided via YAML configuration file, Environment Variables, or CLI Flags (supporting flat names and hierarchical names).

Primary Configuration Options
Option / Setting YAML Key Environment Variable CLI Flag Default Value
Config File Path CONFIG --config ""
HTTP Socket Address socket.http_addr HTTP_ADDR --http_addr or --socket.http_addr 0.0.0.0:7350
gRPC Socket Address socket.grpc_addr GRPC_ADDR --grpc_addr or --socket.grpc_addr 0.0.0.0:7349
Console Admin Address console.address CONSOLE_ADDR --console_addr or --console.address 0.0.0.0:7351
Database DSN database.dsn DATABASE_URL --dsn or --database.dsn postgres://game_admin:game_password@localhost:5432/ultimate_game_db?sslmode=disable
Database Read DSN database.read_dsn DATABASE_READ_URL --read_dsn or --database.read_dsn ""
Run Auto Migrations database.migration DATABASE_MIGRATION --database_migration true
Database Max Open Conns database.max_open_conns DATABASE_MAX_OPEN_CONNS --database_max_open_conns 20
Database Max Idle Conns database.max_idle_conns DATABASE_MAX_IDLE_CONNS --database_max_idle_conns 5
Session Signing Key session.encryption_key JWT_SECRET --jwt_secret or --session.encryption_key super_secret_signing_key_at_least_32_bytes_long_1234567
Modules Runtime Path runtime.path UGE_RUNTIME_PATH --runtime_path or --runtime.path data/modules
RPC HTTP Auth Key runtime.http_key UGE_RPC_HTTP_KEY --rpc_http_key or --runtime.http_key ""
Enable Multi-Instance Mode multi_instance.enabled MULTI_INSTANCE --multi_instance or --multi_instance.enabled false
Redis Server Address multi_instance.redis_addr REDIS_ADDR or REDIS_URL --redis_addr or --multi_instance.redis_addr localhost:6379
Sample YAML Configuration (config.yaml)
name: ultimate-game-server

database:
  dsn: "postgres://game_admin:game_password@localhost:5432/ultimate_game_db?sslmode=disable"
  migration: true
  max_open_conns: 25
  max_idle_conns: 10

socket:
  http_addr: "0.0.0.0:7350"
  grpc_addr: "0.0.0.0:7349"

console:
  address: "0.0.0.0:7351"

session:
  encryption_key: "my_custom_secure_jwt_secret_key_change_me_in_prod"

runtime:
  path: "data/modules"

multi_instance:
  enabled: false
  redis_addr: "localhost:6379"

Docker & Local Infrastructure

Use Docker Compose to quickly spin up PostgreSQL 16 and Redis 7 dependencies for local development.

docker-compose.yml
version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    container_name: ultimate-game-postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: ultimate_game_db
      POSTGRES_USER: game_admin
      POSTGRES_PASSWORD: game_password
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    container_name: ultimate-game-redis
    ports:
      - "6379:6379"
    volumes:
      - redisdata:/data

volumes:
  pgdata:
  redisdata:

Launch infrastructure services:

docker-compose up -d

Building and Testing

1. Run Unit Tests

Run all test packages in the repository:

go test ./pkg/... ./internal/... ./examples/taixiu/...
2. Build the Server Binary

Build the primary server entrypoint executable:

go build -o ultimate-game-server ./cmd/server
3. Run the Server

Launch the server binary with automatic database migration enabled:

./ultimate-game-server --config config.yaml --database_migration true

Directories

Path Synopsis
cmd
server command
examples
internal
api
cronexpr
Package cronexpr parses cron time expressions.
Package cronexpr parses cron time expressions.
iap
Package iap provides store receipt verification helpers (Apple, Google, Huawei).
Package iap provides store receipt verification helpers (Apple, Google, Huawei).
pkg
config
Package config is the public configuration surface for embedding Ultimate Game Engine.
Package config is the public configuration surface for embedding Ultimate Game Engine.
fleet
Package fleet is the public FleetManager surface for embedding Ultimate Game Engine.
Package fleet is the public FleetManager surface for embedding Ultimate Game Engine.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL