350 likes | 471 Views
Scripting and Actions. Robin Burke GAM 376 Fall 2006. Outline. Midterm solutions Scripting Why How Lua language binding to C++ Custom languages Action systems. 1. 2. 3. 4. 5. 6. Midterm solutions: Q1. DFS BFS ID. Q2. Arrive Alignment Evade Obstacle Avoidance. Q3.
E N D
Scripting and Actions Robin Burke GAM 376 Fall 2006
Outline • Midterm solutions • Scripting • Why • How • Lua • language • binding to C++ • Custom languages • Action systems
1 2 3 4 5 6 Midterm solutions: Q1 • DFS • BFS • ID
Q2 • Arrive • Alignment • Evade • Obstacle Avoidance
Q3 • States • Conditions • Graph
Q4 • Preferred velocity • Leading distance • Following distance
Scripting • Two senses of the word • "scripted behavior" • having agents follow pre-set actions • rather than choose them dynamically • "scripting language" • using a dynamic language to make a game easier to modify • The senses are related • a dynamic language • is an excellent tool for working with agent behaviors
Scripted behavior • Write a fixed action sequence • as opposed to something that "make sense" in the game world
Example • fixed trigger regions • when an enemy unit enters this area • send these waiting units to attack • player reaction • build up a big force just outside the trigger area • then attack • Doesn't truly simulate • scouting and preparedness
A better simulated version • Assign a patrol unit • use information to influence production planning • vary depth of patrol with stage of game • Use "expected cost of ignorance" • an idea from surveillance theory
Advantages of scripting • Much, much faster • to apply a simple rule than to run a physical simulation • Easy to write, understand and modify
Disadvantages of scripting • Limits player creativity • Players will try things that "should" work • based on extensive physical intuition • Will be disappointed if they don't • Allow degenerate strategies • players will learn the limits of the scripts • and exploit them • Game will need many scripts • predicting their interactions can be difficult • complex debugging problem
Scripting languages • Scripting languages came into being • so that level designers could design simple behaviors • triggers • level interaction • without having to mess with the game internals • Scripting languages also • enable modding • can be an important factor in the PC game market • witness UnrealTournament, Neverwinter Nights
Issues • Speed • Execution model • Integration • Re-Entrancy
Speed • Always important, esp. for game AI • In most cases • AI scripts will be part of inner game loop • character behavior • event handling
Execution model • Interpreted • Processed bottom-up each time • Compiled • Almost always byte-compiled • compiled into lower level instructions • but not machine instructions • Interpreting byte-code much faster than interpretation • Can remove compiler when distributing code • user can't mess with script internals
Integration • Must be possible to integrate the scripting language with the game • Expose crucial methods and data structures to scripters • Manage script execution from within the game • If possible • avoid translation between data types and calling protocols
Re-Entrant • Re-entrant code can be called safely from multiple processes • Often scripts will be shared among multiple instances of an AI • A script may also need to be suspended and reactivated • to distributed the AI load over multiple frames • Some script sections may not be interruptible • for example, modifying velocity and orientation
Choices • Write your own • more later • Lua • Python • Scheme
Scheme • Lisp variant • lots of parentheses • Pluses • very small implementations exist • very efficient • AI-friendly • no distinction between code and data • Minuses • awkward for non-initiates • less common • (Insert ad for CSC 358 here)
Python • Full-featured language with C-like syntax • used in Civilization IV • Pluses • Large user base • Good integration with C/C++ • Re-entrancy primitives • Minuses • Slow • Interpreter is relatively large
Lua • Relatively stripped-down C-like language • used in many games • Pluses • Excellent integration with C/C++ • Very fast • Small library • Minuses • Weak debugging support • No re-entrancy support
Creating your own • Many developers create their own scripting languages • Pluses • Can be tailored specifically to project needs • Can be extended as necessary • Minuses • Substantial effort • No third-party user base / contributors / tools • (Insert ad for CSC 347, 348 here)
Lua • Buckland uses Lua for the Raven game • mostly to replace his "params.ini" files • eliminates the need for a separate parsing of parameter files • How • simply define variables in a file • load the file into a lua "state" • then use accessors to get the values
Before • params.ini file • TeamName = "MyTeam" • code • entire param loader class and GetNextTokenAsString(); // Skip RedTeam Label RedTeamId = GetNextTokenAsString(); GetNextTokenAsString(); // Skip BlueTeam Label BlueTeamId = GetNextTokenAsString();
After • params.lua file • Bot_MaxHealth = 100 • Bot_MaxSpeed = 1 • Bot_Mass = 1 • in code • script->GetInt("Bot_Mass") • plus minimal interface code importing the lua libraries
Result • Much more flexible system • parameters no longer have to be in order • simple calculations can be embedded in the lua script
How does it work • Two issues • passing data • Lua -> C++ • C++ -> Lua • invoking functions • Lua -> C++ • C++ -> Lua
Basic concept • Stack • Lua and C++ share the "Lua stack" • In each case • calling environment puts information on the stack • transfers control • called environment reads information from the stack • does something • then puts an answer back on the stack • transfers control back • calling environment reads answer from the stack
Data • Lua -> C++ • Assume • we have created a Lua state • pL points to it • we have loaded our parameters file • C++ code lua_settop(pL, 0); // reset the stack lua_getglobal(pL, "Bot_Mass"); if (lua_isnumber(pL, 1)) double mass = (double)lua_tonumber(pL, 1); ...
Function calls • Lua -> C++ • Idea • push some values on the stack • then call the function • get the result from the stack • Example lua_getglobal(pL, "updatePosition"); // the function we're calling lua_pushnumber(pL, posX); // some parameters lua_pushnumber(pL, posY); lua_call(pL, 2, 0); // the call itself
Function calls • C++ -> Lua • Idea • Lua requires a particular function signature • function(lua_state*) • Create a wrapper with this signature • it grabs the data from the state • then calls the relevant function • Register this function in the Lua environment • Call as normal • Details in the book • somewhat ugly and repetitive for lots of functions
Luabind • To the rescue • open source project • version 0.7 now available in public beta • A set of facilities for automatically generating wrappers • Works with C++ classes • Allows class-like object inside of Lua as well
Example • Finite state machine • machine itself written in C++ • states coded in Lua
Wednesday • Soccer Tournament • Must have working code by 5 pm Tuesday • I will compile and test the teams • Your code must be self-contained in a uniquely-named folder inside the SoccerLab folder • You can bring updated code to class • meet in the lab