Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Games Development 2 Scripting for Games CO3301 Week 5 Contents • • • • Why Scripting Scripting Considerations Scripting Languages Python: Language Overview Why Scripting? • Ease of Development – Higher-level – less prone to errors • E.g. no pointers, memory allocation etc. – Less intricate - can be easier to write • By less experienced developers and maybe technical designers • Iteration Time – Much quicker to change and test – No recompilation, change at runtime • Similar rationale to text-based data files Why Scripting? • Scripts as Assets – Possible to regard scripts as a data resource to cut down on the amount of game-specific embedded code • Use scripts to control entity behaviour in particular – Treat like any other resource, e.g. meshes, animations • Script loaded with other entity assets • Script support built into the resource manager – Makes entity behaviour editable outside the compilation process • For example, in a level editor – Allows entity behaviour to be added/modified at a later stage • Post-release modding • Scripting languages can be quite powerful – And customised for particular uses, e.g. AI Scripting Drawbacks • Performance – Scripting languages are often interpreted – Some are part-compiled into bytecode (like Java) • Instructions for a virtual machine – However, still poor performance compared to C++, ten times slower or more • No control of memory management can also cause issues – Dynamic allocation of new variables – Automatic garbage collection – No control over timing, or amount of memory used • Tool support sometimes limited, but much better now • Errors can be hard to spot – usually occur at runtime • Need to write (clumsy) interface to our C++ Scripting Considerations • Performance may not be such an issue – If scripting limited to high-level game logic – Tricky if 1000's of scripted entities though • Don't necessarily need to use scripting languages – A simple, well defined game, with no need for modding • Otherwise, consider language to use based on: – Performance needs, memory footprint, feature-set • Developer can write a custom scripting language – E.g. UnrealScript – Developing a new language is tricky and usually unnecessary only recommended for experts Popular Scripting Languages • Python is a portable, interpreted, object-oriented programming language – Mature, well-used language with clear syntax – Notable for whitespace defining structure – Used on several games, especially MMOs (e.g. EVE) • Also built into Autodesk Maya and Max for plugin development – Large memory use makes it a choice for more heavyweight games • Lua is a lightweight scripting language – – – – Not natively object-oriented Small and simple feature-set Small memory footprint Very widely used, on PC and consoles Python: Language Overview • We will look at Python in this week’s lab – Well suited to PC development • Python is a complete, high-level OO language – Reads a little like psuedo-code • It is dynamically typed – No need to declare variable types • It performs automatic garbage collection – No need to new / delete objects – No pointers • Blocks are defined by indentation – No braces (curly brackets) Python: Variables / Blocks • Variable use (no types, equate several at once, no semicolons): x,y,z = 1,2,3 first, second = second, first a = b = 123 • Indentation defines blocks (plus logical operators): if x < 5 or (x print "The if x < 5 or 10 print "The > 10 and x < 20): value is OK" < x < 20: value is OK" Python: Iteration / Input • Loops (and comments): for i in [1,2,3,4,5]: print "Iteration number", i # Print values from 0-99 inclusive for value in range(100): print value x = 10 while x >= 0: print "x is not negative" x = x – 1 • Simple input: x = input("Please enter a number: ") print "The square of that number is", x*x Python: Lists • Lists, indexing and slicing fruit print print print = ["plum", "pear", "apple", "banana", "fig"] fruit[2], fruit[0] # Prints "apple plum" fruit[-2] # Prints "banana" (counts from end) len(fruit) # Prints "5" # Slicing is selecting sections of a list # Note: 1st example excludes last index in range print fruit[1:3] # Prints "pear apple" print fruit[:3] # Prints "plum pear apple" print fruit[3:] # Prints "banana fig" • Strings can be treated as read-only lists x = "apple" print x[3] # Prints "l" x[0] = "e" # Error Python: Dictionaries / Functions • A dictionary is a map tel = {"Joe":123, "Jim":555, "Jane":999} person = {'Job':'Builder', 'DOB':'12/12/66'} # '=" print tel["Jane"] # Prints 999 print person["Job"] # Prints "Builder" • Functions (use keyword def): def Square(x): return x*x print Square(3) Python: Functions • Simple parameters are passed by value def square(x): x = x*x return x y = 3 print square(y), y # Prints "9 3", y unchanged by fn • But lists / dictionaries are affected in a function def change_list(l): l[0] = "apple" fruit = ["pear", "orange", "fig"] change_list(fruit) print fruit # Prints "apple orange fig" Python: Strings • Wide range of string support: # Basic operations print 'Hello ' + 'World' # Hello World print "Spam "*4 # Spam Spam Spam Spam # Strings can’t be written to – easy to get round str = "Hello World" newstr = 'M' + str[2:] # Mello World # Example of other methods print len( "Piece of String" ) # Output 15 print "london".capitalize() # Output London print "too times too".replace( "too", "two" ) # Output two times two folderlist = "C:\Work\Python".split("\\") # folderlist = ["C:", "Work", "Python“] Further Conditions • More Conditions # Set membership primes = [1,2,3,5,7,11,13,17,19,23,29] if x in primes: print "x is prime" if year not in range(2000, 2100, 4): # 2000->2100 step 4 print "Not a leap year" # String / List comparison "one" < "two" # true – lexicographical comparison [1,2,3] < [1,2,4] # Compare elements [1,3] < [1,2,3] # Shorter list always less than Working with Lists • List operations # Working with this list a = [66.25, 333, 333, 1, 1234.5] # Counting instances of a value print a.count(333), a.count(66.25), a.count('x') # Output: 2 1 0 # Insertion (anywhere), appending (at the end) a.insert(2, -1) # Location, value a.append(333) print a # Output [66.25, 333, -1, 333, 1, 1234.5, 333] Working with Lists • More list operations # Working with this list a = [66.25, 333, -1, 333, 1, 1234.5, 333] # Removal (by location) x = a.pop() # Remove last element y = a.pop(2) # Remove specific element print a, x, y # Output [66.25, 333, 333, 1, 1234.5] 333 -1 # Removal (by value) a.remove(333) # Remove first instance of 333 print a # Output[66.25, 333, 1, 1234.5] Working with Lists • List reordering # Working with this list a = [66.25, 333, 1, 1234.5] # Reversal a.reverse() print a # Output [1234.5, 1, 333, 66.25] # Sorting a.sort() print a # Output[1, 66.25, 333, 1234.5] Functional List Creation • List creation using functions # map – applies function to list elts to create new list def Square(x): return x*x print map(Square, range(1, 11)) # Output [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] # filter – uses def NotDiv3(x): filter(NotDiv3, # Output [1, 2, boolean function to filter elts in a list return x % 3 != 0 range(1, 15)) 4, 5, 7, 8, 10, 11, 13, 14] # List comprehension – powerful list creation def Square(x): return x*x primes = [1,2,3,5,7,11,13,17,19,23,29] print [Square(x) for x in primes if x%10 < 5] # Output [1,4,9,121,169,529] Function Techniques • More function techniques # Argument passing by name def AddRecord( name, ID = 0, job = "Unemployed” ): ... AddRecord( "Bill", 5 ) # Normal style AddRecord( job="Builder", name="Bob" ) # By name # Argument unpacking def VectorLength( x, y ): ... vector = (10, 15) print VectorLength( *vector ) # * unpacks 1 argument to 2 # Documentation – first line can be string literal def Square(x): "Returns the square of the argument" return x*x Libraries • Can import support libraries: # Mathematics – as in C import math print math.cos( math.pi / 3 ) # Output 0.5 # Random numbers import random print random.choice(['apple', 'pear', 'banana']) print random.random() # random float 0-1 print random.randrange(6) # random integer from 0-5 # 5 random samples from list, e.g. [30,83,16,4,8] print random.sample(range(100), 5) Python: Classes • Class definition (each fn has extra 'self' argument): class Person: # __init__ is a constructor __init__(self, name, job="Unemployed"):# Default self.name = name self.job = job def output(self): print self.name, "the", self.job guy1 = Person("Bob", "Builder") guy2 = Person("Bill") guy1.output() # Prints "Bob the Builder" guy2.output() # Prints "Bill the Unemployed"