1. Project Overview & Quickstart (Tencent/puerts)
File: README.md
Unreal Releases
Unity Releases
Nuget Releases
WHAT is PuerTS?
PuerTS is a multi-language scripting solution for Unity/Unreal/DotNet.
- 🌐 Multi-Language Support (Unity 3.0 New!): JavaScript/TypeScript, Lua, and Python — use the language your team is most productive in, or even mix them in one project. (Unreal currently supports JavaScript/TypeScript only.)
- 🚀 Provides high-performance script runtimes with seamless C#/C++ interop.
- 📝 TypeScript declaration generation for type-safe access to host engine APIs.
WHY should I use PuerTS?
- Choose your language (Unity): PuerTS 3.0 introduces a unified
ScriptEnvarchitecture — write game logic in TypeScript, Lua, or Python with a consistent C# bridging API. No more one-size-fits-all. - Massive ecosystem access: leverage npm, LuaRocks, or PyPI packages alongside professional game engines to accelerate development.
- Type safety when you want it: TypeScript's static type checking significantly improves code robustness, while Lua and Python offer rapid prototyping flexibility.
- High efficiency: full-engine, cross-platform reflection calls — zero boilerplate for C++/C# interop.
- High performance: static wrapper generation for performance-critical paths, across all supported languages.
- Talented WebGL Support: massive advantage in performance and dev efficiency, even faster than pure C# in some cases.
Quick Start (Unity)
All three languages share the same ScriptEnv API — just swap the Backend:
JavaScript / TypeScript
using Puerts;
using UnityEngine;
void Start() {
var env = new ScriptEnv(new BackendV8());
env.Eval(@"
const Vector3 = CS.UnityEngine.Vector3;
const Debug = CS.UnityEngine.Debug;
let pos = new Vector3(1, 2, 3);
Debug.Log('Hello from JS! pos = ' + pos);
");
env.Dispose();
}Lua
using Puerts;
using UnityEngine;
void Start() {
var env = new ScriptEnv(new BackendLua());
env.Eval(@"
local CS = require('csharp')
local Vector3 = CS.UnityEngine.Vector3
local Debug = CS.UnityEngine.Debug
local pos = Vector3(1, 2, 3)
Debug.Log('Hello from Lua! pos = ' .. pos:ToString())
");
env.Dispose();
}Python
using Puerts;
using UnityEngine;
void Start() {
var env = new ScriptEnv(new BackendPython());
env.Eval(@"
exec('''
import UnityEngine.Vector3 as Vector3
import UnityEngine.Debug as Debug
pos = Vector3(1.0, 2.0, 3.0)
Debug.Log('Hello from Python! pos = ' + pos.ToString())
''')
");
env.Dispose();
}💡 Three languages, one API surface. Each example creates a
Vector3, then callsDebug.Log— real C# interop in just a few lines.
Puerts.AI (Unity Only)
Built on top of PuerTS, Puerts.AI brings AI capabilities directly into Unity — both in the Editor and at game runtime.
Unity Editor Assistant
Puerts.AI includes a ready-to-use Unity Editor Assistant that lets you control the Unity Editor with natural language. For example:
- "Build a medieval castle scene using basic meshes" — AI creates GameObjects, adjusts Transforms, assigns materials
- "Analyze puerts-related logs" — AI filters and summarizes logs intelligently
- "Check for missing scripts in the current scene" — AI traverses all GameObjects and reports issues
Any C# API is callable — the AI generates scripts that run in the PuerTS environment with full access to UnityEngine.* and UnityEditor.*.
The Editor Assistant comes in two versions:
| Agent Version (Built-in) | MCP Version (External) | |
|---|---|---|
| How it works | Chat directly inside a Unity Editor window | Connect from Cursor, Windsurf, Claude Desktop, or any MCP-compatible AI tool |
| Speed | ⚡ Faster — no network round-trips | Communicates via HTTP/SSE |
| Best for | Scene building, inspections, quick prototyping | Vibe coding workflows — AI edits code while controlling Unity to verify results |
What makes Puerts MCP different from other Unity MCP solutions?
- No separate process — the MCP server runs directly inside the Unity process, no extra services to launch
- Single tool, on-demand builtins — instead of registering dozens of tools upfront, it exposes only one tool; builtin modules are loaded on demand, saving context tokens while remaining equally powerful
- Extensible via builtins & skills — add new capabilities by dropping files into the resource directory, no code changes needed
Puerts.Agent Framework
The Editor Assistant above is built with Puerts.Agent — an open, extensible LLM Agent framework. But it's not just for the editor — agents can also run in game runtime, opening up gameplay possibilities:
- 🎮 Smart NPC Demo — Each NPC has its own LLM Agent instance and personality-driven system-prompt. NPCs generate truly dynamic dialogue based on player behavior and game state, sense their surroundings via C# APIs, and form personalized interactions through conversation memory. (SmartNPCDemo)
- 🧩 Maze Runner Demo — An AI that autonomously navigates a 3D maze by taking screenshots to observe the environment, reasoning about viable paths, executing movement commands, and verifying results — all powered by just two builtin modules and a system-prompt.(MazeRunnerDemo)
Build your own agent by creating a simple resource directory:
Resources/my-agent/
├── system-prompt.md.txt # Who the AI is and how it behaves
├── skills/ # Domain knowledge documents (loaded on demand)
└── builtins/ # Executable helper modulesHOW can I start to use PuerTS
FAQ
How to Install
Changelog
Known issues
Select Script Backend
PuerTS supports multiple script backends. For JavaScript/TypeScript, choose from V8, QuickJS, or Node.js. PuerTS 3.0 also adds Lua and Python as first-class backends.
JavaScript Backends
V8 (default): Generally excellent performance, moderate code size, only includes the implementation of the ECMAScript specification, does not include Node.js API or browser API.
QuickJS: Performance is not as good as V8, does not support debugging, but has a small code size, suitable for scenarios where code size is critical.
Node.js: Supports Node.js API (OpenSSL-related APIs are not supported on Unreal Engine's mobile platform), but has a larger code size.
| JS Backend | Node API | Performance | Code Size | Debugging | Notes |
|---|---|---|---|---|---|
| V8 | ❌ | ***** |
*** |
✔️ | |
| QuickJS | ❌ | ** |
* |
❌ | |
| Node.js | ✔️ | ***** |
***** |
✔️ | OpenSSL may be disabled |
Additional Language Backends (Unity 3.0 New!)
Note: Lua and Python backends are currently available for Unity only. Unreal Engine still supports JavaScript/TypeScript exclusively.
| Backend | Language | Performance | Platform Support | Notes |
|---|---|---|---|---|
| Lua | Lua 5.4 | ***** |
All platforms | Ideal for teams already using Lua |
| Python | CPython | *** |
Desktop only | Great for AI/ML integration & tooling |
Avaliable on these Engine
unreal engine 4.22 ~ latest
unity 5 ~ latest
Any .net project
Available on these Platform
PuerTS's core code supports all platforms supported by the game engines, but each script backend has its own platform requirements:
| Windows | Mac | Linux | Android | iOS | H5/Mini Games | |
|---|---|---|---|---|---|---|
| V8 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| Nodejs | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| Quickjs | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| Webgl | ❌ | ❌ | ❌ | ❌ | ❌ | ✔️ |
| Lua | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| Python | ✔️ | ✔️ | ✔️ | ❌ | ❌ | ❌ |
Note 1: Only V8, Nodejs, and Quickjs backends are available for Unreal. Unity supports all backends listed above.
Note 2: Although the Webgl backend only supports H5/Mini Games, its scripts run in the native JS VM of the web environment, which typically delivers higher performance (e.g., JIT support in iOS Mini Games). It also provides first-class language benefits such as convenient debugging and profiling.
Note 3: For JavaScript, different platforms can use different JS backends — e.g., V8 for mobile apps and Webgl for H5 — achieving full platform coverage with optimal performance.
Ask for help
WHAT - 普洱TS是什么?
PuerTS 是 Unity/Unreal/Dotnet 下的多语言脚本编程解决方案。
- 🌐 多语言支持(Unity 3.0 新特性!):JavaScript/TypeScript、Lua、Python 三大语言开箱即用——团队擅长什么就用什么,同一个项目里甚至可以混用。(Unreal 目前仅支持 JavaScript/TypeScript。)
- 🚀 提供高性能脚本运行时,与 C#/C++ 无缝互操作。
- 📝 提供 TypeScript 声明文件生成能力,类型安全地访问宿主引擎 API。
WHY - 为什么我该用普洱TS?
- 自由选择语言(Unity):PuerTS 3.0 引入了统一的
ScriptEnv架构——用 TypeScript、Lua 或 Python 编写游戏逻辑,享受一致的 C# 桥接 API,不再被某一种脚本语言绑定。 - 海量生态随手可用:npm、LuaRocks、PyPI 的海量包 + 专业游戏引擎的渲染能力,加速开发效率。
- 按需选择类型安全:TypeScript 的静态类型检查显著提升代码健壮性;Lua 和 Python 则提供快速原型验证的灵活性。
- 高效:全引擎,全平台支持反射调用,无需额外步骤即可与宿主 C++/C# 通信。
- 高性能:全引擎,全平台支持生成静态调用桥梁,所有支持的语言都兼顾了高性能场景。
- WebGL 平台天生优势:相比其他脚本方案,PuerTS 在 WebGL 平台性能和效率上都有极大提升,极限情况甚至比纯 C# 更快。
快速上手(Unity)
三种语言共享同一套 ScriptEnv API,只需切换 Backend:
JavaScript / TypeScript
using Puerts;
using UnityEngine;
void Start() {
var env = new ScriptEnv(new BackendV8());
env.Eval(@"
const Vector3 = CS.UnityEngine.Vector3;
const Debug = CS.UnityEngine.Debug;
let pos = new Vector3(1, 2, 3);
Debug.Log('Hello from JS! pos = ' + pos);
");
env.Dispose();
}Lua
using Puerts;
using UnityEngine;
void Start() {
var env = new ScriptEnv(new BackendLua());
env.Eval(@"
local CS = require('csharp')
local Vector3 = CS.UnityEngine.Vector3
local Debug = CS.UnityEngine.Debug
local pos = Vector3(1, 2, 3)
Debug.Log('Hello from Lua! pos = ' .. pos:ToString())
");
env.Dispose();
}Python
using Puerts;
using UnityEngine;
void Start() {
var env = new ScriptEnv(new BackendPython());
env.Eval(@"
exec('''
import UnityEngine.Vector3 as Vector3
import UnityEngine.Debug as Debug
pos = Vector3(1.0, 2.0, 3.0)
Debug.Log('Hello from Python! pos = ' + pos.ToString())
''')
");
env.Dispose();
}💡 三种语言,同一套 API。每个示例都创建了一个
Vector3,然后调用Debug.Log——短短几行代码即可实现真正的 C# 互操作。
Puerts.AI(仅 Unity)
基于 PuerTS 构建的 Puerts.AI,将 AI 能力直接带入 Unity——无论是编辑器还是游戏运行时。
Unity 编辑器助手
Puerts.AI 内置了一个开箱即用的 Unity 编辑器助手,让你用自然语言操控 Unity 编辑器。例如:
- "用基础 Mesh 搭建一座中世纪城堡场景" —— AI 自动创建 GameObject、调整 Transform、设置材质
- "分析下 puerts 相关的日志" —— AI 智能过滤并总结日志
- "检查当前场景有没有脚本丢失" —— AI 遍历所有 GameObject 并报告问题
凡是 C# 能调用的,AI 都能做到——AI 生成的脚本运行在 PuerTS 环境中,可直接访问 UnityEngine.* 和 UnityEditor.* 的完整 API。
编辑器助手有两个版本:
| Agent 版(内置) | MCP 版(外接) | |
|---|---|---|
| 使用方式 | 在 Unity 编辑器窗口内直接对话 | 从 Cursor、Windsurf、Claude Desktop 等支持 MCP 协议的 AI 工具接入 |
| 速度 | ⚡ 更快——没有网络往返 | 通过 HTTP/SSE 通信 |
| 适合场景 | 场景搭建、日常检查、快速原型 | Vibe coding 工作流——AI 一边改代码一边操控 Unity 验证效果 |
Puerts MCP 与市面上其他 Unity MCP 方案有何不同?
- 无需额外启动进程 —— MCP Server 直接跑在 Unity 进程内,不用另起服务
- 单工具 + 按需加载 builtin —— 不像其他方案预注册几十个工具,Puerts MCP 只暴露一个工具,builtin 模块按需加载,更省上下文 token,但功能同样强大
- 通过 builtin 和 skill 机制拓展 —— 只需往资源目录里放文件就能添加新能力,无需改代码
Puerts.Agent 框架
上面的编辑器助手就是用 Puerts.Agent 开发的——一个开放、可扩展的 LLM Agent 框架。它不仅能用于编辑器,还能跑在游戏运行时环境中,为 gameplay 玩法开发打开全新可能:
- 🎮 智能 NPC Demo —— 每个 NPC 拥有独立的 LLM Agent 实例和个性化 system-prompt。NPC 能根据玩家行为和游戏状态生成真正动态的对话,通过 C# 接口感知周围环境,并基于对话历史形成个性化的交互体验。(SmartNPCDemo)
- 🧩 迷宫 AI Demo —— AI 自主走迷宫的 Demo,展示 Agent 通过截屏观察 + 工具调用来探索 3D 迷宫。AI 截屏观察当前视野、推理可行路径、执行移动指令、再截屏验证结果——完全自主完成,整个实现仅用了两个 builtin 模块和一段 system-prompt。(MazeRunnerDemo)
构建你自己的 Agent,只需创建一个简单的资源目录:
Resources/my-agent/
├── system-prompt.md.txt # 告诉 AI 它是谁、该怎么做
├── skills/ # 领域知识文档(按需加载)
└── builtins/ # 可执行的辅助模块HOW - 我该怎么开始
常见问题
最新版本安装
改动日志
已知问题与解决办法
脚本后端选择
PuerTS 支持多种脚本后端。JavaScript/TypeScript 可选 V8、QuickJS、Node.js;3.0 新增 Lua 和 Python 作为一等公民后端。
JavaScript 后端
V8(默认):综合比较优秀,高性能,代码体积适中,仅包含 ECMAScript 规范的实现,不包含 Node.js API、浏览器 API。
QuickJS:性能不如 V8,不支持调试,但代码体积小,适用于包体大小敏感的场景。
Node.js:支持 Node.js API(Unreal Engine 移动平台下不支持 OpenSSL 相关 API),代码体积较大。
| JS 后端 | Node API | 性能 | 代码体积 | 调试 | 补充 |
|---|---|---|---|---|---|
| V8 | ❌ | ***** |
*** |
✔️ | |
| QuickJS | ❌ | ** |
* |
❌ | |
| Node.js | ✔️ | ***** |
***** |
✔️ | OpenSSL 可能被禁用 |
新增语言后端(Unity 3.0 新特性!)
注意:Lua 和 Python 后端目前仅在 Unity 版本中可用,Unreal Engine 仍仅支持 JavaScript/TypeScript。
| 后端 | 语言 | 性能 | 平台支持 | 补充 |
|---|---|---|---|---|
| Lua | Lua 5.4 | ***** |
全平台 | 适合已有 Lua 技术栈的团队 |
| Python | CPython | *** |
桌面平台 | 适合 AI/ML 集成与工具链开发 |
可用引擎
unreal engine 4.22 ~ latest
unity 5 ~ latest
任意.net环境
可用平台
PuerTS的核心代码支持游戏引擎支持的所有平台,但每个脚本后端有其特有的平台要求:
| Window | Mac | Linux | Android | IOS | H5/小游戏 | |
|---|---|---|---|---|---|---|
| V8 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| Nodejs | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| Quickjs | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| Webgl | ❌ | ❌ | ❌ | ❌ | ❌ | ✔️ |
| Lua | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| Python | ✔️ | ✔️ | ✔️ | ❌ | ❌ | ❌ |
注1: Unreal下只有V8、Nodejs、Quickjs三种后端,Unity支持以上所有脚本后端
注2: Webgl后端虽然只支持H5/小游戏,但它的脚本是运行在web环境的原生js虚拟机里,通常性能更高(比如在ios小游戏环境里支持jit),也能享受first class语言诸如方便调试,profiler等好处
注3: 对于js,不同平台可以选不同的js脚本后端,比如app选v8,H5平台选Webgl实现全平台支持且性能最优
技术支持
QQ群:942696334
UE4专属群:689643903
开发博客
File: doc/unity/zhcn/knowjs/debugging.md
VSCode Debug 指引
这里推荐你使用vscode进行debug。但如果是手机debug的时候,推荐你参考开发blog
- new JsEnv之后,需要传入debug端口。且在合适的地方调用jsEnv的Tick函数
//8080是连接的端口,和vscode工程目录下的.vscode\launch.json保持一致
void Start()
{
jsEnv = new JsEnv(new TSLoader(), 8080); // 推荐使用TSLoader,就不需要你手动指定JS输出目录
jsEnv = new JsEnv(new DefaultLoader("F:/puerts/unity/TsProj/output/"), 8080); // 使用DefaultLoader时需要手动指定你的JS输出目录。
}
void Update()
{
jsEnv.Tick();
}- 等待调试器链接
- 调试器通过websocket连接,期间有TCP的握手,websocket握手,建立连接后,调试器和V8还会交换些信息,整个过程大概几百毫秒
- 在这几百毫秒内执行的脚本将无法断点,如果你想断点这些代码,可以用puerts的等待调试器连接功能
- 如果c#版本高于7.2(支持async),建议用异步等待,否则用同步阻塞等待
异步等待例子
async void RunScript()
{
jsEnv = new JsEnv(new DefaultLoader("E:/puerts_unity_demo/TsProj/output/"), 8080);
await jsEnv.WaitDebuggerAsync();
jsEnv.ExecuteModule("QuickStart.mjs");
}
void Start()
{
RunScript();
}
void Update()
{
jsEnv.Tick();
}** 同步阻塞例子
void Start()
{
jsEnv = new JsEnv(new DefaultLoader("E:/puerts_unity_demo/TsProj/output/"), 8080);
jsEnv.WaitDebugger();
jsEnv.ExecuteModule("QuickStart.mjs");
}
void Update()
{
jsEnv.Tick();
}vscode下打开setting,搜索auto attach,将Debug>Node:Auto Attach设置为“on”(高版本vscode没有该选项,可以不设置)。
或是自行创建vscode debug的launch.json,将其端口号配置改为你上面设置的端口号:选择node.js attach
打开“ProjectSetting/Player”页面,把“Run In Background”勾选上
File: doc/unity/zhcn/knowjs/module.md
模块加载
Eval并不建议大量使用
PuerTS 支持使用 Eval 来执行 JS,前文我们也一直是用 Eval 来演示。
但Eval是一个非常基础的接口,它相当于在 JS 的全局作用域执行代码,因而很容易出现如下问题
void Start() {
Puerts.JsEnv env = new Puerts.JsEnv();
env.Eval("const a = 3");
////// 其他代码
////// 其他代码
////// 其他代码
////// 其他代码
////// 很久以后
env.Eval("const a = function () {}");
}上述代码,会抛出a被非法重定义的错误。这显然是不合开发习惯的。
比较好的方式是,把代码内容包裹在一个**立即执行函数 (Immediately Invoked Function Expression)**里面
void Start() {
Puerts.JsEnv env = new Puerts.JsEnv();
int a = env.Eval(@"
(function() {
const a = 3
return a;
})()
");
// a == 3
}实际上,在Javascript里,立即执行函数就是很类似模块的一个概念。它拥有一个独立的作用域,且能定义它自己的输出项。非常便于封装一个功能。
ESM 模块
从立即执行函数开始,Javascript 生态后续发展出过很多个模块规范,比如CommonJS,但目前最流行的是 JS 官方标准:ESM。
PuerTS 是支持执行 ESM 规范的模块的
你可以在任意Resources目录添加一个 helloworld.mjs 文件
import { world } from 'lib.mjs'
console.log('hello ' + world);在任意Resources目录添加一个 lib.mjs 文件
const world = 'puerts'
export { world }随后通过JsEnv.ExecuteModule引入。
void Start() {
Puerts.JsEnv env = new Puerts.JsEnv();
env.ExecuteModule("helloworld.mjs")
}执行以上代码,控制台会输出hello puerts。
通过以上写法,即可利用puerts加载js文件并执行,而不需要使用前面例子中的Eval(也不建议您正式开发时使用)。
CommonJS
在比较古老的PuerTS版本里,曾经也支持过CommonJS模块规范。但在2.0版本之后,PuerTS不再默认支持CommonJS,转为建议使用更为流行的ESM规范,
不过,PuerTS依旧提供了单独的第三方包,如果你在切换ESM中遇到任何困难,可以通过添加这个支持包来恢复CommonJS支持,参见:PuerTS.CommonJS
File: doc/unity/zhcn/knowjs/typescript.md
Typescript
正如我们的项目名为 PuerTS ,我们强烈建议你使用 Typescript 来写代码。TS 会比纯 Javascript 开发提供更强大的能力。
生成 d.ts
在 Typescript 中,d.ts 文件可以为你编写 Typescript 代码时提供代码提示。PuerTS 内置了生成 d.ts 文件的功能,这样你就可以在 Typescript 中得到 C# API 的代码提示了。你可以在 Unity 编辑器菜单的 PuerTS->Generate index.d.ts 处使用这个功能。
编写 tsconfig
有了 C# API 的声明文件后,你就可以编写 tsconfig 文件。这里提供一个 tsconfig.json 的范例,或者你可以参考官方 demo 项目:
{
"compilerOptions": {
"target": "esnext",
"module": "es2016",
"sourceMap": true,
"noImplicitAny": true,
"typeRoots": [
"../Assets/Puerts/Typing",
"../Assets/Gen/Typing",
"./node_modules/@types"
],
"outDir": "output"
}
}编译 Typescript
使用 tsc/swc 编译 Typescript 并加载
有了 tsconfig 文件后,我们可以简单地通过 tsc 命令将 ts 编译为 js。或者你也可以使用速度更快的 swc:
tsc -p tsconfig.json为了方便,你可以将 tsconfig 里的 output 目录改为你的 loader 会读取的目录,比如使用 defaultloader 的话直接生成到 resources。改成这样后你可以考虑开启 tsc 的 watch 模式,tsc 会在你修改 ts 代码后自动编译 ts,这样你就可以在修改完 ts 代码后直接运行 Unity 测试:
tsc -w -p tsconfig.jsonsource-map-support支持
在 Unity 里执行 js 代码时,如果抛了错,你会发现控制台里打印的 JS 栈的行数和你的代码完全对不上。这是因为 PuerTS 执行的是编译出来的 Javascript,这个错误栈是你编译出来的 Javascript 的栈,而非 Typescript 源码的。所幸的是,我们可以通过 sourcemap 功能将 Javascript 的行数映射回 Typescript 的行数。
- 正常情况下,你可以直接使用TSLoader,其内置了source-map支持
- 如果你的项目不适用TSLoader,可以直接将TSLoader的这个脚本文件放到你的项目,在JsEnv启动后执行下面代码即可。
import sm from 'source-map-support.gen.mjs'
sm.install({
retrieveFile: (path) => {
// 如果你用的不是inline的source-map,这里还得处理sourcemap的加载
return puer.loadFile(path).content
}
});console-redirect
在控制台里得到 Typescript 栈之后,还有一点是比较麻烦的,就是你不能像 C# 文件一样直接点击控制台里的文件路径跳转到指定位置。这时候就要添加 consoleredirect 的支持。
- 正常情况下,你可以直接使用TSLoader,其内置了console-redirect支持
- 如果你的项目不适用TSLoader,你可以参考这个项目:https://github.com/chexiongsheng/puerts_unity_demo/tree/master/projects/1_Start_Template/Assets/Samples/Editor/03_ConsoleRedirect。
File: doc/unity/zhcn/knowjs/webgl.md
WebGL支持
PuerTS 基于 JS 提供脚本能力,因此在打包WebGL上有很大的优势。
WebGL平台与JIT技术
JIT(即时编译)技术可以提高脚本语言的执行速度,包括JS、Lua和WASM等。有了JIT,脚本的执行速度可以与编译型语言相媲美。但如果没有JIT,脚本语言就会非常慢。v8、LuaJIT都是能将其脚本代码用JIT的方式执行的(iOS除外、某些游戏机平台也不行)。
Unity游戏发布到WebGL平台后,其C#代码会经Il2cpp转化为WASM,并通过浏览器的WASM引擎通过JIT执行。但如果你的游戏包含Lua,如果是xLua的方案,这些Lua代码会在编译为WASM的Lua虚拟机里执行,此时Lua代码是无法享受JIT的(浏览器有JIT权限,执行WASM可以JIT。但WASM没有JIT权限,执行脚本无法JIT)。
PuerTS-WebGL
PuerTS的优势在于:它可以将JS脚本发送到浏览器的JS环境里,利用浏览器的JIT能力来执行JS。这意味着,相比xLua,PuerTS在脚本执行上有压倒性的优势。
下面是一个比较表格,展示了在100k fibonacci(12)的情况下,xLua WebGL和PuerTS WebGL的执行速度对比:
| 100k fibonacci(12) | |
|---|---|
| xLua WebGL | 6200ms |
| Puerts WebGL | 165ms |
WebGL目前处在一个子包中,并不在puerts本体里。如果你想了解更多关于WebGL能力的信息,可以查看PuerTS-WebGL。
上面的测试是关于执行速度的。在跨语言性能上,这个方案并不优秀。但我们还是可以利用WebGL平台的特性,通过别的方式解决问题,参见这篇知乎文章
File: doc/unity/zhcn/other/building.md
PuerTS Unity Plugin 编译指南
在unity里使用PuerTS时,Plugins目录的puerts.dll,puerts.bundle等,都是C++编译成的native plugin。
如果遇到了需要Debug版plugin、或者其他需要修改C++代码的需求,你可以根据这个文档操作。
2.0.0以上版本指引
2.0版本后,PuerTS采用Node.js驱动cmake编译PuerTS的native plugin。你只需要进入unity/native_src/目录,输入以下命令即可完成编译
node ../cli make --backend v8_9.4 --platform win --arch x64上述命令会有一点长,你也可以参见unity/cli/cmd.mts查找quickcommand相关的信息,比如以上命令可以简化为node ../cli make vw6
1.x版本指引
PuerTS 官方是怎么编译 C++ plugin 的?
PuerTS采用github action进行自动化构建。因此,你可以很容易地在 .github/workflows/build_unity_plugins.yml 中找到编译 C++ plugins 的步骤。
以 macos 为例。你可以在 build_unity_plugins.yml 中找到构建的几大步骤:
- 下载v8/quickjs/node依赖库
- name: Download artifact
uses: dawidd6/action-download-artifact@v2
with:
workflow: build_v8.yml
name: v8_bin
repo: puerts/backend-v8
path: unity/native_src/说明:
PuerTS负责构建v8依赖库的仓库是https://github.com/puerts/backend-v8(你也可以该仓库所属组织下找到负责构建QuickJS和NodeJS依赖库的仓库)
而上述action的这个步骤,就会把v8依赖库仓库下名为build_v8的action的产物下载到native_src目录下。
- 执行构建
- name: Build
run: |
cd unity/native_src
npx ts-node --esm make.mts --platform osx说明:
这个npx ts-node --esm make.mts会调用cmake启动c++编译,最终在 unity/native_src 目录下生成build_osx_v8目录。里面就包含着我们需要的构建产物:puerts.bundle。
1.3版本及以前,这里用的是sh make_osx.sh
本地构建
如果要本地构建puerts,只需要按照上述github action workflow的流程跑一遍即可。
当然,在此之前你需要先准备好相关的构建编译工具,比如XCode、VisualStudio、CMake等,这部分内容在互联网上很容易能搜到,就不多表述了。
- 将 https://github.com/puerts/backend-v8 或者 https://github.com/puerts/backend-quickjs 等JS引擎的构建产物放入
unity/native_src目录,它们可以在github项目首页的Actionstab里找到。(其中需要注意的是,因为github action页面的编排的问题,鼠标滚动的时候需要将鼠标放在页面比较边缘的位置) - 执行
npx ts-node --esm make.mts,并将你需要的JS引擎作为参数传入,比如npx ts-node --esm make.mts --backend quickjs。如果不传最后的参数,默认为v8。npx ts-node --esm make.mts -h可以看到更多的编译选项,如编译其他平台的plugin或者是调试版本plugin
File: doc/unity/zhcn/other/commercial.md
普洱精品支持(初稿)
普洱TS一直以来都通过开源共建的规则迭代维护。不过,为了帮助更多类型的开发者。普洱项目组准备提供更高级别的增值服务,增强开发者的接入信心,同时更能发挥普洱的潜力,帮助开发者更高效地完成项目:
征集意向项目组中, 定价皆为暂定
1. 高级计划
提供等同于普洱面向腾讯公司内部工作室的服务,至少包括:
- 无限制的普洱的基础问答咨询服务。
- JS生态相关知识与应用方法的教学。
- 项目立项建议。
- 协助分析项目性能,排查项目性能问题。
- 过往版本支持:
- PuerTS 1.3及以下版本。
- Unity 2018及以下版本。
- 未来无开源打算的技术服务使用权。功能包括但不限于:
- v8 Snapshot 启动速度优化。
- 字节码支持。
- 指针压缩功能,减少内存消耗
- 基于pixui的用HTML编写UI功能。
- 以更高优先级提供普洱开源计划中但未实现/未开源的功能。功能包括但不限于:
- 基于buffer读写的跨语言套件
- WebGL下的多线程组件
- fast-c-api call
- ts代码分析生成link.xml / d.ts。
- Lua到TS的AI转写。
- PlayStation/Switch等游戏机平台支持
- 小游戏上线全链路技术服务
- 基于QuickJS的JS热更支持(原理与xLua相同,无法直接调用wxapi,没有JIT)
- 小游戏加载速度优化服务
- 协助与官方沟通
- 普洱生态相关开源技术的服务 —— 若您期望使用普洱爱好者业余时间提供的库/框架,但担心稳定性和维护性问题,普洱团队可以代为提供技术协助。这部分服务的收入最终会根据工作量给予原作者奖励,鼓励生态的成长。目前支持的库和框架:
关于费用:
接入方负责人力成本的0.2倍,其余成本由腾讯公司负担
涉及开源的部分,接入方可额外签署排他协议,可以以游戏类型为维度,保证贵项目在发布后或是开始接入的一段时间内,没有竞品使用对应服务。
2. 特级计划
提供包含在高级计划内的所有服务。同时接受贵项目内具体功能需求的开发(最好与普洱相关),可配合签署保密协议,并保证不会保存相关代码的副本。
关于费用:
约为人力支出的2倍
功能备注
pixui
PuerTS 提供了在 Unity/UE 下的 Typescript 编程能力,那么,HTML/CSS 技术是否也能在 Unity/UE 下应用呢?
答案是可以的。PuerTS 的兄弟团队,就开发了这么一个框架,名为 PixUI。它支持完整的HTML/CSS渲染,甚至支持<video>、<canvas>等特别麻烦的标签。
PixUI 同时也支持和 PuerTS 联合运作,在使用全套 HTML 技术栈编写 UI 的同时,也能享受 PuerTS 的所有能力。
Buffer读写套件/WebGL多线程组件
参见知乎文章 【Unity WebGL】让JS比C#还快 —— Puer-WebGL 性能优化实录
fast-c-api call
v8自带功能,原本用于优化JS操作图形的接口。即对于大部份是基础数据类型的接口,跨语言速度有极大的优化(Windows下约4倍)。
其限制在于这个跨语言方式不支持回调JS,不支持创建新的JS对象,返回值也只支持数字和bool,且需要进行上千次调用后优化才会生效。
指针压缩功能
v8官方宣称可以节省40%内存。我们实测约33%左右。代价是启动时v8要预留一大块内存,ios要做特殊设置。
File: doc/unity/zhcn/other/community.md
PuerTS 在社区
下列内容都来自于社区,PuerTS会不定时搜集优秀内容填进下面的列表,但更希望您通过 PR 的方式将您东西分享出来。
- 脚手架/二次封装框架
| Author | repo | type | star |
|---|---|---|---|
| @sbfkcel | https://github.com/sbfkcel/puerts_cli | Cli | |
| @throw-out | https://github.com/throw-out/puerts-unity-kit | Framework | |
| @Justin-sky | https://github.com/Justin-sky/Nice-TS | Framework | 280+ |
| @Geequlim | https://github.com/Geequlim/puerts-starter-kit | Framework | 100+ |
| @zgz682000 | https://github.com/zgz682000/puerts-component | Framework | 20+ |
| @jungog | https://github.com/jungog/UnityTs | Framework | |
| @zombieyang | https://github.com/zombieyang/puerts-ts-loader | Library |
- 例子项目
| Author | repo | type | star |
|---|---|---|---|
| @zombieyang | https://github.com/zombieyang/puerts_unity_webgl_demo | Samples | 70+ |
| @throw-out | https://github.com/throw-out/PerformanceTesting | Samples | |
| @DOSexample | https://github.com/DOSexample/puerts_unity_demo | Samples |
- 优秀文字/视频教程:
| Author | title | url |
|---|---|---|
| @NowPaper | Unity TypeScript 脚本解决方案 Puerts 实例解析快速上手 | https://www.bilibili.com/video/BV13v411g7sV |
| @Justin-sky | Puerts中使用protobuf | https://zhuanlan.zhihu.com/p/205342984 |
File: doc/unity/zhcn/other/dotnet.md
在Dotnet项目中使用PuerTS
PuerTS Unity不仅可以在Unity C#中使用,同样可以在一个纯Dotnet项目中使用。步骤也非常简单:
- 让dotnet项目引用所有PuerTS C#代码
- 添加 PUERTS_GENERAL 宏
- 编写特定的 Loader 使PuerTS可以加载内置JS
示例
普洱官方采用了一个dotnet程序进行代码单元测试,你可以参见我们的github action配置:<repository>/.github/workflows/unity-unittest.yml。
进入官方仓库的<repository>/unity/test/dotnet目录,执行 node ../../cli dotnet-test v8_9.4 。
随后就会在该目录下生成名为vsauto-static的dotnet项目。
File: doc/unity/zhcn/other/upgrade.md
升级指南
本文档用于记录各个大版本之间主要的升级内容及其注意事项。
1.4.x -> 2.0.x
- 主要新功能
- 新增xil2cpp模式,极大提高跨语言性能。但需要你自己编译普洱的binary,牺牲一点灵活度。
- 目录结构完全遵循upm格式
- 不向下兼容的变动:
- DateTime不再映射到js Date对象。js侧需要按照System.DateTime来使用。
- TypedValue只能传给object类型,不再具备选择重载的作用。
- 反射模式下,如果一个函数无重载也无默认参数,不会进行参数检查。
- Ref所使用的下标由['value']变为[0](如果你代码使用的是puer.$ref和puer.$unref,而不是直接使用下标的话,不受影响)。
- 1.4版本中预告过的:2.0版本不自带require,建议改用ExecuteModule。如果改造成本过大,可以直接使用puerts-commonjs
Puerts.Editor.Generator.BindingMode更名为Puerts.BindingMode
1.3.x -> 1.4.x
- 主要新功能
- 支持Apple silicon(m系列)
- 全平台支持Node.js
- 新增子包 puerts-webgl,新增webGL平台支持,且在该平台下有极大的性能优势
- 新增子包 puerts-tsloader,内置Typescript处理,用于减少Typescript新手上手的学习成本,类似Deno的想法。支持node_modules的直接加载。
- 新增ESModule支持,且官方后续都建议使用ESModule。这种方式更为贴近JS标准。
2. Official Technical Reference & Guides (Tencent/Tencent.github.io)
File: konajdk/sm/README.md
Tencent Kona JDK ShangMi Reference Guide
Overview of ShangMi
ShangMi is a set of cryptographic techniques and tools in commercial or business applications, including the encryption of sensitive business data, secure communication channels, digital signatures for document verification, and even more.
Generally, the below ShangMi cryptographic algorithms and secure communication protocols are widely applied.
ShangMi cryptographic algorithms
- SM2, which is a public key algorithm based on Elliptic Curve Cryptography (ECC). It complies with China's specifications:
- GB/T 32918.1-2016 Part 1:General
- GB/T 32918.2-2016 Part 2:Digital signature algorithm
- GB/T 32918.3-2016 Part 3:Key exchange protocol
- GB/T 32918.4-2016 Part 4:Public key encryption algorithm
- GB/T 32918.5-2017 Part 5:Parameter definition
- SM3, which is a cryptographic hash algorithm. It complies with China's specification:
- GB/T 32905-2016 SM3 cryptographic hash algorithm
- SM4, which is a block encryption algorithm. It complies with China's specification:
- GB/T 32907-2016 SM4 block cipher algorithm
ShangMi secure communication protocols
- Transport Layer Cryptography Protocol (TLCP), which is a TLS liked protocol. This protocol requires an endpoint must have two certificates, one for signature and the other for encryption. It complies China's specification:
- GB/T 38636-2020 Information security technology-Transport layer cryptography protocol (TLCP)
- ShangMi (SM) Cipher Suites for TLS 1.3, which defines elements for applying ShangMi algorithms over TLS 1.3. It complies IETF's Informational specification:
- RFC 8998 ShangMi (SM) Cipher Suites for TLS 1.3
Providers and implementations
Tencent Kona JDK extends Java Cryptography Architecture (JCA) and Java Cryptography Extension (JCE) providers, exactly SUN, SunEC and SunJCE, to support ShangMi cryptographic algorithms, and extends Java Secure Socket Extension (JSSE) provider, exactly SunJSSE, to support ShangMi secure communication protocols.
The algorithms are implemented by the different security providers in the JDK. The followings list the security providers and the corresponding supported ShangMi algorithms and protocols.
- SUN
- MessageDigest
- SM3
- MessageDigest
- SunEC
- KeyAgreement
- SM2
- KeyFactory
- SM2
- Signature
- SM3withSM2
- KeyAgreement
- SunJCE
- Cipher
- SM4
- KeyGenerator
- HmacSM3
- SM4
- Mac
- HmacSM3
- Cipher
- SunJSSE
- SSLContext
- TLCP 1.1
- ECC_SM4_GCM_SM3
- ECC_SM4_CBC_SM3
- ECDHE_SM4_GCM_SM3
- ECDHE_SM4_CBC_SM3
- TLS 1.3/RFC 8998
- TLS_SM4_GCM_SM3
- TLCP 1.1
- SSLContext
Since Tencent Kona JDK just uses the existing OpenJDK security providers to accommodate the ShangMi stuff, and these providers are already installed with the highest priorities, so the application developers can use these out-of-the-box features as those JDK built-in algorithms (e.g. EC and AES) and protocols (e.g. TLS 1.3).
The following sections will unveil the details on using the above algorithms and protocols.
SM2
Key pair
Generating SM2 key pair is the same as generating the key pairs on other EC curves. It just needs to invoke the standard JDK APIs. The JDK builtin ECKeyPairGenerator. In the key pair generated by this implementation, the format of private key is PKCS#8 and the format of public key is X.509.
Create KeyPairGenerator implementation for EC algorithm.
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC);
keyPairGenerator.initialize(spec);spec can be SM2ParameterSpec (use SM2ParameterSpec.instance() to create the instance) or ECGenParameterSpec (use new ECGenParameterSpec("curveSM2") to create the instance).
Generate key pair.
KeyPair keyPair = keyPairGenerator.generateKeyPair();
ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();SM2 key pair is also EC key pair, so the public key and private key are also ECPublicKey and ECPrivateKey respectively.
For more information on key pair generation, please refer to the official KeyPairGenerator docs.
Generally, in the signing and encrypting operations, the key pairs are already generated. They are not generated on the runtime. It just reads the existing public key and private key to create PublicKey and PrivateKey instances respectively.
byte[] encodedPublicKey = ;
byte[] encodedPrivateKey = ;
KeyFactory keyFactory = KeyFactory.getInstance("SM2");
SM2PublicKeySpec publicKeySpec = new SM2PublicKeySpec(encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
SM2PrivateKeySpec privateKeySpec = new SM2PrivateKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);Signature
Using SM2 signature is the same as using other existing signatures, like ECDSA, though the parameters are different.
Create Signature instance.
Signature signature = Signature.getInstance("SM3withSM2);Initialize the Signature instance with the private key for signing.
signature.initSign(privateKey);Behind the above initialization, it uses the default SM2 ID, exactly 1234567812345678. It also derives the public key from the private key. According to the associated specification, public key must be used for generating SM2 signature data. This is a significant difference between the international algorithms, like ECDSA, and SM2 signature algorithm. Note that calculating the public key leads to some overhead. That is harmful for the performance.
If not using the default ID or expect to eliminate the cost on calculating public key, it would provide an AlgorithmParameterSpec, exactly SM2SignatureParameterSpec, instance.
byte[] altID = <custom ID>;
ECPublicKey publicKey = ;
SM2SignatureParameterSpec paramSpec = new SM2SignatureParameterSpec(altID, publicKey);
signature.setParameter(paramSpec);
signature.initSign(privateKey);After parameter setup and initialization, it is time to pass the message data in.
byte[] message = ;
signature.update(message);Generate signature data.
byte[] sign = signature.sign();Initialize the Signature instance with public key for verifying.
signature.initVerify(publicKey);Pass the message in.
byte[] message = ;
signature.update(message);Pass the signature data in.
boolean verified = signature.verify(sign);If the verification is successful, the result is true, otherwise false.
It has to know that the private key is used for signing, however the public key is used for verifying. For detailed information about Signature APIs, please refer to the official Signature docs.
Encryption
Because of the performance concern, public key encryption is only used for encrypting short but critical data. The same to SM2 encryption.
Create Cipher instance.
Cipher cipher = Cipher.getInstance("SM2");Initialize the Cipher instance with public key and set the mode to encryption.
cipher.init(Cipher.ENCRYPT_MODE, publicKey);Pass the message in and generate the ciphertext.
byte[] message = ;
byte[] ciphertext = cipher.doFinal(message);Initialize the Cipher instance with private key and set the mode to decryption.
cipher.init(Cipher.DECRYPT_MODE, privateKey);Pass the ciphertext in and generate the plaintext.
byte[] cleartext = cipher.doFinal(ciphertext);It has to know that public key is used for encryption, however the private key is used for decryption. For detailed information on Cipher APIs, please refer to the official Cipher docs.
SM3
Using SM3 hash algorithm is the same as using other existing hash algorithm, like SHA-256. It only invokes JDK APIs to generate the message digest (hash).
Create MessageDigest instance.
MessageDigest md = MessageDigest.getInstance("SM3");It can pass all the message in and generate the digest.
byte[] message = ;
byte[] digest = md.digest(message);It also can pass the message segments, and finally generate the digest.
byte[] messageSegment1 = ;
byte[] messageSegment2 = ;
// Pass the message segments in
md.update(messageSegment1);
md.update(messageSegment2);
// Finally generate the digest
byte[] digest = md.digest();For detailed information about MessageDigest APIs, please refer to the official MessageDigest docs.
HmacSM3
Using HmacSM3 algorithm is the same as using other existing MAC algorithm, like HmacSHA256. It only invokes JDK APIs to generate the message authentication code.
Prepare a 16-bytes key.
byte[] key = ;
SecretKey secretKey = new SecretKeySpec(key, "SM4");Create Mac instance.
Mac hmac = Mac.getInstance("HmacSM3");Initialize the Mac instance with the key.
hmac.init(secretKey);Pass all the message in and generate message authentication code. The code is 32-bytes length.
byte[] message = ;
byte[] mac = hmac.doFinal(message);It also can pass the message segments, and finally generate the message authentication code.
byte[] messageSegment1 = ;
byte[] messageSegment2 = ;
// Pass the message segments in
hmac.update(messageSegment1);
hmac.update(messageSegment2);
// Finally generate the message authentication code
byte[] mac = hmac.doFinal();For the detailed information about Mac APIs, please refer to the official Mac docs.
SM4
Using SM4 cipher algorithm is the same as using other existing block cipher algorithm, like AES. It only invokes JDK APIs to do encryption and decryption. Tencent Kona JDK supports four operation modes, including CBC, CTR, ECB and GCM. It also supports PKCS#7 padding specification.
Prepare a 16-bytes key.
byte[] key = ;
SecretKey secretKey = new SecretKeySpec(key, "SM4");Create Cipher instance.
Cipher cipher = Cipher.getInstance(transformation);The transformation consists of algorithm name, operation mode and padding type. A symbol / is used as separator between the parts.
The following transformations are supported:
- SM4/CBC/NoPadding: The operation mode is CBC. No padding is needed. It requires the input must be 16x bytes.
- SM4/CBC/PKCS7Padding: The operation mode is CBC. PKCS#7 padding is used. It doesn't require that the input must be 16x bytes.
- SM4/CTR/NoPadding: The operation mode is CBC. No padding is needed. It doesn't require that the input must be 16x bytes.
- SM4/ECB/NoPadding: The operation mode is ECB. No padding is needed. It requires the input must be 16x bytes.
- SM4/ECB/PKCS7Padding: The operation mode is ECB. PKCS#7 padding is used. It doesn't require that the input must be 16x bytes.
- SM4/GCM/NoPadding: The operation mode is GCM. No padding is needed. It doesn't require that the input must be 16x bytes.
Create the algorithm parameters.
AlgorithmParameterSpec paramSpec = ;Different operation modes may need different AlgorithmParameterSpec types,
- CBC and CTR modes use IvParameterSpec. This parameter type needs a 16-bytes as Initialization Vector (IV).
- GCM mode uses GCMParameterSpec. This parameter type needs a 12-bytes as Initialization Vector (IV) and specifies the tag length to 12-bytes.
Initialize the Cipher instance with the key and parameter type and set the mode to encryption.
cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);Pass all the message in and generate the ciphertext.
byte[] ciphertext = cipher.doFinal(message);Initialize the Cipher instance with the key and parameter type and set the mode to decryption.
cipher.init(Cipher.DECRYPT_MODE, secretKey);Pass all the ciphertext in and generate the plaintext.
byte[] cleartext = cipher.doFinal(ciphertext);It also can receive the plaintext/ciphertext segments in, and then generate the ciphertext/plaintext segments.
byte[] input1 = <segment1>;
byte[] input2 = <segment2>;
// Pass the plaintext/ciphertext segments in
byte[] output1 = cipher.update(input1);
byte[] output2 = cipher.update(input2);
// Generate the ciphertext/plaintext segments
byte[] outputFinal = cipher.doFinal();For the detailed information about Cipher APIs, please refer to the official [Cipher] docs.
Certificate
The so-called ShangMi certificate also complies to X.509 specification, though the public key algorithm is EC with SM2 curve and the signature algorithm is SM3withSM2.
String certPEM = <certificate in PEM format>;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) cf.generateCertificate(
new ByteArrayInputStream(certPEM.getBytes(StandardCharsets.UTF_8));For more information on certificate parsing, please read the official reference on CertificateFactory.
It can parse public key from the ShangMi certificate.
PublicKey publicKey = certificate.getPublicKey();publicKey can be cast to ECPublicKey.
It can parse private key from PKCS#8 format.
String peyPEM = ;
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
Base64.getMimeDecoder().decode(keyPem));
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);privateKey can be cast to ECPrivateKey.
It can sign data with PKCS#8 private key and verify the signature with X.509 certificate.
Create Signature instance and use SM3withSM2 signature algorithm.
Signature signature = Signature.getInstance("SM3withSM2");Sign the message with the private key and generate the signature data.
signature.initSign(privateKey);
signature.update(message);
byte[] sign = signature.sign();Verify the signature data with the certificate and determine whether the verification passes or fails.
signature.initVerify(certificate);
signature.update(message);
boolean verified = signature.verify(sign);The certificate has to contain digitalSignature key usage for verifying signature data. But it also can verify the signature with the public key directly.
signature.initVerify(publicKey);
signature.update(message);
boolean verified = signature.verify(sign);TLCP 1.1 and TLS 1.3/RFC 8998
In order to take advantage of the implementations on TLCP 1.1 and TLS 1.3/RFC 8998, the most important point is taking SSLSocket or SSLEngine to apply the SSLContext implementation that supports the protocols.
KeyStore trustStore = <a trust store carring the CAs>;
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(trustStore);
KeyStore keyStore = <a key store carring the end entity certificates>;
KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
kmf.init(keyStore, keyStorePassword);
SSLContext context = SSLContext.getInstance("TLCPv1.1");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());When create SSLContext instances, it allows to specify the following context protocols:
- TLCPv1.1, which indicates only TLCP 1.1 is supported.
- TLSv1.3, which indicates only TLS 1.3 is supported.
- TLCP, which indicates TLCP 1.1, TLS 1.3 and TLS 1.2 are supported.
Please read the official JSSE reference for understanding it deeply.
File: konajdk/README.md
Tencent Kona
Tencent Kona is a no-cost, production-ready distribution of the Open Java Development Kit (OpenJDK), Long-Term Support (LTS) with quarterly updates.
Kona serves as the default JDK at Tencent internally, optimized for extreme-scale of Big Data, Machine Learning and Cloud Computing workloads. It is also used to build and maintain a Tencent supported version of OpenJDK for Tencent customers and partners who wish to use OpenJDK to run their applications.
Kona also implements China's cryptographic algorithms, including SM2, SM3 and SM4, and secure communication protocol TLCP (or SMSSL). For more details on these features, please refer to the reference guide.
Supported JDK Releases
Tencent Kona currently supports the JDK Long-Term Support (LTS) releases 8, 11, 17, 21 and 25.
For more details, please go through the individual repository for each of these releases:
- Tencent Kona 8: https://github.com/Tencent/TencentKona-8
- Tencent Kona 11: https://github.com/Tencent/TencentKona-11
- Tencent Kona 17: https://github.com/Tencent/TencentKona-17
- Tencent Kona 21: https://github.com/Tencent/TencentKona-21
- Tencent Kona 25: https://github.com/Tencent/TencentKona-25
Supported System Platforms
Tencent Kona currently supports Linux/x86_64, Linux/aarch64, Windows/x86_64, macOS/x86_64 and macOS/aarch64.
License
Tencent Kona is under the same licensing terms as the upstream OpenJDK project. It is clearly a "friendly fork". Please find the license text for more details.