denny 2025. 3. 24. 15:55

LuaJIT을 이용한 Behavior Tree 구현 (C++ + Lua)

LuaJIT을 이용하면 Lua 스크립트를 JIT(Just-In-Time) 컴파일하여 성능을 크게 향상시킬 수 있어. MMORPG 서버에서 Behavior Tree를 적용할 때 LuaJIT을 사용하면 일반 Lua보다 실행 속도가 빠르므로 적합한 선택이야.


1️⃣ C++에서 LuaJIT을 사용하는 방법

필요 라이브러리

  1. LuaJIT 공식 GitHub에서 LuaJIT을 다운로드하고 빌드
  2. C++에서 LuaJIT을 실행하기 위해 LuaJIT의 C API 사용

2️⃣ Lua 측 코드 (Behavior Tree)

📌 behavior_tree.lua

-- LuaJIT을 사용한 Behavior Tree
Node = {}
Node.__index = Node

function Node:new(name)
    local obj = { name = name, children = {} }
    setmetatable(obj, self)
    return obj
end

function Node:addChild(child)
    table.insert(self.children, child)
end

function Node:run()
    for _, child in ipairs(self.children) do
        local result = child:run()
        if result == "running" or result == "success" then
            return result
        end
    end
    return "failure"
end

-- ActionNode 정의 (실제 행동 수행)
ActionNode = setmetatable({}, { __index = Node })

function ActionNode:new(name, action)
    local obj = Node:new(name)
    obj.action = action
    setmetatable(obj, self)
    return obj
end

function ActionNode:run()
    return self.action()
end

-- 행동 함수 정의
function moveToTarget()
    print("🏃 Moving to target...")
    return "success"
end

function attackTarget()
    print("⚔️ Attacking target...")
    return "success"
end

function idle()
    print("😴 Idle...")
    return "failure"
end

-- Behavior Tree 생성
btRoot = Node:new("Root")
moveNode = ActionNode:new("Move", moveToTarget)
attackNode = ActionNode:new("Attack", attackTarget)
idleNode = ActionNode:new("Idle", idle)

btRoot:addChild(moveNode)
btRoot:addChild(attackNode)
btRoot:addChild(idleNode)

-- Behavior Tree 실행 함수
function runBehaviorTree()
    print("🌳 Running Behavior Tree")
    return btRoot:run()
end

✔️ 이 Lua 코드는 Behavior Tree를 정의하고 실행하는 역할을 해.
✔️ C++에서 runBehaviorTree()를 호출하면 BT 실행 결과를 받아올 수 있음.


3️⃣ C++ 측 코드 (LuaJIT 연동)

📌 main.cpp

#include <iostream>
#include <lua.hpp>  // LuaJIT C API

int main() {
    // LuaJIT 상태 생성
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);

    // Lua 스크립트 로드
    if (luaL_dofile(L, "behavior_tree.lua") != LUA_OK) {
        std::cerr << "Error loading Lua script: " << lua_tostring(L, -1) << std::endl;
        return -1;
    }

    // Lua 함수 호출 (Behavior Tree 실행)
    lua_getglobal(L, "runBehaviorTree");  // Lua의 runBehaviorTree() 호출

    if (lua_pcall(L, 0, 1, 0) != LUA_OK) {
        std::cerr << "Error executing Lua function: " << lua_tostring(L, -1) << std::endl;
        return -1;
    }

    // 결과 가져오기
    const char* result = lua_tostring(L, -1);
    std::cout << "Behavior Tree Result: " << result << std::endl;

    // Lua 상태 종료
    lua_close(L);
    return 0;
}

✔️ luaL_dofile(L, "behavior_tree.lua"): Lua 파일을 실행
✔️ lua_getglobal(L, "runBehaviorTree"): Lua의 Behavior Tree 실행 함수 호출
✔️ lua_tostring(L, -1): Lua에서 반환된 실행 결과 (success or failure 등)를 가져옴


4️⃣ 컴파일 및 실행

🔧 1) LuaJIT 빌드

git clone https://github.com/LuaJIT/LuaJIT.git
cd LuaJIT
make && sudo make install

🔧 2) C++ 코드 컴파일

g++ -o bt_main main.cpp -lluajit-5.1

🔧 3) 실행

./bt_main

✅ 최종 결과

🌳 Running Behavior Tree
🏃 Moving to target...
⚔️ Attacking target...
Behavior Tree Result: success

📌 결론

LuaJIT을 사용하여 Behavior Tree를 고속 실행 가능
MMORPG 서버에서 NPC AI, 몬스터 AI를 동적으로 조정 가능
C++에서 LuaJIT을 호출하여 게임 서버와 연동 가능
🚀 MMORPG 서버 AI 성능 최적화를 위해 LuaJIT + C++ 연동을 추천!