Game Scripting By: Nicholas Haines. Aurora Neverwinter Toolset.
-
Upload
francis-higgins -
Category
Documents
-
view
222 -
download
0
Transcript of Game Scripting By: Nicholas Haines. Aurora Neverwinter Toolset.
Game ScriptingGame Scripting
By: Nicholas Haines
Aurora Neverwinter Toolset Aurora Neverwinter Toolset
What is Scripting?What is Scripting?
Interpreted Interpreted LanguageLanguage– As the game runsAs the game runs
AdvantagesAdvantages
Ease of useEase of use Makes the game more data drivenMakes the game more data driven
– Instead of hard coding into game engineInstead of hard coding into game engine Allows for in-game “tweaking”Allows for in-game “tweaking”
– Quick resultsQuick results– Does not require a recompileDoes not require a recompile
Allows user modability Allows user modability Game can be patched at a later dateGame can be patched at a later date Many publicly available scripting languagesMany publicly available scripting languages
DisadvantagesDisadvantages
PerformancePerformance– Not noticeable most of the time inNot noticeable most of the time in
real world performancereal world performance Automatic memory managementAutomatic memory management
– Can cause problems if it interrupts a Can cause problems if it interrupts a command or takes awhile to completecommand or takes awhile to complete
Poor debugging toolsPoor debugging tools– Some languages don’t give warningsSome languages don’t give warnings– Tends to be very hard to find the errorsTends to be very hard to find the errors
Lua In The IndustryLua In The Industry Ease of UseEase of Use
– for non-programmersfor non-programmers SpeedSpeed
– don’t slow down the gamedon’t slow down the game SizeSize
– Lua executable is ~ 160kbLua executable is ~ 160kb Well DocumentedWell Documented
– Lua documentation is Lua documentation is lackinglacking
Flexible Flexible – Clean and flexible Clean and flexible
interfaceinterface
Falko Poiker Falko Poiker
JobsJobs
Optimizing Script ExecutionOptimizing Script Execution
Using PatternsUsing Patterns Object: Reduce the number of instructionsObject: Reduce the number of instructions Look for patterns in the opcode outputLook for patterns in the opcode output
– Replace with optimized versionReplace with optimized version Check for addresses calculated multiple Check for addresses calculated multiple
times and save to a spare registertimes and save to a spare register– Replace matching with reference to registerReplace matching with reference to register
May shorten code by up to 50%May shorten code by up to 50%assuming decoding script is theassuming decoding script is the
bottleneck of the virtual machine [VM]bottleneck of the virtual machine [VM]
Non-Branched, Constant Non-Branched, Constant ScriptsScripts
Native function calls can be Native function calls can be intercepted inside the VMintercepted inside the VM
Store as a function pointer along its Store as a function pointer along its argumentsarguments
Big list of stored functions is called an Big list of stored functions is called an Execute ListExecute List
Will now traverse execute list instead Will now traverse execute list instead of having to interpret the opcode of having to interpret the opcode againagain
Branched ScriptsBranched Scripts Conditional jumps cannot be Conditional jumps cannot be
predictedpredicted A A Jump TableJump Table can be used to can be used to
decrease decode time during decrease decode time during executionexecution
Contains the offset of native Contains the offset of native opcode executing specific opcode executing specific script opcodescript opcode
Use pure jump table opcodes Use pure jump table opcodes for most common instructionsfor most common instructions
Combine jump table/parse for Combine jump table/parse for less common instructions to less common instructions to reduce the table sizereduce the table size
Note: jump table values change Note: jump table values change wheneverwhenever
the VM’s code is changedthe VM’s code is changed
Example to be decoded mov [vm_reg0], vm_reg1
(using x86 asm)
;get contents of vm register 0 into eax mov eax, [ecx+0];get contents of vm register 1 into ebx mov ebx, [ecx+4];solve indirection mov [eax], ebx;increment vm instruction pointer add edx, 4;transfer program control to next
opcode jump [edx]
~3 cycles
~3 cycles
~3 cycles
~1 cycles
~3 cycles
Branched into Non-Branched into Non-BranchedBranched
Monster::PlayerSpotted(bool hear_player, bool see_player, Monster::PlayerSpotted(bool hear_player, bool see_player, float* pos)float* pos)
{{
if(!see_player)if(!see_player)
{{
if(hear_player)if(hear_player)
{{
//we have heard something..check out//we have heard something..check out
//situation..keep an eye on the place//situation..keep an eye on the place
FocusAttention(pos); //native functionFocusAttention(pos); //native function
}}
elseelse
{{
//someone told us about the//someone told us about the
//player (monster friend or so)//player (monster friend or so)
//let's help our friends//let's help our friends
WalkTo(pos); //native functionWalkTo(pos); //native function
}}
}}
elseelse
{{
//we can see the enemy..let's kill him!//we can see the enemy..let's kill him!
ShootAt(pos); //native functionShootAt(pos); //native function
}}
}}
Generates each Generates each possibility and removes possibility and removes branchingbranching
Code to the left Code to the left becomes:becomes:
Monster::PlayerSpotted(bool hear_player=true,Monster::PlayerSpotted(bool hear_player=true,
bool see_player=false,bool see_player=false,
float* pos)float* pos)
{{
FocusAttention(pos);FocusAttention(pos);
}}
This can be optimized This can be optimized using execution listsusing execution lists
Advanced Script DebuggingAdvanced Script Debugging
Exchanging Debug Exchanging Debug InformationInformation
Debugger creates a new processes that Debugger creates a new processes that uses the VM to execute scriptsuses the VM to execute scripts
VM sends string messages to DebuggerVM sends string messages to Debugger
VM needs memory buffers for the VM needs memory buffers for the Debugger to write toDebugger to write to
VirtualVirtual
MachineMachineDebuggerDebugger
breakpoint hitbreakpoint hitaccess violationaccess violation
update breakpointsupdate breakpoints
Useful FeaturesUseful Features
Debug informationDebug information Handling Handling
BreakpointsBreakpoints Variable WatchVariable Watch Call StackCall Stack Step-by-Step Step-by-Step
ExecutionExecution
Step-by-Step Step-by-Step Assembly Assembly ExecutionExecution
Register WatchRegister Watch Memory WatchMemory Watch Step-by-Step High-Step-by-Step High-
Level ExecutionLevel Execution Step Over Step Over
ExecutionExecution
Adding Error ReportingAdding Error Reporting
Create A Parser For Your Create A Parser For Your ScriptScript
Use tools like Lex and YaccUse tools like Lex and Yacc
Since mostly nonprogrammers use Since mostly nonprogrammers use the scripting language, make the scripting language, make meaningful error messages.meaningful error messages.
A Simple LanguageA Simple Language
Example code:Example code:
int x;int x;
int y;int y;
y = 0;y = 0;
x = SomeFunction() - x = SomeFunction() - 5;5;
if( x > if( x > OtherFunction() )OtherFunction() )
y = 3;y = 3;
Possible ErrorsPossible Errors– Semicolon missingSemicolon missing– Parentheses missingParentheses missing– Unrecognized Unrecognized
characterscharacters– Unrecognized Unrecognized
keywordkeyword– Function misspelledFunction misspelled– Undeclared variableUndeclared variable– Variable declared Variable declared
more than oncemore than once
Reporting with yyerror()Reporting with yyerror()
Prints “syntax error” to standard outputPrints “syntax error” to standard output Overwrite yyerror() with a useful Overwrite yyerror() with a useful
versionversion Derive a custom scanner functionDerive a custom scanner function Print formatted error messages to a Print formatted error messages to a
specified error filespecified error file– Include line number and copy of the lineInclude line number and copy of the line
This can be stored as a log or displayed This can be stored as a log or displayed in another applicationin another application
Identifying Specific ErrorsIdentifying Specific Errors
Unknown Character ErrorsUnknown Character Errors . yyerror(“Error: Unknown character ‘%c’ “, *yytext);. yyerror(“Error: Unknown character ‘%c’ “, *yytext);
Append grammar to trap missing Append grammar to trap missing semicolonsemicolon
Do the same to catch unrecognized Do the same to catch unrecognized functionsfunctions
Undeclared and Redeclared VariablesUndeclared and Redeclared Variables– Parser must check variable table to see if the Parser must check variable table to see if the
variable has been previously declaredvariable has been previously declared
ReferencesReferences
AI Game Programming WISDOM 2AI Game Programming WISDOM 2Sections 9.1-9.3Sections 9.1-9.3
Game Dev Articles: Game Dev Articles:
Scripting by Falko Poiker Scripting by Falko Poiker http://http://www.relic.com/industry/articles/scripting.phpwww.relic.com/industry/articles/scripting.php
The Secret Life of Game Scripting The Secret Life of Game Scripting
By Brian HookBy Brian Hook
http://www.bookofhook.com/Article/GameDevelhttp://www.bookofhook.com/Article/GameDevelopment/TheSecretLifeofGameScript.htmlopment/TheSecretLifeofGameScript.html