Unreal Engine Core
This page is an introduction to the core concepts of the Unreal Engine. At its simplest, a computer game is made up of the following things:
- a collection of things that describe the environment the player is supposed to experience,
- a means of conveying that to the player on her monitor, through her speakers and so on.
The collection of things is staggeringly huge, even for the average game of UT2003. We don't tend to realize just how fast computers are these days. In programming terms, each thing is called an object. The Unreal engine is constantly aware of where these objects are in the fictional world, what they are doing and so on. It does this by looking at each one in turn, although as we'll see later from the point of view of the programmer, we can usually envisage all this as happening simultaneously, in real time.
So far, we have a long list of objects, and each one is assigned a position in 3-dimensional Cartesian coordinates. Now the engine also knows where the player is this world (the player is represented by just another type of object, but more on this much later), and can calculate what the player is supposed to see and hear. If a rocket just flew past in front of you, then you'll see a rocket in front of you on the screen.
Some questions that might be raise now include: what makes the rocket fly in a particular direction? what makes it explode when it hits something? when it hits the player, what makes him lose health and go 'ouch'?
The virtual machine
We now come to a fundamental difference between the Unreal Engine and most other first-person shooters. It's a difference which, in the opinion of many modders, makes working with Unreal much easier than with other engines.
The parts of the software that handle display on the screen (rendering), sound, and knowing where all these objects are, networking (clients and servers sending each other information about the objects) as well as anything else that is platform-specific, is written in C++. We call the "native" stuff. You can't see the code for this (it's "closed-source"), and hardly any of the work done by modders involves this.
The native software also creates a virtual machine, similar to the Java virtual machine. This is like a programming environment that sits on top of the native stuff. The language for this is UnrealScript; it's similar to Java and JavaScript. It is compiled into bytecodes, like Java, but the source remains visible, and it's this that allows the modding of the Unreal engine games. Tim Sweeney's Design goals for UnrealScript explain this idea further.
In very simple terms, every single object in the game is a piece of UnrealScript code. The engine runs all these scripts, and they decide what to do. So when the rocket hits a wall, a function in its script called something like HitAWall says: "I have hit a wall. I should now produce an explosion, make a noise, and remove myself from the game." How does the rocket know it hit a wall? The native part of the engine told it. How does the engine know? Every single moment of the game, it is checking where objects are and what they are touching.
Since UnrealScript is object oriented, you won't be editing any of the original source. This is different from Quake, where you edit the original source and then distribute a new DLL. In US, you will subclass the classes that shipped with Unreal Tournament, modifying them to suit your needs. – Tim Sweeney
The tick
The engine divides time into ticks. A tick is not a specific length, which allows the engine to scale rthis according to the power of the machine and the current load. While the C++ parts of the engine are fast, UnrealScript is a relatively slow language to execute. The software is designed in such a way that things that happen all the time, like movement and checking whether objects are touching, is handled natively, while particular events are handled in UnrealScript. While the rocket is moving, no UnrealScript is being executed. The native engine knows to keep moving it forwards each tick, and the renderer is of course showing it to you in a different position each frame (the renderer works in frames, like animation. Again, how fast these go, the FPS, depends on your hardware and how much is going on in the game, but frames and ticks are unrelated. The virtual machine that runs the objects doesn't care about what the renderer does and vice versa).
But when the rocket hits the wall, things begin to happen in UnrealScript:
- the rocket is notified. This starts a chain of events:
- the rocket informs the thing it's hit: "you've just been hit by a rocket. This is maybe going to hurt you". The thing it's hit could be a player which received damage, or a piece of architecture which won't care much. But the point is that the rocket doesn't care what the target does about being hit. This is a very important point about object-oriented programming, which we'll see later on. Roughly speaking, this is encapsulation.
- the rocket creates a new object: an explosion. This explosion object will begin to run its own script, which says:
- display bright flashes at your position.
- Make a loud noise.
- Now some smoke. When the renderer inspects all the objects the player can see, it will see that there are bright flashes and smoke called for at a particular spot.
- Then remove yourself from the game, you're done.
- the rocket then removes itself from the game. The object that represents the rocket no longer exists.
Now from the point of view of the C++ native code, each object is taken in turn. But from a programmer's point of view, we can imagine the rocket and the explosion as running in parallel.
Tarquin: ok guys, what next? Are we ready to lead on into OOP Overview?
Comments
Tarquin: How am I doing so far? Want to change the list on UnrealScript Lessons so it reflects the order?
Sobiwan: How can I say this... ah, yes. The music artist "Sting" comes to mind: "every little thing Tarquin does is magic..."
Wormbo: I'm sure this is mentioned somewhere: The Unreal engine loads packages because they are referenced by code, i.e. they are referenced by other packages, or because objects in those packages are mentined in INT files, which again leads to code loading those objects after scanning all INT files for a certain MetaClass.
Daid303: "UnrealScript (lets call it US for short)" Let's NOT call it US for short, but UScript for short, ok?
Tarquin: Well I think much of the bottom half of this page will be deleted anyway, unless someone tidies it up... This page needs a better title too. !Unreal Engine Ovewview" maybe?