Yet another masterpiece from Tuncay Talayman, simply and humbly one of the most gifted talents in the video game industry. This time he portraits me as a GPU burner sorcerer, which is literally true.
Thank you very much indeed, Tuncay!
Hi there!
Nowadays, my master slave is over-busy with developing something called “The Occult 2024”. Besides feeding and petting me twice a day, I’m afraid he has no spare time for writing new articles on this blog. So, I decided to take advantage of this situation by taking possession of his blog and reminding you something of great importance (!) on behalf of my brothers and sisters… Mark my words! Twice is NOT enough. Cats –especially me– should be fed, petted and tickled behind the ears at least thrice a day… I mean it!
Yours Truly,
Karaböcük
“Innovation Engineering” is a great influence on the growth and survival of today’s world. As a method for solving technology and business problems to innovate, adapt, and enter new markets using the expertise in emerging technologies, it is an essential tool for creative minds.
Much like every other industry in the world, video game development industry is open to new ideas and products more than ever. Actually, it has never been more critical. New technologies emerge, as do new business models. Thanks to innovation culture, video game development process has become more than classic software engineering by evolving into modern innovation engineering.
The latest release of The Occult is a meticulous combination of software and innovation engineering. In order to maximize productivity and efficiency, outside the box thinking was vital. I had to come up with creative and unorthodox problem solving methods. So, rather than waiting for a-ha! moments, I relied on cross-disciplinary research and practices for creativity, and classic engineering methodology for productivity; simply harnessing the best of both worlds… And it worked, charmingly!
The Occult version 2022.2 is released!
The Occult, a virtual gameplay programming ecosystem for Unreal Engine, is now available for both Intel and ARM architectures by offering improved cross-platform compatibility, exciting new features, enhancements, and a few bug fixes. As usual, all commercial and personal video game development projects that I am currently involved in will benefit from the new/enhanced features available in this release.
New Architecture
Multiprocessing System Architecture: User-defined number of virtual processors can perform sync/async operations at the same time. Multiprocessing read/write operations on shared code/memory are 100% thread-safe at both virtual and physical access level.
Multiple Stacks for Multiple Processors: A private stack is assigned for each vCPU, and a public stack is shared among all processors. The public stack is mainly used for level-scope variables, and can be accessed via Index/Data bus. Contrary to the public stack, private stacks do not use Occult’s bus architecture anymore. They are hardwired to parent vCPUs for exceptional low-latency access!
Virtual/Native Code Switching: Instant code switching at instruction-precision level of detail creates an opportunity to inject native C++ code into virtual Assembly code and vice versa, while creating endless possibilities for hardcore code optimization.
New Features
Enhancements
Improved Game Executable Compatibility
Improved C++ Code Compatibility
Improved C++ Development Environment Compatibility
Bug Fixes
Credo quia absurdum!
In terms of productivity, efficiency, and profitability, coding via versatile range of “cross-platform” tools is a must for 21st century video game developer.
However, regarding Unreal Engine’s cross-platform features, debugging, fine-tuning and optimizing game code simultaneously on multiple platforms can sometimes be a real headache even for veteran developers. It is a complex, time-consuming and error-prone task by its very nature. And, this is where The Occult’s latest release comes into play…
The Occult version 2022.1 is released!
I am truly excited to announce the latest release of The Occult. It is now available for both Intel and ARM architectures by offering improved platform compatibility, exciting new features, various enhancements, and a few bug fixes. As of today, all commercial and personal video game development projects that I am currently involved in will benefit from the new/enhanced features available in this release.
Enhancements
Improved Game Executable Compatibility
Improved C++ Code Compatibility
Improved C++ Development Environment Compatibility
Bug Fixes
Vivre libre ou mourir!
A Synchronous/Asynchronous Virtual Machine Architecture
for Unreal Engine
Mert Börü
Video Game Developer
mertboru@gmail.com
Abstract
The “Occult” virtual machine architecture is a cross-platform C++ middleware designed and implemented for Unreal Engine. The primary feature of the Occult is to deliver super-optimized AAA grade games. By adding a very thin-layer on top of Unreal Engine C++ API, the Occult provides a virtual microcomputer architecture with a synchronous/asynchronous 64-bit CPU, various task specific 32-bit coprocessors, and a modern assembly language gameplay programming ecosystem for handling real-time memory/asset management and in-game abstract object/data streaming. It can be used as a standalone solution or as a supplementary tool for existing Blueprint/C++ projects.
(Cover Illustration: “Inferno”, Canti XXVI-XXVIII
by Federico Zuccari – © Uffizi collection)
For the 700th anniversary of the death of Dante, Uffizi Gallery (Florence, Italy) curates a virtual exhibition with 88 rarely displayed drawings of “The Divine Comedy”, as a part of the nationwide celebrations.
The mediaeval poet and philosopher Dante Alighieri (1265-1321), known as the Father of the Italian language, is credited with making literature accessible to the public for using common Tuscan dialect, instead of Latin, as well as paving the way for important Italian writers such as Petrarch and Boccaccio.
“The path to Paradise begins in Hell.” – Dante
Dante’s masterpiece, “The Divine Comedy”, is an epic poem in three parts recounting a pilgrim’s travels through Hell, Purgatory and Heaven. As an allegory, the poem represents the journey of the soul toward God, with the Inferno describing the recognition and rejection of sin. The message in Dante’s Inferno is that human beings are subject to temptation and commit sins, leaving no escape from the eternal punishments of Hell. However, human beings have free will, and they can make choices to avoid temptation and sin, ultimately earning the eternal rewards of Heaven.
“To rebehold the stars”
To mark the 700th anniversary of the Italian poet’s death in 2021, Uffizi Gallery is providing Dante-centric artworks online “for free, any hour of the day, for everyone” says Uffizi director Eike Schmidt. He states that these drawings are a “great resource” for Dante scholars and students, as well as “anyone who likes to be inspired by Dante’s pursuit of knowledge and virtue.”
The virtual exhibition consists of 88 high-resolution images of works by the 16th-Century Renaissance artist Federico Zuccari. The pencil-and-ink drawings are in contrasting shades of black and red, which were originally bound in a volume with each illustration opposite the corresponding verse in Dante’s epic poem. They were completed during Zuccari’s stay in Spain from 1586 to 1588, and became part of the Uffizi collection in 1738.
Dante Illustrated links:
This event is part of the nationwide celebrations for the 700th anniversary of the death of Dante Alighieri, but also aims to symbolize the rebirth of Italy and the art world.
(Cover Photo: ©1984 – ITV Granada
Jeremy Brett, “Sherlock Holmes” TV Series)
It is no secret that, due to nature of modern OOP guidelines, Unreal Engine C++ source code is full of “virtual functions”. It is also no secret that, calling a virtual function is inherently slower than calling a non-virtual function… So, what’s the catch?
A non-virtual call is simply a jump (JMP) to a compiled-in pointer. On the other hand, a virtual call requires at least an extra indexed dereference, and sometimes a fixup addition, which is stored in a lookup table known as Virtual Method Table (VMT). This is simply why a virtual call is always slower than a non-virtual call.
To avoid this overhead, compilers usually steer clear of VMT whenever the call can be resolved at compile time. However, due to complex nature of Inheritence based class structures used in modern game engines, using VMT is unavoidable in most cases.
Virtual Method Table (VMT)
An object’s VMT (also known as vtable) contains the addresses of the object’s dynamically bound methods. Method calls are performed by fetching the method’s address from the object’s virtual method table.
C++ compiler creates a separate VMT for each class. When an object is created, a virtual pointer (VPTR) to this table is added as a hidden member of this object. The compiler also generates hidden code in the constructors of each class to initialize new object’s VPTR to the address of its class’ virtual method table.
The virtual method table is same for all objects belonging to the same class, and is therefore typically shared between them. Objects belonging to type-compatible classes in an inheritance hierarchy will have virtual method tables with the same layout.
Speaking of hidden codes and VMTs in the constructors of each class, each C++ object should also contain additional information about its type. An object’s data type is a crucial information in terms of casting.
Run-Time Type Information (RTTI)
RTTI is a feature of the C++ programming language that exposes information about an object’s data type at runtime. It can apply to simple data types, such as integers and characters, or to generic types.
Run-Time Type Information is available only for classes that are polymorphic, which means they have at least one virtual method. In practice, this is not a limitation because base classes must have a virtual destructor to allow objects of derived classes to perform proper cleanup if they are deleted from a base pointer.
RTTI is used in three main C++ language elements:
The dynamic_cast operator: Used for conversion of polymorphic types.
The typeid operator: Used for identifying the exact type of an object.
The type_info class: Used to hold the type information returned by the typeid operator.
In order to perform cast-related operations listed above, RTTI heavily uses VMT. For example, given an object of a polymorphic class, a type_info object can be obtained through the use of the typeid operator. In principle, this is a simple operation which involves finding the VMT, through that finding the most-derived class object of which the object is part, and then extracting a pointer to the type_info object from that object’s virtual function table (or equivalent).
In terms of performance, using the dynamic_cast operator is more expensive than type_info. Given a pointer to an object of a polymorphic class, a cast to a pointer to another base subobject of the same derived class object can be done using a dynamic_cast. In principle, this operation involves finding the VMT, through that finding the most-derived class object of which the object is part, and then using type information associated with that object to determine if the conversion (cast) is allowed, and finally performing any required adjustments of the pointer. In principle, this checking involves the traversal of a data structure describing the base classes of the most derived class. Thus, the run-time cost of a dynamic_cast may depend on the relative positions in the class hierarchy of the two classes involved.
Hacking VMT and RTTI Information using UE C++
In order to gather “header” information (that contains VMT and RTTI data) in an Unreal Engine C++ class/object, I have written the following LogClassHeader() C++ function using Visual Studio 2019 version 16.3.8 for Unreal Engine version 4.23.1.
void UDebugCore::LogClassHeader(void* const pThis, size_t nSize) { FString fsClassName = "NULL"; FString fsObjectName = "NULL"; UObject* const pCastedToUObject = (UObject*)(pThis); void** const pCastedToHeader = reinterpret_cast<void**>(pThis); if (pCastedToUObject) { fsClassName = pCastedToUObject->GetClass()->GetName(); fsObjectName = pCastedToUObject->GetName(); } if (pCastedToHeader) { for (size_t i = 0; i < nSize / sizeof(void*); i++) { MACRO_PRINTF("Pointer[%04zu] = 0x%p", i, pCastedToHeader[i]) } } }
This function has 2 input parameters:
pThis: Object to extract Class Header Info from
nSize: Size of Header
Calling the function is very easy. You simply insert your call into the constructor of the class that you would like to hack. For example, the following code gathers C++ header information of <APlayerControllerThirdPerson> class.
APlayerControllerThirdPerson::APlayerControllerThirdPerson() { UDebugCore::LogClassHeader(this, sizeof(*this)); }
When you run the code, all pointers that are available (and used) in the header of <APlayerControllerThirdPerson> will be listed. And, in case you need, instance name and class type is stored in fsObjectName and fsClassName variables, as a bonus.
Pointer[0000] = 0x00007FFC8A3ECB00 Pointer[0001] = 0x0000BC5B00000231 Pointer[0002] = 0x000001648346AC00 Pointer[0003] = 0x000AAD5B000AAD5B Pointer[0004] = 0x0000000000000000 Pointer[0005] = 0x00000164834864E0 Pointer[0006] = 0x00007FFCAAB2EF98 Pointer[0007] = 0x00007FFCA8708208 Pointer[0008] = 0x0000000F00000000 ..... ... .
So, what do these numbers mean? Well, all these pointers are addresses of the virtual functions, followed by some of the member variables. In order to understand which is which, we need to decipher the structure of the data set.
Here comes the tricky part! With each and every update to Visual Studio C++ compiler, the structure tends to get updated as well. In other words, the header structure of a C++ class changes with each major compiler update. Try to think of it as a “living organism”. As I’m typing this sentence now, a new update with a new C++ header structure may be on its way. So, it is up to you (!) to analyze what’s going on under the hood.
Good news is, we can gather <template> information about C++ class header structure from the official Microsoft patent documents! Although they are not up-to-date, I think it is a good practice to start the investigation using the source of information itself.
Here is some of the Microsoft patents which describe various parts of C++ implementation used in Visual Studio:
US Patent #5410705: “Method for generating an object data structure layout for a class in a compiler for an object-oriented programming language”
US Patent #5617569: “Method and system for implementing pointers to members in a compiler for an object-oriented programming language”
US Patent #5754862: “Method and system for accessing virtual base classes”
US Patent #5297284: “Method and system for implementing virtual functions and virtual base classes and setting a this pointer for an object-oriented programming language”
US Patent #5371891: “Method for object construction in a compiler for an object-oriented programming language”
US Patent #5603030: “Method and system for destruction of objects using multiple destructor functions in an object-oriented computer system”
So, what I’m offering is, good old-fashioned “reverse engineering”.
– “Is such a challenge worth it?”
– “Um, yes!… If it doesn’t break you, it can make you.”
References:
Bjarne Stroustrup, “A History of C++: 1979—1991”, p. 50 – (March 1993)
Keith Cooper & Linda Torczon, “Engineering A Compiler”, Morgan Kaufmann, 2nd Edition – (2011)
Microsoft Visual Studio Documentation, “C++ Run-Time Type Information” – (November 2016)
“Technical Report on C++ Performance”, OpenRCE.org – (September 2006)
“Reversing Microsoft Visual C++: Classes, Methods and RTTI”, OpenRCE.org – (September 2006)
“Intel® 64 and IA-32 Architectures Optimization Reference Manual” – (April 2018)