Game Scripting
By: Nicholas Haines
Aurora Neverwinter Toolset
What is Scripting?

Interpreted Language
– As the game runs
Advantages
Ease of use
 Makes the game more data driven

– Instead of hard coding into game engine

Allows for in-game “tweaking”
– Quick results
– Does not require a recompile
Allows user modability
 Game can be patched at a later date
 Many publicly available scripting languages

Disadvantages

Performance
– Not noticeable most of the time in
real world performance

Automatic memory management
– Can cause problems if it interrupts a
command or takes awhile to complete

Poor debugging tools
– Some languages don’t give warnings
– Tends to be very hard to find the errors
Lua In The Industry

Ease of Use
– for non-programmers

Falko Poiker
Speed
– don’t slow down the game

Size
– Lua executable is ~ 160kb

Well Documented
– Lua documentation is lacking

Flexible
– Clean and flexible interface
Jobs
Optimizing Script Execution
Using Patterns
Object: Reduce the number of instructions
 Look for patterns in the opcode output

– Replace with optimized version

Check for addresses calculated multiple
times and save to a spare register
– Replace matching with reference to register

May shorten code by up to 50%
assuming decoding script is the
bottleneck of the virtual machine [VM]
Non-Branched, Constant Scripts
Native function calls can be intercepted
inside the VM
 Store as a function pointer along its
arguments
 Big list of stored functions is called an

Execute List

Will now traverse execute list instead of
having to interpret the opcode again
Branched Scripts





Conditional jumps cannot be
predicted
A Jump Table can be used to
decrease decode time during
execution
Contains the offset of native
opcode executing specific script
opcode
Use pure jump table opcodes for
most common instructions
Combine jump table/parse for less
common instructions to reduce the
table size
Note: jump table values change whenever
the 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]
~3 cycles
;get contents of vm register 1 into ebx
mov ebx, [ecx+4]
~3 cycles
;solve indirection
mov [eax], ebx
~3 cycles
;increment vm instruction pointer
add edx, 4
~1 cycles
;transfer program control to next opcode
jump [edx]
~3 cycles
Branched into Non-Branched
Monster::PlayerSpotted(bool hear_player, bool see_player, float* pos)
{
if(!see_player)
{
if(hear_player)
{
//we have heard something..check out
//situation..keep an eye on the place
FocusAttention(pos); //native function
}
else
{
//someone told us about the
//player (monster friend or so)
//let's help our friends
WalkTo(pos); //native function
}
}
else
{
//we can see the enemy..let's kill him!
ShootAt(pos); //native function
}
}


Generates each possibility
and removes branching
Code to the left becomes:
Monster::PlayerSpotted(bool hear_player=true,
bool see_player=false,
float* pos)
{
FocusAttention(pos);
}

This can be optimized
using execution lists
Advanced Script Debugging
Exchanging Debug Information

Debugger creates a new processes that uses
the VM to execute scripts

VM sends string messages to Debugger

VM needs memory buffers for the Debugger
to write to
breakpoint hit
Virtual
Machine
access violation
Debugger
update breakpoints
Useful Features





Debug information
Handling Breakpoints
Variable Watch
Call Stack
Step-by-Step
Execution





Step-by-Step
Assembly Execution
Register Watch
Memory Watch
Step-by-Step HighLevel Execution
Step Over Execution
Adding Error Reporting
Create A Parser For Your Script

Use tools like Lex and Yacc

Since mostly nonprogrammers use the
scripting language, make meaningful error
messages.
A Simple Language
Example code:
int x;
int y;
y = 0;
x = SomeFunction() - 5;
if( x > OtherFunction() )
y = 3;

Possible Errors
–
–
–
–
–
–
–
Semicolon missing
Parentheses missing
Unrecognized characters
Unrecognized keyword
Function misspelled
Undeclared variable
Variable declared more
than once
Reporting with yyerror()
Prints “syntax error” to standard output
 Overwrite yyerror() with a useful version
 Derive a custom scanner function
 Print formatted error messages to a
specified error file

– Include line number and copy of the line

This can be stored as a log or displayed in
another application
Identifying Specific Errors

Unknown Character Errors
.
yyerror(“Error: Unknown character ‘%c’ “, *yytext);
Append grammar to trap missing semicolon
 Do the same to catch unrecognized
functions
 Undeclared and Redeclared Variables

– Parser must check variable table to see if the
variable has been previously declared
References

AI Game Programming WISDOM 2
Sections 9.1-9.3

Game Dev Articles:
Scripting by Falko Poiker
http://www.relic.com/industry/articles/scripting.php

The Secret Life of Game Scripting
By Brian Hook
http://www.bookofhook.com/Article/GameDevelopme
nt/TheSecretLifeofGameScript.html
Descargar

Game Scripting - Lehigh University