You are on page 1of 12

Introduction to Game Programming

Autumn 2016
2. Scripting games, and
C# (.Net/Mono)

Chapter 11 "Scripting
"Scripting languages and file formats"
formats"
[Madhav, 2014, pp. 224-
224-242].
Section 15.8 "Scripting
"Scripting"" in [Gregory, 2014, pp. 954-
954-978]
Bytecode design pattern [Game
[Game Programming Patterns]
Patterns]

Juha Vihavainen
University of Helsinki

Outline
 Scripting languages
 the tradeoffs of using scripts
 different types of scripting languages
 Implementing a scripting language (very briefly)
 the phases of processing a programming language
 interpretation by a VM vs vs.. native execution
 Bytecode design pattern
 "give behavior the flexibility of data by encoding it as
instructions for a virtual machine"
 ~ metaprogramming, managing code as resource

 C# - a scripting language in, e.g., XNA and Unity

6.12.2016 Juha Vihavainen / University of Helsinki 2


Evolution of (scripting) languages
 Early games (applications) were written in assembly (symbolic
machine language) for performance reasons and for reasons of
availability of languages and tools; needed direct (efficient)
access to hardware-
hardware-level display buffers

 With more powerful computers and language processing tools,


high--level languages such as Fortran, Lisp, Pascal, C/C++, Java,
high
C# etc. became practical

 Now, we often prefer scripting languages for gameplay logic


 most heavy-
heavy-duty calculations are done by a game engine and
shader programs in GPU (Graphics Processing Unit)
 in C++/C and shader languages

6.12.2016 Juha Vihavainen / University of Helsinki 3

Scripting language tradeoffs

Advantages Disadvantages
 it's typically much easier  runtime performance is
and faster to make and typically substantially slower
test changes in script than C/C++
than with, say, C/C++  use multiple languages (system,
 unlike in C/C++, bad script)
code is unlikely to crash  language tools may be less
the entire game mature, limited, or non-
non-existing

6.12.2016 Juha Vihavainen / University of Helsinki 4


When to use scripting?
 If performance of the component is critical, do not use script;
otherwise, the benefits usually outweigh the negatives
 Sample breakdown

C/C++ (Native Code) Scripting Language


Rendering engine Camera logic
AI (pathfinding) AI (state machines)
Physics systems General gameplay
logic
File loading User interface
 the low-
low-level tasks are often part of a game engine (C++)
 the game-
game-specific tasks often written in a script language
6.12.2016 Juha Vihavainen / University of Helsinki 5

Types of scripting languages


Scripting languages that already exist
Custom Languages
 examples
 Lua (WoW)  proprietary languages created
 Python (Blender)
for a specific game/engine
 JavaScript (in Unity, kind of) examples 
 C# (XNA, Unity)  UnrealScript (late)

 QuakeC
Visual scripting systems
 SCUMM
 flowchart
flowchart--like scripting system  Blueprint
 used for level, AI scripting  UnityScript
 to hook up game-
game-level events and behaviour
 e.g., enemies spawn when the player opens a door

6.12.2016 Juha Vihavainen / University of Helsinki 6


Implementing a (scripting) language
 Language creation/compiler theory is a huge sub-
sub-field of
computer science
 Programming languages are our tools, so useful to understand at
least the basic principles of how a language processor works
 The main phases (using the Pipeline architecture/pattern)
 lexical analysis ("tokenization"): find tokens = basic text
items (such as names, operators, delimiters, keywords)
 syntax analysis (parsing): statement/block structures
 semantic analysis (omitted in the text book): contextual
constraints (such as: "names
"names must be declared before use..")
 optimization (omitted in the text book): transformations for
speedup or memory improvements
 code generation:
generation: in multiple phases, again..

6.12.2016 Juha Vihavainen / University of Helsinki 7

The basic idea: use an AST (Abstract Syntax Tree)


AST for "5 + 6 * 10"

 Shows the nested structure of a


construct / whole program
 The Interpreter pattern
[Gamma et al.]:
al.]: how to
evaluate sentences in a
language
 The AST of a sentence/
expression in a language
is used for evaluating
(interpreting) the construct;
 A similar traversal can be used to traverse the tree in post-
post- order
generate portable bytecode, for evaluating the nodes one-
one-by
by--
later execution one
6.12.2016 Juha Vihavainen / University of Helsinki 8
Implementing an interpreter
abstract class Expression
function Execute ()

class Integer : Expression


int value . . . // store the integral value
function Execute ()
// push value onto calculator's stack . . .
class Addition : Expression
Expression lhs, rhs . . . // left and right operands
~ byte
code
function Execute ()
// post
post--order means left child, right child, then this
lhs.Execute () // leave the result on stack
rhs.Execute () // leave the result on stack
// add top two values on stack, push result back on . . .
6.12.2016 Juha Vihavainen / University of Helsinki 9

Case: WoW scripting [Madhav, 239


239--241]
 In an MMORPG, players may have differing preferences, e.g., some
players might want the enemy health to be shown in the center of the
screen, others might want it in the top right, etc.
 An XML file stores the layout of interfaces, such as placement of
images, controls, buttons, and so on
 can inherit from a particular widget and overwrite certain
properties
 specifies whether there are events to register

 specific to widgets: clicking a button, opening a frame, and


sliding a slider, and
 to the game as a whole: to deal or take damage or perform one
of different actions
 The behavior of the UI is implemented using Lua language
 Problem of "player automation": automating gameplay with UI mod
 For details, see the textbook [Madhav, pp. 239-
239-241]
6.12.2016 Juha Vihavainen / University of Helsinki 10
On Unity scripting
 Unity scripting is creating MonoBehaviour classes
 For many reasons,
reasons, C# is the recommendable alternative for those
who already can program
 Using the C# programming language with the Unity engine
 an overview of C# programming (Mono version)
 a comparison between C# and Java
 a selection of C# programming features and idioms
 on basic syntax and uniform type system

 inheritance
inheritance,, generics
 logical properties (accessors)
accessors)
 many other features:
features: lambda expressions,
expressions, reflection. .

6.12.2016 Juha Vihavainen / University of Helsinki 11

General features of the C# language (.NET/Mono)


 A safe, general-
general-purpose object
object--oriented language, with
 object--oriented features, generics, threads, exceptions, . .
object
 strong type checking: static plus dynamic
 compile-time checking for early error detection & efficiency
compile-
 optional dynamic "typing" = (actually) dynamic binding
 prevention of uninitialized variables (checked at compile time)
 array bounds checking (at run time, mostly)
 automatic garbage collection (no dangling references..)
 Moderately easy to learn by programmers familiar with Java
and/or C++
 Systems:: MS .NET CLR = VM;
Systems VM; MS XNA, MonoGame, Unity..

6.12.2016 Juha Vihavainen / University of Helsinki 12


E.g., UnityScript

CIL =
bytecode

~ Java
.class file

CIL was not designed


Compile-time
for interpretation
and run-time
processes

[Illustrated C# 2012,
p. 9.]

6.12.2016 Juha Vihavainen / University of Helsinki 13

"Hello, World!" example


using System; // import names from System
static class Hello {
static void Main () { // main entry point
Console.WriteLine ("Hello, World!");
}
}
 using imports the types contained in a namespace enabling the
identifier of each type to be used without qualification
 uses the predefined static System.Console class
 WriteLine is a public static method of Console
 the customary meaning for static
static:: no instances needed
for using/calling class-
class-level data/methods

6.12.2016 Juha Vihavainen / University of Helsinki 14


Similarities in C# and Java
 Classes and interfaces in both C# and Java
 A single root class for inheritance tree
 java.lang.Object in Java (identifier, not a reserved keyword)
 object in C# (actually, the same as .NET's System.Object
System.Object))
 but value types (primitives) are also part of the hierarchy

 All methods defined within classes in both Java and C# (+ structs


structs))
 Both C# and Java provide extensive class libraries, garbage
collection, type safety, generics, exceptions to manage errors,
threads, generics, reflection facilities, bytecode verification..
(some differences in details)
 Implementations are based on platform-
platform-independent bytecode and
virtual machines (technical differences in details and tradeoffs)

6.12.2016 Juha Vihavainen / University of Helsinki 15

Differences between C# and Java


 structs, delegate
structs, delegates,
s, and nullable value types ("bool?
("bool?")
") in C#, only
 but can use wrapper classes in Java: Boolean myval = null;

 C# provides properties, indexers, overloaded operators (needed for


value types), and many forms of function values (delegates, lambdas)
 C# instantiates generic classes at run time; Java uses type erasure
 virtual as well as non-
non-virtual methods in C# (the same as in C++)
 Classes inside classes are static in C# (in Java, kind of closures
closures))
 C# supports also rectangular arrays (rows are of the same length)
 No checked exceptions in C# (similar to C++)
 In Java, an enumeration type is a special form of a class, and each
enumerated value is an instance (object) of this special class
 In C#, an enumeration type is a value type (as in C/C++)
6.12.2016 Juha Vihavainen / University of Helsinki 16
Meaning of some (exotic) C# keywords
Can test before downcast: "as
"as T" (or null
null)) - also: "is
"is T"
"base
base"" (= "super") for calling base methods/ctor "unchecked { . . . }" , too

"checked (expr)" / "checked


"checked { . . }": checks for int overflows
"internal
internal":
": visible only in this or friend assemblies (spec. via attributes)
"namespace
namespace": ": logical scopes to enclose names (similar to C++)
"operator
operator":
": overloading (only of existing operator symbols)
"params
params":
": for defining variable-
variable-length argument lists
"readonly
readonly":": cannot be reassigned - after initialization (vs. const
const))
"sealed
sealed"" (= "final
"final"" in Java): cannot have subclasses
"struct
struct":
": user
user--defined value type,
type, somewhat similar to class
"virtual
virtual"" / "override
"override":": explicit dynamically bound methods
"dynamic run-time, only (~ "duck
dynamic"" : check called methods at run- "duck typing"?)
typing"?)

6.12.2016 Juha Vihavainen / University of Helsinki 17

Defining a class
In C# , a single file can contain
Simple example multiple public class definitions

class A { // illustrative, only !


int num1 = 1; // can be initialized here
int num2; // = zero, by default
public A (int no = 0)
0) { // can use optional arguments
num2 = no; // set initial value of number
}
...
}
Named arguments
arguments:: Rather than identifying an argument by
position, you can identify an argument by name "Bar (d:3);"
- in Ada
Ada,, these were called keyword parameters

6.12.2016 Juha Vihavainen / University of Helsinki 18


Sample generic class
public class Stack <T> { // illustrative, only
private Entry <T> top; // T is any type (or constrained
constrained))
public void Push (T data) { top = new Entry <T> (data, top); }
public T Pop () {
if (top == null) throw new InvalidOperationException ();
T result = top.data; top = top.next; return result;
}
class Entry <V> { . . . } // C++
C++--like (static
static)) class..
}

 A generic method is a method that is declared with type parameters


static void Swap <T> (ref T lhs, ref T rhs) {
T tmp = lhs; lhs = rhs; rhs = tmp;
} Resembles C++ reference
Calls can use type inference parameters: "(T&
"(T& re
re)"
)"
from actual arguments
6.12.2016 Juha Vihavainen / University of Helsinki 19

Passing arguments in C#
 Values are usually passed by value (of course)
 Heap--allocated objects are passed by reference
Heap
 Variables can be passed by-
by-reference with keyword "ref
"ref""
public static void Add (int i, ref int result) {
result += i;
} ...
int total = 20; passes the address of "total"
Add (10, ref total); // note obligatory keyword "ref ref""
Console.WriteLine ("Value after Add () call: {0}", total);
 resembles C++ reference types ("&")
 Also reference out parameters (assigned within the method)
 Can also pass an object-
object-reference variable by reference:
reference: passes the
address of the local variable itself (of course)
6.12.2016 Juha Vihavainen / University of Helsinki 20
Inheritance

 Use ":
":" to indicate inheritance (vs. "extends
"extends"" in Java)
 C++
C++--like notation (but without C++ public
public//private clauses)
 Constructors can invoke base-
base-class constructor by special base-
base-class
constructor call:
public Derived (int
(int x, int y) : base (x, y) . . // note base keyword
 Casting up and down as in Java (usually run-
run-time check needed)
 Must use "virtual
"virtual"" keyword to indicate virtual functions
 Must use "override
"override"" when redefining a virtual method
 can call the base-
base-class implementations via ""base
base""
 Also: abstract class concept (with "abstract
abstract"" keyword)

6.12.2016 Juha Vihavainen / University of Helsinki 21

C# property example
public class GameInfo {
...Name = "...";
private string name;
public string Name { // can have access modifiers
get { return name; }
set { name = value;
value; } // contextual keyword value
}
}
 get actually a method, returning a value of the specified type

 set uses an implicit parameter "value


"value"" to set some internal data
representation (here simply a field but not necessarily)
 Can omit get or set (but not both), and use access modifiers

 By convention, property names capitalize the first character, so


often use public property "X
"X" to access a private field "x
"x"

6.12.2016 Juha Vihavainen / University of Helsinki 22


C# properties
properties:: "logical fields"
 Provide access to an "abstract data" property
 hidden custom implementations of getters and setters
 Have syntax similar to direct variable access
 can write "foo.X
"foo.X"" instead of "foo.GetX
"foo.GetX ()"
()"
 can write ""foo.X
foo.X = value"
value" instead of "foo.SetX
"foo.SetX (value);"
value);"
 the actual accessor methods can additionally
 check state and so enforce invariants
 provide lazy evaluation or some other processing..
 In a way, a minor feature ("syntactic sugar") but
 improves readability and uniformity of access notation (~ Eiffel
Eiffel))
 used extensively in C#/.NET libraries, and in Unity (Mono)

6.12.2016 Juha Vihavainen / University of Helsinki 23

Automatic properties
 Often, a property just reads and writes one variable (why
(why..?)
..?)
 Such get and set can be automatically created (by the compiler)
public class GameInfo {
public string Name { get; set; } // automatic property
}
 here, a hidden "private
"private string"
string" member is created and used
 Behaves the same way as the previous Name property
GameInfo g = new GameInfo ();
g.Name = "Radiant Silvergun"; // calls "set
set""
System.Console.Write (g.Name); // calls "get
get""
 Here too, can omit one of the two, or specify restricted accessibility
public string Name { get; protected set; }

6.12.2016 Juha Vihavainen / University of Helsinki 24

You might also like