Sign in to follow this  
Dom_152

How does the Unreal Engine work?

Recommended Posts

Dom_152    476
I've been wondering how everything in the Unreal engine fits together. I've looked at some resources on the internet but none go into the detail I'm looking for, probably because you would have to license the engine to find out this stuff but I'm not sure. I know that most games that use the Unreal engine make heavy use of UnrealScript to do most of the gameplay specific code but I'm wondering how does that fit into the native C++ code that's written. How is a generic Unreal application written in C++, what's the setup? Where does the C++ code end and the UnrealScript begin and how do they work together? Sorry for all the questions but I'm trying to understand as much much as I can about game engine structures and how it all comes together and any answers will be a great help.

Share this post


Link to post
Share on other sites
Mike2343    1202
If you want to know this so you can build your own engine, stop. Build a few games, you will see how this will all come together. Use something like Lua for scripting (since its written and well documented how to integrate them with C++/C#). Then after a few small games, think about writing an engine.

Share this post


Link to post
Share on other sites
DvDmanDT    1941
I'd be intrested in the OPs questions as well though, out of pure intrest. I have written games, with my own engines, but still intresting to hear about succesful engines like UE.

Share this post


Link to post
Share on other sites
umbrae    308
As I understand Unreal Engine games are written heavily in Unreal Script - little or no custom C++. Although I have little experience with the Unreal Engine.

I'm planning to just implement an API in C++ then call it through my scripting language. The C++ is behind the objects you create... you call methods on them and they are translated into C++ method calls.

The C++ code will also initiate events that will eventually call the scripts.

Share this post


Link to post
Share on other sites
jjd    2140
Quote:
Original post by umbrae
As I understand Unreal Engine games are written heavily in Unreal Script - little or no custom C++. Although I have little experience with the Unreal Engine.


That is not generally true. There are some studios that mostly use unreal script but it is certainly not universal. Where I work we have substantially modified the engine, and a lot of our code is in C++.

Share this post


Link to post
Share on other sites
Dom_152    476
Quote:
Original post by jjd
Quote:
Original post by umbrae
As I understand Unreal Engine games are written heavily in Unreal Script - little or no custom C++. Although I have little experience with the Unreal Engine.


That is not generally true. There are some studios that mostly use unreal script but it is certainly not universal. Where I work we have substantially modified the engine, and a lot of our code is in C++.


Have you worked with the engine then? I wasn't aware you could modify the engine itself. I was under the impression that the actual engine source code was closed source and licensees only got libraries and examples of UnrealScript code. If you have worked with it could you explain how the engine is generally setup in the C++ code, like what stages you go through? That would be great!

Share this post


Link to post
Share on other sites
Palidine    1315
Quote:
Original post by Dom_152
Have you worked with the engine then? I wasn't aware you could modify the engine itself. I was under the impression that the actual engine source code was closed source and licensees only got libraries and examples of UnrealScript code. If you have worked with it could you explain how the engine is generally setup in the C++ code, like what stages you go through? That would be great!


If you're at a big publisher and pay a few million dollars they give you full source. But then along with that also comes an NDA, so we can't talk about it... =)

-me

Share this post


Link to post
Share on other sites
Driv3MeFar    1080
Quote:
Original post by jjd
Quote:
Original post by umbrae
As I understand Unreal Engine games are written heavily in Unreal Script - little or no custom C++. Although I have little experience with the Unreal Engine.


That is not generally true. There are some studios that mostly use unreal script but it is certainly not universal. Where I work we have substantially modified the engine, and a lot of our code is in C++.


This is true where I work as well. We use our own, heavily-modified version of UE. Most of the day-to-day coding is done in C++, but we do use Unreal Script frequently as well (there's really no way around it). Unfortunately, I can't say much beyond that (see Palidine's post).

Share this post


Link to post
Share on other sites
Dom_152    476
I thought there might be some NDA or something considering how little information there is around. Worth asking though. Thanks for the information. I'm sure I once came across some source code for a game that used the Unreal Engine but I can't remember where I found it. I'm also not sure how legal it was either :S

Because of all the confidentiality it seems I won't get the answers I originally wanted but would you, as people who have worked with the engine, say that the fact that UnrealScript is so closely tied to game development using the engine can be a hindrance or an annoyance at times? As the previous poster said "there's really no way around it".

Share this post


Link to post
Share on other sites
Mike2343    1202
From my understanding you buy the license it comes with full source code including their games already published (for example code). Its sorta like the id Software licenses.

Share this post


Link to post
Share on other sites
Fisco    122
I remember the UT engine being more CPU intensive than the Quake3 engine. And by intensive I mean, UT scales better with an increase in CPU speed than quake3. Quake3 was more limited by the graphics card...

Any gems of understanding in that observation... let me know.

Share this post


Link to post
Share on other sites
Dom_152    476
Yeah I've had a look at that site but as you said you need to log on as a licensee to see most of the stuff. The information you don't need to login for is mostly aimed at mods which doesn't really help me in what I want to understand. I wish the original Unreal Engine would go open source :D

Share this post


Link to post
Share on other sites
RAZORUNREAL    567
Look at the script for one of the unreal games. I have a feeling you can actually see which methods are in native code (some keyword, extern maybe?). In any case, whatever isn't implemented in script must be in the engine proper. So by reading the interface, you can see where they drew the line. It's been a while since I modded unreal, but I doubt you'll be surprised by what's done where. Basically, all the low level stuff like collision detection, rendering, audio, input, networking, resource/level loading is done engine side. The script objects inherit from a couple which are defined almost entirely in C++, which provide some useful functionality. There are functions that let you iterate over all the game objects, or all the objects of a particular type. The script (mostly) defines what game objects are, and how they interact. Things like mesh and texture are just properties of a base class you inherit from, and there's a built in mechanism for triggering events. I won't comment on the habit of dumping all the functionality in the base classes. Oh damn, I just did. There's also an interesting article about unreals networking and how it fits in with the script but I don't remember where I saw it.

It's funny, the fact that I know far less means I can say more than these hardcore guys that actually use the engine.

Share this post


Link to post
Share on other sites
Aldacron    4544
There was a public source release for Unreal Tournament some time ago. IIRC, there are some engine headers there that can give you an idea of how the engine is structured. They also released the source for their OpenGL driver at some point, so it might still be around somewhere out there.

Share this post


Link to post
Share on other sites
Nathan Baum    1027
Quote:
Original post by Aldacron
There was a public source release for Unreal Tournament some time ago. IIRC, there are some engine headers there that can give you an idea of how the engine is structured.

That's pretty nasty. There are plenty of header files, but most of the interesting source is missing and the provided makefiles don't work without it.

At least the source looks nicer than Quake's. Carmack might be an optimization genius, but he don't half write ugly code.

Share this post


Link to post
Share on other sites
Ravuya    135
Quote:
Original post by Nathan Baum
Quote:
Original post by Aldacron
There was a public source release for Unreal Tournament some time ago. IIRC, there are some engine headers there that can give you an idea of how the engine is structured.

That's pretty nasty. There are plenty of header files, but most of the interesting source is missing and the provided makefiles don't work without it.
That's a public SDK, for modding. The source files aren't there; you just use the headers and then link against the provided static libraries.

Interesting to see how the UnrealScript classes work.

Share this post


Link to post
Share on other sites
bzroom    647
I was very curious about the same thing, since I too am working on an engine. I feel fairly confident that if you were to purchase the Unreal Engine, aside from the fact that all the work is done for you, you would be slightly disappointed at how simple the system really is. At least that's my assumption.

A game is really not that complex, no more complex than say a combustion engine. That doesn’t mean the average Joe can write/build one. It just means that if he looked at the blue print, he'd see the simplicity.

That being said, here is the current version of my engine's declaration file. The exposed public functions here are what the game, the mod use to manipulate the engine (there are also public members of the returned objects).



//This is the engine itself, though it is named renderer.
//This takes care of all tasks of the game including
//marshalling the game update routine. It is a rough draft.
//- Matt Kincaid 7/2/07

#ifndef CRENDERER
#define CRENDERER

#include <windows.h>
#include <vector>
#include <string>
#include "renderdefs.h"

//PICKING DEFINES
#define NOTHING_SELECTED 0
#define MODEL_SELECTED 1
#define AXIS_SELECTED 2

#define SELECTED_MODEL_ID 0
#define SELECTED_AXIS_ID 1

#define MODEL_START 10000
#define AXIS_START 1


struct sPassDetails
{
cViewable *viewable;
cViewable *reflectcam;
cTarget *target;
cReflector *reflector;

bool reflected;
float *reflectorEQ ;
bool shadowing;

sPassDetails()
{
shadowing = false;
reflected = false;
reflector = 0;
viewable = 0;
target = 0;
reflectorEQ = 0;
}
};

class cRenderer
{
private:
cViewableManager *viewables;
cView *currentView;
cGUI *gui;
pPhysicsWorld *physics;
cAtmosphere *atmosphere;
cTerrain *terrain;
cSoundManager *sound;
cParticleSystem *particles;
cControlManager *controls;
cGame *curgame;

cShader *shadowShader;
cShader *flatNoTexShader;
cShader *brightPassShader;
cShader *finalMixShader;
cShader *horizontalBlurShader;
cShader *verticalBlurShader;
cShader *luminanceDownSampleShader;
cShader *DownSampleShader;
cShader *flatShader;

bool VBOSupport;
bool FBOSupport; //without this, we get no targets
cTarget *mainTarget;
cTarget *brightpass;
cTarget *luminance1; //64px
cTarget *luminance2; //16px
cTarget *luminance3; //12px
cTarget *blurHorz;
cTarget *blurVert;

float curluminance;
float newluminance;
float exposure;

long drawcalls;

std::string geometrypath;
std::string materialpath;
std::string modelpath;
std::string physicalspath;
std::string soundspath;

std::vector <pObject*> physicals;
std::vector <cModelInstance*> instances;
std::vector <cModel*> models;
std::vector <cModelInstance*> frustumList; //temporary list
std::vector <cMaterial*> materials;
std::vector <cSurface*> surfaces;
std::vector <cShader*> shaders;
std::vector <cPass*> passes;
std::vector <cLight*> lights;
std::vector <cCamera*> cameras;
std::vector <cReflector*> reflectors;
std::vector <cChunk*> chunks;
std::vector <cVBO*> vbos;
std::vector <cAnimator*> riggedmodels;
std::vector <pVehicle*> vehicles;
std::vector <pCharacter*> characters;
cGraphObject *worldobjects;

cMaterial *LoadMaterial(std::string filename_);
cSurface *LoadSurface(std::string *filenames_, int depth);
cSurface *CreateSurface(int x, int y, int type);
cShader *LoadShader(std::string filename_);

//cRendererGeometryLoaders.h
cModel *LoadModel(std::string filename_);
cModel *LoadGeometry(std::string filename, bool ignorematerials = false);
cModel *LoadMilkshape(std::string filename_, bool ignorematerials);
cModel *Load3DS(std::string filename_, bool ignorematerials);

void GenerateVBO();

//physics
pVehicle *AddVehicle(std::string filename_);
pCharacter *AddCharacter(std::string filename_);

//rendering
void PushChunk(cChunk *chunk, bool zerobuffer = false);
void UseMaterial(cMaterial *material);
void FrustumCull(cViewable *view);
void SortByMaterial();

void ShadowPass(sPassDetails passdetails);
void ReflectionPass(sPassDetails passdetails);
void MainPass(sPassDetails passdetails);
void PostPass(sPassDetails passdetails);
void PickPass(int x, int y);

void ProcessHits(int hits, unsigned int buffer[]);
void ShaderBounceTo(cTarget *target);

void DrawUtilitys();
bool UpdateInput(float etime);

//mouse values
bool leftmouse;
bool rightmouse;
bool lastleftmouse;
bool lastrightmouse;
bool leftmouseonce;
bool rightmouseonce;
bool mouseonce; //avoid repeating mousedown calls
int curpos[2];
int lastpos[2];
int cursorStart[2];
int cursorCurrent[2];
bool lastkeys[256];
bool curkeys[256];
bool oncekeys[256];

//picking
int selectedtype;
int curselected[3];
cMoveable *selectedItem;
int showBounds;
int showPhysics;
bool DrawUtility;

bool exiting;
bool focused;

public:
cRenderer();
~cRenderer();
void Init(int width, int height);
void SetGame(cGame *newgame);

//object requestors
cModelInstance *SpawnModel(cModelInstance *spawndoner);
cModelInstance *AddModel(std::string model_, bool forphysics_ = false);
cLight *AddLight(int type_);
cCamera *AddCamera(int type_);
cCamera *FindCamera(std::string name_);
pGeneral *FindObject(std::string name_);

void ClosestHoldables(std::vector<pGeneral*> &list, cControllable *target, float cutoff);
void ClosestItems(std::vector<pGeneral*> &list, cControllable *target, float cutoff, int type);
void ClosestVehicles(std::vector<pVehicle*> &list, cControllable *target, float cutoff);

//controls
cControllable *FindControllable(std::string name_);
void SetControllable(cControllable *conrollable);

void AddMirror(cReflector *reflector_, cModelInstance *geometry_);
void SetCamera(int camera);
void SetViewPort(cView *view_);
bool Update(float etime);

void RenderScene();
void ClearWorld();
void SaveScene(std::string filename);
void LoadScene(std::string filename);

//see if a key was pressed
bool GetKey(int key);
bool GetKeyOnce(int key);//ignore repeats

//delete these
void MouseUp(int button, int x, int y);
void MouseDown(int button, int x, int y);
void MouseMove(int x, int y);
void SetFocus(bool focused_);
void Resize(int width, int height);
//end delete
//put them in here
int WinInput(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);


friend class cGUI;
};


#endif






Excuse the formatting, apparently tabs are retarted in the forums.

Here is the demo "mod" I am working on along with the engine.


//This is a derived game object. The engine loads this
//and calls setup. Then the update function get's called
//once per frame. - Matt Kincaid 7/2/07

#ifndef MYGAME
#define MYGAME

#include "renderdefs.h"

#include "cgame.h"
#include "crenderer.h"
#include "ccamera.h"
#include "ccontrollable.h"
#include "pgeneral.h"
#include "pvehicle.h"
#include "pcharacter.h"
#include "math.h"

#include <vector>

class cExampleGame : public cGame
{
private:
pCharacter *character;
cCamera *maincamera;

std::vector<pVehicle*> results;
std::vector<pGeneral*> holdables;

public:
cExampleGame()
{
character = 0;
maincamera = 0;
}
~cExampleGame()
{

}

virtual void Setup(cRenderer *renderer_)
{
renderer = renderer_;
renderer->LoadScene("c:\\media\\scenes\\testout.xml");

character = dynamic_cast<pCharacter*>(renderer->FindControllable("dude"));

maincamera = renderer->FindCamera("main");
//put the club in the guys hand
character->HoldObject(renderer->FindObject("gun1"), HOLD_LEFT);
character->HoldObject(renderer->FindObject("golfclub"), HOLD_RIGHT);

//give guy control first
renderer->SetControllable(character);
maincamera->TrackMoveable(character->GetHeadMoveable());
//maincamera->TrackMoveable(renderer->FindObject("golfball")->GetMoveable(), true);
}

virtual void Cleanup()
{

}

virtual void Update(float etime)
{
if (renderer->GetKeyOnce('E'))
{
if (!character->IsRiding())
{
//see if there is a golfcart near by
renderer->ClosestVehicles(results, character, 10);

if (results.size() > 0)
{
//switch to closest one
character->EnterVehicle(results.at(0));
}
}
else
{
//switch to character
character->ExitVehicle();
}
}
if (renderer->GetKeyOnce('1'))
{
renderer->ClosestHoldables(holdables, character, 10);

if (holdables.size() > 0)
{
character->HoldObject(holdables.at(0), HOLD_LEFT);
}
else
character->DropObject(HOLD_LEFT);
}
if (renderer->GetKeyOnce('2'))
{
renderer->ClosestHoldables(holdables, character, 10);

if (holdables.size() > 0)
{
character->HoldObject(holdables.at(0), HOLD_RIGHT);
}
else
character->DropObject(HOLD_RIGHT);
}
}
};

#endif



With 110 lines of code, this demo was generated. Clicky (google video)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this