
Tibia 규칙 시뮬레이터 tibia는 Spiral 한 소스에서 C·Rust·WGSL용 코드를 생성해 에이전트를 훈련하고, 공개 재현형 벤치마크 OT Agent Arena에서 오픈소스 Tibia 봇과 비교하는 프로젝트다. 저장소는 시뮬레이터의 실시간 게임 예측 정확도와 정책별 결과, GPU 실행 조건, 실행 절차를 함께 공개한다.
구성과 현황
저장소는 2026년 10월 21일 기준 src 아래 Spiral 모듈 27개와 표준 규칙 파일 src/standards.spi, apps/arena의 Lua 프로브 및 공용 클라이언트 모듈 15개, apps/map의 서버 맵 도구로 구성된다. 규칙 모듈은 기하·생명력·코인·난수·재사용 대기시간·피해·전투·생물·경험치·기술·축복·통신을 다룬다. 타입 도메인에는 단위가 붙은 수량, GADT 증인으로 표현하는 준비 상태, 직업별 주문, 생성 생물 목록, 매핑·계수 뷰, 지형 레이아웃이 포함된다.
정책·정수 신경망·진화 탐색 모듈과 사냥 시뮬레이터, 여러 생물을 다루는 hunting_pack, OTClient의 Lua 진입점 live.spi도 들어 있다. 테스트는 실행 대상을 이유와 함께 지정한다. C는 기준 구현, WGSL은 GPU 경로, Lua는 실시간 클라이언트, Rust는 훈련 호스트가 필요한 테스트에 쓰인다.
실시간 검증 결과와 한계
현재까지의 결과에는 2026년 10월 14일 정정이 반영됐다. 10월 13일 11:48부터 수정 전까지 실시간 spiral-* 실행에는 vBot의 HealBot과 TargetBot이 정책과 함께 작동했다. vBot 프로브 설정을 끄지 않은 탓이다. 이 기간의 실시간 승리 주장은 철회됐으며, 아래 결과는 수정된 경기장에서 경쟁자별 30회 실행하고 외부 행동이 없었는지 매번 확인한 재측정에 근거한다.
시뮬레이터는 실시간 클리어 시간을 점검한 모든 경우에 맞췄고, 물약 사용량도 대체로 예측한다. 물약 예측은 실시간 측정이나 Canary 소스 분석에 따라 네 차례 수정됐다. 새로 접속한 기사의 로그인 보호가 10초 동안 몬스터를 막는 점, 작은 경기장에서 사이클롭스 세 마리를 배치한 시뮬레이터 오류, 몬스터가 줄을 서지 않고 기사를 둘러싸는 점, 보호 중 몬스터가 돌아다녀 클리어 시작 지형이 달라지는 점을 반영했다. 사이클롭스의 공격 간격은 2166ms로 측정했다. 피해량당 물약 수는 항상 맞았으며 오차는 기사가 맞은 타격 수에서 나왔다.
수정된 모델은 두세 마리 사이클롭스 상황에서 규칙 정책과 후퇴 정책의 물약 사용량을 실시간 평균의 변동 범위 안에서 예측했다. 다만 표본 밖 검증에서는 ‘사정거리 안의 몬스터를 우선 공격하면 물약 0.8개를 더 쓴다’는 예측이 틀렸다. 실제로는 차이가 없었고 규칙 정책은 12.3개, 해당 정책은 12.5개였다. 실시간에서 세 정책은 비슷한 양의 물약을 쓴다.
2026년 10월 20일부터 후퇴 걸음도 다른 이동처럼 예약된 공격을 취소하도록 했고, 기사의 판단 주기를 약 1083ms로 맞췄다. 이 조건에서 ReachFirst는 물약 12.47개, 규칙 정책은 12.30개로 예측돼 실시간 결과에 가까웠지만, 이 비교는 학습에 사용한 표본 안에서 이뤄졌다. 로그인 보호가 없는 경기장에서는 모델이 여전히 물약을 과대 예측했다. 다만 10월 21일 추가한 현재 경기장 규칙 묶음은 표본 밖 40회 실행에서 규칙 정책을 실시간 13.90개, 예측 14.55개로, 후퇴 정책을 13.25개, 예측 12.81개로 맞췄다. 후퇴 걸음 수도 실시간 12.4회, 모델 11.7회였다.
사냥터에서는 10월 22일 새 실행 결과를 반영해 물약 차이가 변동 범위 안에 들었다. PR-23에서 방패 11 조건으로 실시간 14.8개, 예측 14.84개였다. PR-15의 실시간 12.7개는 낮게 나온 표본으로 판명됐다. 반면 사냥꾼 클리어 시간은 여전히 열려 있다. PR-19에서 실시간 60.5초, 모델 55.9초였다. 실시간 사냥꾼은 기사와 두세 타일 떨어졌을 때 모델보다 빠르게 이동한다. 첫 추격에서 표적이 기사보다 20타일 이상 앞서는 경우가 실시간에는 약 절반이지만 모델에서는 20%에 그친다. 그런 추격 중 다른 사냥꾼들이 시야에서 벗어나면 실행이 실패한다.
기사의 이동·추격 방식을 모델링하는 여러 규칙을 시험했지만, 사냥꾼의 이동 속도 차이를 모두 설명하지 못했다. 모델의 사냥꾼은 기사가 같은 행에 들어서면 매번 직선으로 달린다. 실시간 사냥꾼은 방향을 바꿔도 앞서가며, 실시간 장거리 추격의 절반은 남쪽으로 끝나지만 모델에서는 그런 경우가 없다. 모델 사냥꾼의 방향을 무작위로 바꾸면 기사가 모두 따라잡아, 방향 전환 후에도 실시간 사냥꾼이 앞서는 이유가 남은 문제다. 기사의 표적이 멀어질 때 실시간 기사는 98%의 경우 1초 뒤에도 제자리에 있지만 모델은 57~68%였다. 이를 반영한 규칙 D32는 정지 현상을 재현했으나 사냥꾼 실행 클리어율을 100회 중 53회로 낮췄다. 실시간은 72~95%였다. 따라서 이 변경은 채택하지 않았고 클리어율은 미해결 상태다.
후퇴 걸음 간격을 실시간 경쟁자의 650ms에 맞추자 모델의 후퇴 걸음은 클리어당 15.1회에서 11.7회로 줄었다. 20회 표본 밖 실행에서는 10.1회, 실시간 11.3회였고 물약은 모델 12.80개, 실시간 13.32개였다. 다만 분산이 커 기존의 15.1회도 통계적으로 배제하지 못했다. 실시간 기사는 약 5걸음 뒤 1936,1349의 좁은 지점에 갇히지만 모델 기사는 약 8걸음 뒤 1937,1342에 있다. 후퇴 전부터 차이가 나는데, 실시간 사이클롭스는 기사가 행동하기 전에 소환 지점을 벗어나지만 모델에서는 움직이지 않아 시작 상황이 매번 같다.
시뮬레이터에서 설계한 정책은 실시간에서 이기지 못했다. 사이클롭스 두 마리가 다가오면 물러서는 정책은 초기 시뮬레이터에서 클리어당 물약을 약 4개 아꼈다. 그러나 실시간처럼 몬스터가 기사를 둘러싸도록 수정하자 절약량은 약 1개(5%)로 줄었고, 실제로는 기본 규칙보다 물약을 1.4개 더 썼다. 차이는 통계적으로 유의하지 않았다. 과거의 실시간 승리는 vBot 치료 기능이 함께 켜진 실행에서 나왔다.
규칙 정책은 충분한 반복 실행에서 vBot과 대등했다. 사전 등록한 PR-9에서 50회씩 비교했을 때 Spiral 규칙 정책은 사이클롭스 클리어당 물약 12.5개, vBot은 14.7개였다(t=-3.8). 차이는 첫 10초에만 나타났다. Canary는 플레이어가 이동·회전·대화·아이템 사용을 하면 로그인 보호를 끝내며, vBot은 그렇게 했지만 우리 프로브는 하지 않았다. 그 구간에서 vBot은 9.1회, 프로브는 1.6회 맞았다. 이후 받은 타격은 각각 60.1회와 60.4회였다. 양쪽 모두 보호를 끝낸 PR-11에서는 물약 14.4개와 14.8개로 차이가 나타나지 않았고(t=-0.6), 받은 타격도 69.1회와 69.2회로 같았다.
세 Spiral 정책의 실시간 물약 사용량도 규칙 12.5개, ReachFirst 12.3개, 후퇴 12.2개로 비슷했다. 후퇴 정책은 nExBot보다 약간 나아 보였지만, nExBot이 로그인 직후 대화하는 규칙이 결과의 약 절반을 설명했다. 양쪽의 보호를 끝내고 로그인 2.5초 뒤 시작한 PR-12에서는 후퇴 12.75개, nExBot 13.93개였지만 차이가 확인되지 않았다(t=-1.88, 차이 -1.18, 구간 -2.42~0.07). nExBot은 경기장 보정 세 가지를 적용해 실행했다.
현재까지 시도한 모든 상황(개활지·복도·방·경기장·사이클롭스와 트롤 혼합·물약 한도·재생성 사냥)에서 조정된 임계값 규칙은 신경망 및 학습 정책과 같거나 더 높은 점수를 냈다. 재생성 사냥터에서는 다음 생성 지점을 쓸어 담는 규칙이 60초 재생성 조건에서 고정 경로와 진화 정책을 모두 앞섰지만, 30초 조건에서는 그렇지 않았다. 한 번에 상대할 수 있는 수보다 몬스터가 많으면 조정된 순찰 봇이 앞서고, 후퇴 규칙은 비용을 낮추는 대신 경험치를 포기한다. 기사 두 명은 공통 규칙을 함께 따르는 편이 가장 좋았지만, 초기 실시간 협동 사냥은 첫 모델의 예측을 확인하지 못했다. 실시간에서는 물약 5.1개와 처치 16.6회, 모델에서는 7.56개와 15.36회였다. 모델이 모든 사이클롭스를 첫 기사에게 보냈기 때문이다. Canary의 표적 순서(마지막으로 접속한 기사를 먼저 표적으로 삼고, 이후 기사는 맵 스캔 순서로 처리)를 반영하자 물약과 피해 분배는 맞았지만 트롤 처치가 사냥당 약 한 마리 부족해 협동 순찰 결과를 다시 실행하기로 했다.
모델 충실도와 GPU
충실도 기록은 각 규칙을 Canary 소스 또는 실시간 측정에서 가져와 양쪽에 대조한다. 기사에게 들어가는 사이클롭스 타격은 모델에서 적중당 34.97, 최대 86이며, 장비를 갖추고 포지 효과를 끈 실시간은 33.6, 최대 86이었다. 2026년 10월 20일 PR-12의 적중 5204회 분포는 모델의 충전된 방어 타격 분포와 맞았다(17 자유도에서 카이제곱 17.1). 방어 충전이 적용된 타격은 실시간 약 94.5%(구간 90.7~97.4%), 혼잡한 모델 전투 약 82%였다.
사냥꾼 화살 피해는 모델 40.57, 실시간 39.58(적중 518회, 최대 87)이었다. 모든 실시간 사냥꾼 타격은 화살이었다. 기사에서 트롤로 들어가는 피해는 모델 9.37, 실시간 9.35였다. 레벨 30 사냥터의 트롤 비치명타는 모델 24.89, 실시간 107회 타격에서 24.02였다. 레벨 30·도끼 기술 60인 기사의 사이클롭스 타격은 모델 23.10, 최대 66, 실시간 2427회에서 22.52, 최대 64였다. 각 분포 적합도 수치와 분석 파일은 저장소의 충실도 표에 기록돼 있다.
기사의 이동은 기본 모델 650ms다. 실시간 프로브의 후퇴 걸음은 경기장 지형에서 700~725ms였고 정책 판단에 제한됐다. Canary 공식에 따른 레벨 30 기사의 직선 걸음은 클라이언트 속도 139에서 486ms에 폴링·이동 지연이 더해져 서버 기준 558ms였다. 사이클롭스 직선 이동은 실시간 701~715ms, 대각선은 직선의 3배(2109ms 대 710ms)였다. 지형 이동 속도는 서버 맵을 사용한다. 경기장 지형 속도는 160으로 잔디보다 8% 느리고, 도로는 100이다. 걸음 비용은 출발 타일의 속도를 따른다. 맵 지형은 반경 45를 사용하며, 실시간 클라이언트 스캔과 252칸 중 251칸이 일치했다.
재생성 모델 respawning_like_canary는 처치된 몬스터가 생성 지점의 정리 확인 30초, 생성 시간, 순간이동 효과 4.2초 뒤 돌아오도록 한다. 생성 시간이 60초면 총 94.2초다. 다만 사냥터 실험의 일반 설정은 60초 재생성을 사용했다. 보호 구역은 맵에서 표시된 타일로 나타내며, 모든 생물의 이동을 막지만 화살은 막지 않는다. 순간이동 타일과 층 변경은 벽처럼 취급한다. 행동은 250ms마다 하나씩 허용하고, 사망 여부를 기사 행동 전에 확인한다. 두 생물은 같은 타일을 공유하지 않으며 경로 탐색은 점유 타일을 피해 간다.
경기장 경로 탐색은 직선 10, 대각선 25의 Canary A* 비용과 다른 생물을 장애물로 반영한다. 사냥터는 직선 걸음만 쓰는 최단 경로를 사용한다. 실시간 검사에서 벽 뒤의 사이클롭스는 5회 모두 10~12초 대기 뒤 라우터가 예측한 직선 경로를 탔다. 원거리 몬스터는 표적 거리 바깥에서는 생물 판단 주기당 최대 한 걸음, 안에서는 최대 속도로 거리를 유지한다. 기사와 5~6타일 떨어진 사냥꾼의 속도는 실시간 초당 0.83~0.93타일, 모델 0.91~1.00타일이었다. 서버 측 원인은 아직 추적되지 않았다.
사냥꾼 클리어율은 10월 22일 채택한 모델 묶음에서 100회 중 77회로 예측됐고 PR-18은 20회 중 14회, PR-19는 20회 중 15회로 유지됐다. 그 전 묶음은 100회 중 99회를 예측해 실시간 25회 중 16회와 맞지 않았다. 기사가 직전 틱의 시야만 보는 규칙이 예측을 크게 바꿨다. 실험실에서는 사냥꾼 이동 전 같은 틱에 기사가 조준하거나 행동하면 도주 걸음이 먼저 막힌다. 후퇴 경주와 사냥꾼 도주를 함께 맞추려면 틱 안의 사건 순서를 더 세밀하게 다뤄야 한다.
모델은 몬스터의 첫 10초 대기, 대기 중 무작위 이동, 공격 간격, 표적 획득 뒤 첫 공격, 기사 걸음 뒤 공격 취소 등을 규칙으로 반영한다. 실시간 모델 mirroring_the_live_arena는 이러한 요소를 켜고, live_retreat_tactic은 프로브와 같은 후퇴 걸음을 쓴다. 이후 현재 경기장에 맞춘 mirroring_the_current_arena는 몬스터가 판단 주기에만 경로를 다시 계산하고 공격 가능한 공격 주기에만 공격하도록 했다. 규칙을 측정 전에 작성하는 방식으로 PR-11·12·15의 오차 제곱합은 36.9에서 12.6으로 줄었다. 새로운 40회 실행에서 규칙 정책은 실시간 14.35개, 모델 14.63개(t=-0.43)였지만 후퇴 정책은 실시간 12.45개, 모델 13.74개(t=-2.39)로 맞지 않았다. 기사 이동 속도, 몬스터의 춤걸음, 타일 지형에 따른 이동 공식, 클라이언트가 한 틱 전 본 화면을 쓰는 규칙을 추가한 뒤 PR-17에서 규칙 정책은 13.90 대 14.55, 후퇴 정책은 13.25 대 12.81로 맞았다.
다중 생물 시뮬레이터는 2026년 10월 20일부터 WGSL에서도 비트 단위로 일치한다. GPU 테스트가 반환한 상태를 무시하던 Cells 문제를 고친 뒤 28개 GPU 대응 테스트가 모두 통과했다. 테스트에는 전체 트롤 사냥, 경기장 사이클롭스 클리어 5회, 최단 경로 탐색과 임시 배열을 사용하는 사냥터 5분 실행이 포함된다. GPU 병렬 실행은 시드 하나를 스레드 하나에 배정하며 모든 결과가 C와 정확히 일치한다. 실행 시작 비용은 약 4초이고 이후 경기장 클리어당 약 0.23ms로, C 코어 하나의 1.6ms보다 빠르다. 시작 비용을 고려하면 실행당 약 4000회 클리어부터 GPU가 유리하다. 큰 작업은 1024개 단위로 나눠 실행하며, 16384개 작업에서 멈추던 WGSL-LANES-LARGE-DISPATCH-HANG 문제는 pack-1e 컴파일러에서 수정됐다.
시뮬레이터 실험
실험 결과는 훈련 시드로 조정하고 보류 시드로 평가한다. 시드 블록은 타입으로 구분해 보류 시드에 맞춘 정책은 컴파일되지 않는다. 주장은 처치 수와 수익의 파레토 우위 또는 시간 제한 내 비용으로 판단한다. 수익은 획득한 골드에서 물약당 50gp, 사망당 14000gp를 반영한다. 무작위 정책은 매 판단마다 물약 사용·교전·무작위 타일 이동·대기를 같은 확률로 선택한다. 보류 시드에서 사냥터 경험치 54310에 -115만 gp를 기록했고, 경기장 클리어에는 94초와 물약 72개가 들었다. 서버 제한은 최대 초당 물약 한 개이며, 모든 규칙 정책보다 결과가 낮았다.
- 트롤 세 마리 무리 20개 시드에서 현재 표적을 먼저 처치하면 330마리를 잡았다. 사정거리 안의 적을 공격하면 75마리 처치와 381회 도주에 그쳤다. 실시간 클라이언트는 공격 순서를 바꿔 트롤 세 마리를 모두 잡았고 이전 순서는 한 마리만 잡았다. 추격 정책은 356마리, 제자리 정책은 34마리를 처치했다.
- 개활지 사이클롭스 무리에서 회복 임계값 130 미만은 사망했고 170 이상은 950마리 처치로 같았다. 동굴 봇에서 시작해 회복 임계값 160으로 조정한 신경망만 같은 955마리 처치에서 1550gp 더 벌었다. 몬스터 시야가 11타일이라 연을 날리는 정책은 시야 밖으로 나가게 해 300마리만 처치했다.
- 지형이 결과를 크게 바꿨다. 한 타일 복도에서 같은 동굴 봇은 사이클롭스 세 마리를 물약 6.5개, 사망 없이 잡았다. 개활지에서는 20회 중 물약 15.3개와 사망 3회였다. 복도가 있는 방에서 훈련 시드 100개로 진화시킨 규칙(ReachFirst, 공격자 수에 따라 회복 임계값 223+3, 공격자 세 명이면 후퇴)은 보류 시드 100개에서 조정된 동굴 봇보다 우세했다. 처치 수는 946 대 942, 수익은 -288217gp 대 -477181gp였다.
- 경기장 지점의 보류 클리어 100회에서, 조정된 동굴 봇보다 시간 15% 이내에 가장 싼 클리어를 찾은 규칙은 ReachFirst, 회복 임계값 88+공격자당 26, 몬스터 한 마리가 닿으면 후퇴를 선택했다. 물약은 1070개 대 동굴 봇 1702개(회복 임계값 90), 사망은 1회 대 0회, 시간은 95.6초 대 90.1초였다. 비용은 낮지만 느려 지배적이지는 않았다. 도로 속도를 적용하기 전 반경 30 맵에서는 회복 임계값 96+공격자당 8을 선택해 물약 1069개, 사망 0회, 90.9초를 기록했다.
- 혼합 야영지(사이클롭스 한 마리와 트롤 두 마리)에서 야영지별로 조정한 동굴 봇은 보류 클리어 100회에 물약 85개와 37.7초를 썼다. 종류를 모른 채 진화한 규칙은 사망 없이 물약 74개, 37.6초로 우세했다. 종류를 아는 규칙은 68개였지만 한 번 사망했다. 사이클롭스 세 마리용 규칙은 190개를 썼고, 공격·교전 중인 몬스터만 세는
policy.temperate(트롤은 도주하고 사이클롭스는 도주하지 않음)는 135개로 낮췄다. - 사냥터에는 사이클롭스 두 마리와 트롤 네 마리가 60초마다 재생성된다. 경기장 주변 서버 맵에서 5분 사냥, 보류 시드 100개를 사용했다. 한 타일씩 탐욕적으로 걷는 봇은 벽에서 막혀, 기사와 몬스터 모두 직선만 허용하는 최단 경로를 썼다. 대각선은 직선 세 걸음 비용이며 Canary A*와 일치한다. 모든 걸음 비용에는 현재 지면 속도를 적용한다. 도로 속도 100은 경기장 지면 160보다 1.6배 빠르며 PC-1 실시간 측정과 사전 등록 PC-2로 확인했다. 회복 임계값 120인 동굴 봇은 시작 지점 대기 시 경험치 104920, 직접 그린 경로 108270, 생성 지점 순환 114470, 도로를 활용한 훈련 경로 119280, 살아 있는 또는 다음 생성 예정 몬스터를 찾아 이동하는 규칙 119950을 얻었다. 동쪽 건물 보호 구역은 2026년 10월 20일부터 벽으로 처리했다. 재생성 시간을 읽는 규칙은 60초에서 앞서고 120초에서는 동률이지만, 30초에서는 고정 경로가 앞섰다(직접 경로 133170, 왕복 경로 133200, 순환 규칙 126980). 최선의 이동 방식은 재생성 시간에 따라 달랐다.
- 사냥터의 사이클롭스 여섯 마리는 기사가 한 번에 싸울 수 있는 수보다 많다. 보류 사냥 100회에서 시작 위치를 지키는 정책(회복 임계값 100)은 경험치 112700, 사망 2회, -211081gp였다. 생성 지점을 순찰하는 정책(임계값 130)은 경험치 126900, 사망 3회, -296687gp로 경험치가 가장 많았다. 순찰하며 공격자 두 명일 때 물러나는 규칙은 경험치 121050, -166786gp, 사망 0회였다. 경험치는 약 5% 적지만 비용이 44% 낮아지는 선택이지, 한 정책이 모든 목표에서 낫다는 뜻은 아니다.
- 기사 두 명이 사이클롭스 여섯 마리 사냥터에서 협동할 때 두 기사는 같은 코드를 쓰고, 몬스터는 더 가까운 기사를 추격·공격한다. 함께 순찰하면 보류 사냥 100회에서 경험치 259350, -180187gp였다. 사냥터를 둘로 나눠 맡으면 경험치 248550, 비용은 30% 더 높았다(-233638gp). 각 기사가 혼자 사이클롭스를 상대하기 때문이다. 협동용으로 진화한 규칙(회복 임계값 117+공격자당 6, 후퇴하지 않음)은 경험치 261750, -180890gp로 1% 이내였으며 하나의 공통 규칙으로도 협동을 구현했다.
- 학습 정책은 회복·후퇴·표적 선택·이동 가중치를 갖는 유전자 12개 정책이다. 진화 규칙을 재현하는 시작 유전체에서 640회 평가했지만 더 나은 결과를 찾지 못했다. 물약 예산 6개에서는 사망과 물약 수가 같고 5.6% 빨랐지만 비용 개선 기준 5%에 못 미쳤다. 재생 사냥에서도 물약이 약 40개를 넘으면 예산이 제약하지 않고, 그보다 적으면 떠날 시점만 중요해 한 개 숫자의 규칙으로 표현됐다.
실시간 경기장 비교
실시간 경기장의 PR-4는 2026년 10월 14일 수정된 경기장에서 시행했다. 사이클롭스 클리어, BENCHMARK 팩 v1, 매 실행 전 장비 복구, 모든 경쟁자에 같은 250ms 행동 제한과 100ms 판단 틱, 회복 임계값 160, 경쟁자당 30회, 번갈아 실행했다. 모두 클리어했고 사망과 경기장 실패는 없었다. 이 실행은 로그인 보호 수정 전이라 vBot만 로그인 시 보호를 끝냈고 프로브는 그렇지 않았다. 따라서 vBot은 클리어당 약 7회 더 맞았다.
| 정책 | 물약 | 클리어 시간 | 받은 피해 |
|---|---|---|---|
| Spiral 규칙 | 11.5 (표준편차 2.5) | 87.6초 | 2029 |
| Spiral 후퇴(시뮬레이터 설계) | 12.9 (표준편차 3.2) | 91.3초 | 2217 |
| vBot 4.8 | 14.0 (표준편차 2.6) | 92.7초 | 2397 |
사전 등록한 후퇴 대 vBot 비교는 차이가 확인되지 않았고(t=-1.45), 후퇴 대 규칙도 차이가 없었다(t=1.82). PR-8에서 규칙과 vBot을 각각 30회 새로 비교했을 때 물약은 12.9 대 14.2개로 차이가 확인되지 않았다(t=-1.47). PR-4의 규칙 정책 11.5개는 재현되지 않았다. PR-9에서 50회씩 비교하면 12.5 대 14.7개로 유의한 차이가 있었지만(t=-3.80), 클리어 시간은 88.7 대 87.9초, 피해는 2145 대 2479였다. 물약 차이는 vBot이 처음 10초 안에 로그인 보호를 끝낸 데서 전부 발생했다. 양쪽 보호를 끝낸 PR-11에서는 14.4 대 14.8개로 차이가 없었다(t=-0.58).
PR-3a에서 후퇴와 nExBot 4.0.4를 20회씩 비교하면 물약 12.2 대 14.6개(t=-2.14), 시간 90.9 대 88.4초, 피해 2030 대 2421이었다. 기록 20개 중 16개와 18개가 일치했고 사망은 없었다. 양쪽 보호를 끝내고 시작 시점을 맞춘 PR-12(각각 40회)에서는 물약 12.75 대 13.93개로 차이가 확인되지 않았다(t=-1.88). 시간은 90.3 대 89.2초, 피해는 2230 대 2369였고 사망은 없었다. 후퇴 실행 한 건은 경기장 동쪽 보호 구역에 서서 클리어하지 못해 이후 정책에서 보호 구역 타일로 들어가지 않도록 했다. 무작위 대조군은 10회 실행에서 102.7초와 물약 94.1개로 모든 경쟁자보다 낮았다.
오류가 있던 경기장의 과거 결과도 기록으로 남겼다. 당시 spiral-* 실행과 함께 vBot의 HealBot·TargetBot이 켜져 있었다. 규칙 대 vBot 6회씩은 14.7 대 14.8개로 동률, 규칙의 회복 임계값을 120으로 낮춘 10회씩 비교는 12.8 대 13.2개로 동률이었다. 후퇴 대 규칙은 각각 23~24회, 12.6 대 15.5개로 후퇴가 앞섰다(t=-3.89, 피해 2125 대 2639, t=-4.20, 클리어 시간 동일). 후퇴에서 ReachFirst와 CurrentFirst 표적 순서를 18회씩 비교한 12.7 대 13.4개는 차이가 없었다. 후퇴 대 vBot 세 차례 합산은 47 대 42회, 12.6 대 13.7개였고 동률 또는 약간 우위였다(t=-1.89). 첫 비교만 유의해 보였고 이후 동률로 돌아가, 이후 비교는 실행 횟수를 고정해 사전 등록한다.
초기 경기장 측정에는 포지가 몬스터 능력치를 높이는 문제, 사망 뒤 장비 미복구, 닫힌 배낭을 무시하는 vBot HealBot, 프로브의 250ms 판단, 후퇴 중 추격 모드 유지, 10초마다만 표본을 모아 vBot 클리어 시간을 약 5초 올림하는 문제 등이 있었다. 프로브는 apps/arena/, 경기장 스크립트는 live/에 있다. 실행 대상은 저장소 밖 로컬 폴더의 Canary 3.6.1과 OTClient Redemption 4.1이며 화면 밖·음소거 상태로 구동한다.
저장소와 실행 방법
저장소 구성에서 src/는 Spiral 패키지와 규칙·타입 도메인·시뮬레이터·테스트를 담는다. docs/에는 계획, 사전 등록과 결과를 포함한 벤치마크, 모델링 기록과 선행 자료가 있다. apps/arena/에는 Spiral로 작성하고 Lua 백엔드로 컴파일하는 OTClient 프로브가 있다. 계층은 Lua 상태(lua.spi), 타입 클라이언트 바인딩(client.spi), 프로브 수명 주기(probe.spi), 공용 실행 모듈(scoreboard·observer·adjacency), 경쟁자·무작위·vBot·nExBot·소환·스캔·경로·측정·걸음 프로브다. build.ps1은 target/arena/<probe>.lua를 만들며 -ProbeBody <probe>로 하나를 선택하고 오래된 결과를 다시 만든다.
apps/map/은 Canary 맵을 읽고 생성된 지형 정의 및 지역 덤프를 results/에 쓰는 Rust 도구다. apps/predict/은 현재 모델 묶음의 정책별 사이클롭스 클리어, 사냥꾼 클리어, 사냥터 결과를 출력하는 C 진입점이다. live/에는 동등성 계층, 봇 보정과 설정, 실행·검사 스크립트, 시나리오 자산, 블록 실행기가 있다. analysis/에는 eoie로 아직 표현할 수 없는 사전 등록 분석 스크립트가 있으며 해당 기능이 eoie에 추가되면 삭제한다. 새 사전 등록의 방법은 새 스크립트가 아니라 BENCHMARK 테스트 행의 eoie 명령으로 기록한다. results/는 BENCHMARK.md가 인용하는 실시간 표, 맵 스캔 및 맵 도구 덤프를 보관한다. scripts/에는 init.ps1, build.ps1, publish.ps1, workflow.ps1, 예측용 predict.ps1, 규칙 D16에 따른 후보 점수화 score.ps1이 있다. .github/workflows/gh-pages.yml은 Ubuntu와 Windows에서 Spiral Cells 실행기로 모든 테스트 파일을 돌린 뒤 게시 트리를 만든다.
실행 안내: 설정에는 pwsh scripts/init.ps1을 실행한다. 이 명령은 Spiral을 포함하는 polyglot을 저장소 옆에 복제하고 둘을 deps/에 연결하며, Ubuntu에는 Mesa 소프트웨어 Vulkan을 설치하고 WGSL 실행기를 target/에 빌드한다. -fast 1은 연결과 누락된 항목 빌드만 수행한다.
테스트는 pwsh scripts/build.ps1로 실행한다. src/*.spi의 테스트를 deps/spiral/apps/cells/spi/run_notebook.ps1로 돌리고, 실패·미지원·건너뜀·누락 행이 없으며 모든 테스트가 실행되고 통과해야 성공한다. -Files geometry,views로 일부만 실행할 수 있다. 노트북 출력은 Git에서 제외된 notebooks/에 기록되며 scripts/publish.ps1로 게시된다.
표준 검사는 빌드 전에 SpiralCompiler format src apps/arena apps/map --check를 실행해 서식 변경이 있으면 멈춘다. 로컬에서는 eoie standards src apps/arena apps/map으로 src/standards.spi의 규칙도 검사한다. 주석 줄 금지, LF 줄바꿈, 모든 테스트 위의 대상 표기, 120열 제한, 정수 전용 모듈 26개에서 부동소수점 금지가 포함된다.
실시간 경기장에는 저장소 밖의 Canary, MariaDB, OTClient 및 로그가 필요하다. 기본 위치는 ~/tibia-local 또는 TIBIA_WORLD이며, MariaDB 실행 파일은 TIBIA_MARIADB_BIN으로 지정하고 기본값은 scoop 경로다. 예시 실행은 다음과 같다.
pwsh live/run-arena.ps1 -Runs 1 -Monster cyclops -MonsterCount 3 -Level 30 -AxeSkill 60 -HealBelow 160 -StrikeAbove 0 -FullExperience 675 -Competitors spiral-policy,vbot -Out results/arena-results-try.tsv
사냥터는 생성 지점을 바꾸고 고정 시간 동안 실행한다.
-Scenario hunting-ground -SpawnFile live/hunting-ground-spawns.xml -KnightAt 1936,1336 -RunMs 300000 -MonsterCount 0 -FullExperience 1000000
nExBot은 라이선스 문제로 저장소에 포함되지 않는다. -Competitors nexbot은 월드의 bots/ 아래에 설치된 nExBot을 기대한다. 사전 등록 블록은 pwsh live/block.ps1 -Ledger <ids>로 실행한 뒤 target/ledger의 eoie 작업 복사본에서 eoie experiment analyze로 분석한다. 기록은 BENCHMARK 섹션이며, 테스트를 작성한 직후 eoie experiment register target/ledger ...로 등록한다.
문서와 원칙
문서의 BENCHMARK.md는 OT Agent Arena의 충실도·기준선·시나리오·측정값·사전 등록·공개 방식을 설명한다.
프로젝트 원칙은 한 번에 새 요소 하나만 도입하고 각각 별도 벤치마크를 두는 것이다. 충실도 검증 뒤 훈련을 하고, 훈련 뒤 규모를 키운다. 같은 시드의 CPU·GPU 실행은 정수 시뮬레이션과 카운터 기반 난수로 비트 단위까지 같아야 한다. 모든 주장은 기준선·무작위 대조군·예산을 밝히며 수사만으로 승격하지 않는다. CipSoft에서 유래한 맵·스프라이트·아이템 데이터는 로컬에 두고, 경기장은 코드·시나리오 명세·시드만 공개한다.
테스트 대상 표기는 ///> c가 규칙 테스트의 의미상 기준, ///> wgsl이 GPU 시뮬레이터, ///> lua가 실시간 클라이언트, ///> rust가 시뮬레이터 기준 시드에 쓰인다. Rust 컴파일은 테스트당 약 10초가 걸려 2026년 10월 13일 전체 테스트 1164초 중 662초를 차지했다. 모듈의 static 테스트는 타입 검사만 한다. Tibia에서 필요한 워크플로 기능이 빠졌다면 우회 코드를 먼저 만들지 않고 Cells·컴파일러·eoie의 백로그 항목으로 등록한다. 모든 백로그 항목은 지원하는 주장이나 이정표를 밝혀야 하며, 어느 쪽도 지원하지 않으면 완료하지 않고 폐기한다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요