🌛

Lua の代替スクリプト言語まとめ

に公開

Lua の代替スクリプト言語

組み込み用のスクリプト言語として使える Lua はライトな反面、動的型付けや 1-based index といった仕様がボトルネックになりがちです。そうした状況の中、相応の短所も抱えた Lua の代替となりえる C/C++ 開発用組み込み用のスクリプト言語が多く開発されています。しかしながら、それらを横並びで比較及び評価した記事をあまり見かけませんでした。そこで、本記事では AltLua となりうる言語を取り上げ、それぞれの特徴を検証していきます。

Lua 向けトランスパイラ言語

コンパイルして Lua を出力するトランスパイラ言語について。Lua VM 上で動作するため、既存の Lua ライブラリの利用が可能な他、軽量で高速な強みを十分に生かせることが期待できます。

github stars やリリースなどの情報は 2025 年現時点のものを記載します。

MoonScript

https://github.com/leafo/moonscript

  • AltJS である CoffeeScript にインスパイアされて開発されたらしい。
  • MoonScript から直接 Lua スクリプトをインポート出来る。
  • Python と構文の思想が近そう。
  • 初期リリースは 2013、最新リリースは 2016 と最近は開発が落ち着いている印象。この言語をフォークした YueScipt は現在でも開発されている (後述)

コード例:

class Thing
  name: "unknown"

class Person extends Thing
  say_name: => print "Hello, I am #{@name}!"

with Person!
  .name = "MoonScript"
  \say_name!
import concat, insert from table

double_args = (...) ->
  [x * 2 for x in *{...}]

tuples = [{k, v} for k,v in ipairs my_table]

Fennel

https://github.com/bakpakin/Fennel

  • LISP 系の構文で、純粋な関数型よりの言語。
  • 実行ファイルとして Fennel を使うことも出来るが、Lua 同様アプリケーション自体にライブラリとして組み込むことが可能。
  • 初期リリース 2018、最新リリース 2021
;; Sample: read the state of the keyboard and move the player accordingly
(local dirs {:up [0 -1] :down [0 1] :left [-1 0] :right [1 0]})

(each [key [dx dy] (pairs dirs)]
  (when (love.keyboard.isDown key)
    (let [[px py] player
          x (+ px (* dx player.speed dt))
          y (+ py (* dy player.speed dt))]
      (world:move player x y))))

Teal

https://github.com/teal-language/tl

  • Lua そのものに静的型付けの恩恵を追加したような言語。TypeScript に思想が近いと言える。
  • enum や record, interface など機能も充実しており、かなり使い勝手が良さそう。
  • 初期リリースは 2021、最新リリースは 2025 と現在も活発に開発されている。
local addsub = {}

function addsub.add(a: number, b: number): number
   return a + b
end

function addsub.sub(a: number, b: number): number
   return a - b
end

return addsub
local enum State
   "open"
   "closed"
end

-- a record: a table with a known set of fields
local record Point
   x: number
   y: number
end

YueScript

https://github.com/IppClub/YueScript

  • 前述の通り、MoonScript dialect でありオリジナルよりも多くの機能が追加されている。
  • 初期リリースは 2023、最新リリースは 2025 と現在も活発に開発されている。
  • 開発者は Dora SSR というゲームエンジンも開発しており、このエンジンのスクリプティング用の一言語として使用されている。
-- import syntax
import "yue" as :p, :to_lua

-- object literals
inventory =
  equipment:
    * "sword"
    * "shield"
  items:
    * name: "potion"
      count: 10
    * name: "bread"
      count: 3

-- pipe operator
[1, 2, 3]
  |> map (x) -> x * 2
  |> filter (x) -> x > 4
  |> reduce 0, (a, b) -> a + b
  |> print

-- metatable manipulation
apple =
  size: 15
  <index>:
    color: 0x00ffff

with apple
  p .size, .color, .<index> if .<>?

-- js-like export syntax
export 🌛 = "月之脚本"

TypeScriptToLua

https://github.com/TypeScriptToLua/TypeScriptToLua

  • TypeScript そのものを Lua にトランスパイルするという野心的なプロジェクト。
  • 2025 現在も活発に開発されている。
// Give points to all friends around the target position
function onAbilityCast(caster: Unit, targetPos: Vector) {
    const units = findUnitsInRadius(targetPos, 500);

    const friends = units.filter(unit => caster.isFriend(unit));

    for (const friend of friends) {
        friend.givePoints(50);
    }
}

// ⬇️ ts to lua

-- Give points to all friends around the target position
function onAbilityCast(caster, targetPos)
    local units = findUnitsInRadius(targetPos, 500)
    local friends = __TS__ArrayFilter(
        units,
        function(____, unit) return caster:isFriend(unit) end
    )
    for ____, friend in ipairs(friends) do
        friend:givePoints(50)
    end
end

その他の多言語トランスパイラ言語

以下は、複数のプログラミング言語にトランスパイルすることを目的として開発された斬新なプログラミング言語です。ターゲットの一つとして Lua が使えます。

Haxe

https://github.com/HaxeFoundation/haxe

  • ライブラリ自体もクラスプラットフォームで扱えるものが提供されている。

ScriptX

https://github.com/Tencent/ScriptX

  • 「スクリプティングの抽象化レイヤー」
  • 高いパフォーマンスを謳っている。

その他 Lua 関連 (非スクリプト言語)

以下は Lua インスパイアの言語ですが、aot コンパイルの言語です。スクリプティングには使用できません。

Lua 向けトランスパイル言語のまとめ

言語名 GitHub Stars 現在の開発状況 特徴
MoonScript 3.3k 🌑 Python-like
Fennel 2.6k 🌗 LISP系の関数型
Teal 2.3k 🌕 静的型付け Lua dialect
YueScript 500 🌕 MoonScript diarect
TypeScriptToLua 2.3k 🌕 TypeScript で書ける
Haxe 6.4k 🌕 「多言語トランスパイラ」
ScriptX 500 🌗 「スクリプト抽象化レイヤー」

非 Lua VM の組み込み向けスクリプト言語

Lua と関わりのない組み込み向けスクリプト言語にも、強力かつ柔軟な選択肢がいくつか存在します。ここでは代表的な言語を紹介します。

AngelScript

https://www.angelcode.com/angelscript/

  • 静的型付けスクリプティング言語
  • 20年以上開発が続けられており、現在でもメンテナンスされている。最新リリースは 2024。
  • C++ like な構文 (GCの付いた C++ というイメージが分かりやすいかも)
  • setter / getter, interface, delegate といった C# の機能も取り入れられている。
  • Lua よりも低レベルな部分まで型のバインドが可能。例えば、配列型や文字列型を独自のものにしたり、バインドする型に対して明示的に値型または参照型を指定して細かい振る舞いを制御出来る。
  • 数多くのオプションが用意されており、スクリプトエンジン自体のカスタマイズ性が柔軟である。
  • JIT Compiler や Lua における sol のように、モダン C++ 向けのバインド asbind20 も存在する。
// Include the shared code
#include 'shared.as'

// This script implements the logic for the player character
class CPlayer : IController
{
	// The constructor must take a CGameObj handle as input,
	// this is the object that the script will control
	CPlayer(CGameObj @obj)
	{
		// Keep the owner for later reference
		@self = obj;
	}

	void OnMessage(ref @m, const CGameObj @sender)
	{
		CMessage @msg = cast<CMessage>(m);
		if( msg !is null && msg.txt == 'Attack' )
		{
			// The zombie got us
			self.Kill();
			game.EndGame(false);
		}
	}
	
	CGameObj @self;
}

AngelScript は Lua よりも細かい制御が可能で、よりハードウェアに近いレイヤーの表現が可能です。例えば、数値型について全てを double 値 (64-bit) として取り扱う Lua に対し、AngelScript では int8~uint64 まで細かく指定出来るためメモリ使用量の節約が期待できます。オブジェクト型についても、それぞれについて GC の対象とするかどうかをコンパイル段階で管理しているためパフォーマンスの向上が見込めます。

これらの優位性はゲーム開発に寄与する重要な要素となります。以前の記事でも取り上げましたが、Hazelight Studios は Unreal Engine 5 に AngelScript を導入した独自フォークを開発しています[1]。AngelScript の導入は単に開発イテレーションの質が高まっただけでなく、パフォーマンス的にも高水準なようです。UE 向け Lua プラグインと AngelScript のベンチマーク測定に関する資料を確認したため以下に掲載します。この結果によると、 AngelScript は Blueprint と Lua に大きく差をつけ、C++ と遜色ないほどの性能を発揮しています。

https://github.com/straywriter/UnrealEngine-Angelscript-Performance

Rhai

https://github.com/rhaiscript/rhai

  • Rust で書かれた比較的新しい軽量スクリプト言語。
  • JS と Rust に似た動的型付け言語。

拡張性も充実していそうで、今後 Rust プロジェクトの機会があれば使ってみるといいかもしれません。しかし、ある程度性能があるとはいえ、ゲームロジックを Rhai で全て実装するのは推奨されず、代わりに Lua を使ってほしいと明記されていました… [2]

// This Rhai script calculates the n-th Fibonacci number using a
// really dumb algorithm to test the speed of the scripting engine.

const TARGET = 28;
const REPEAT = 5;
const ANSWER = 317_811;

fn fib(n) {
    if n < 2 {
        n
    } else {
        fib(n-1) + fib(n-2)
    }
}

print(`Running Fibonacci(${TARGET}) x ${REPEAT} times...`);
print("Ready... Go!");

let result;
let now = timestamp();

for n in 0..REPEAT {
    result = fib(TARGET);
}

print(`Finished. Run time = ${now.elapsed} seconds.`);

print(`Fibonacci number #${TARGET} = ${result}`);

if result != ANSWER {
    print(`The answer is WRONG! Should be ${ANSWER}!`);
}

Python

https://github.com/pocketpy/pocketpy

pocketpy というゲームスクリプティング向けの軽量 Python インタプリタが開発されているようです。

  • 2023年から開発されているようで比較的新しい

  • 本家の実装である CPython と同じくらい高速らしい

JavaScript

V8 が組み込みに不向きとはいえ、軽量JS のプロジェクトを調べてみると一定数ありました。やはり需要があるようで予想以上にありました。以下にアクティブな3つを掲載します。

https://github.com/svaarala/duktape

https://github.com/jerryscript-project/jerryscript

https://github.com/quickjs-ng/quickjs

その他

最近はやや開発が緩やかに見受けられますが、参考までに紹介します。

  • Squiirel

https://github.com/albertodemichelis/squirrel

  • Wren

https://github.com/wren-lang/wren

  • ChaiScript

https://github.com/ChaiScript/ChaiScript

  • MiniScript

https://github.com/JoeStrout/miniscript

  • Gravity

https://github.com/marcobambini/gravity

まとめ

今回取り上げきれなかった言語も多くあるかと思いますが、本記事が何かしらの参考になれば幸いです。

自分としては、Lua プロジェクトにおいては Teal、C++ ゲーム開発においては AngelScript、Rust 関連をする機会があれば Rhai を使ってみたいという気持ちになりました。

脚注
  1. https://www.unrealengine.com/ja/developer-interviews/sci-fi-and-fantasy-worlds-collide-in-ue5-powered-co-op-adventure-split-fiction ↩︎

  2. https://rhai.rs/book/about/benchmarks.html ↩︎

Discussion