Native Coding FAQ

Discussions about Coding and Scripting
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Native Coding FAQ

Post by Feralidragon »

Well, I am creating this topic to cover up all the common (and even the less common) problems when starting (and also during) native mod making.
Personally, I know next to zero about native coding for UT, so I will update this topic as new issues arise and our knowledgeable C++ users come with the solutions to build a central FAQ relative this level of development.
If you see any mistake here, please point it out so I can correct it.
Here it goes:
_________________________________________________________________________________________________________

Q: My Visual Studio 2010 gives me linker errors when I'm trying to compile the dll...
A:
  • Make sure that Core.lib is in your list of "Additional Dependencies" (Project Properties -> Configuration Properties -> Linker -> Input);
  • In General Properties you've got to change Character Set to Unicode;
  • Put "Treat wchar_t as built in type" to No in C++>Language.
User avatar
anth
Adept
Posts: 257
Joined: Thu May 13, 2010 2:23 am

Re: Native Coding FAQ

Post by anth »

Some extra frequently asked questions:

Q: Do the official public headers (v432) work with Visual Studio?
A: Yes they do but there are a few things to keep in mind:
  • Epic originally used Visual Studio 4.0 to work on UEngine. The most recent version of Visual Studio that works perfectly with the official headers is 6.0. You CAN (and probably should) use more recent versions of Visual Studio but then you need some slight modifications to the official headers. You can grab my modified headers here: http://utgl.unrealadmin.org/UTHeaders.rar. These headers also contain a sample project file for Visual Studio 6.0. You might also notice that I've made lots of annotations in the headers. These annotations are irrelevant for 99.9% of the people so feel free to ignore them.
  • UEngine 1 has its own implementations of the C++ memory allocation operators (new, delete) in UnFile.h. If you include Core.h (which in turn includes UnFile.h), all of your memory allocation operations will be handled by UEngine's memory allocator. Sadly, this memory allocator has some serious limitations. The most severe limitation is thread-safety. It is NOT safe to use new, new[] or delete in a multi-threaded UT mod _unless_ you strip out the overridden operations in UnFile.h. Long story short: if you want to build a multi-threaded mod, you should define UTGLR_NO_APP_MALLOC in your preprocessor definitions. This will automagically comment out UEngine's overridden memory allocation operators.
  • If you want to use a more recent VS version than 6.0, then stay away from TArray<BYTE>. The compiler will completely flip out if you attempt to use BYTE arrays. I never really bothered to figure out why.
Q: Are there any project settings I need to change to build a mod with Visual Studio?
A: Yes, depending on your version of VS, there might be quite a few of them. Here's a list:
  • In the General section, you should specify Unicode as the default character set.
  • In the Linker->Input section, you have to add Core.lib and Engine.lib as additional dependencies.
  • If you're using an old version of VS then you have to enable Incremental Linking manually in the Linker->General section.
  • In the C/C++->General section, you'll have to add Core\Inc, Engine\Inc and any folder that contains headers for your project as additional include directories.
  • In the C/C++->Preprocessor section you should have the following preprocessor definitions: UTGLR_NO_APP_MALLOC (if your mod is multithreaded), _CRT_SECURE_NO_WARNINGS (if you're using VS.net 2003 or later), DEBUG and _REALLY_WANT_DEBUG (if you're building a debug version of your mod).
  • In the C/C++->Language section you should disable "Thread wchar_t as built-in type" and you should enable "disable construction displacement" (only for older VS versions)
  • In the C/C++->Core generation section you should set the struct member alignment to 4 bytes. In this same section, you should use either "Multi-Threaded Debug" as the runtime library (if you're building a debug version) or "Multi-Threaded" (if you're building a release build). If you're not using either of these options then VS will dynamically link your mod with the VC++ Runtime Library that came with the compiler. For VS 6.0 this is not a problem, since the game shipped with the VS 6.0 runtime library. If you're using a more recent version then the players might have to manually install the appropriate runtime library. This is especially problematic if you're using VS.net 2003 since that runtime library only came with .NET framework 1.1, which is now deprecated. If you're using VS 2005 or 2008, it is relatively safe to dynamically link with the runtime library (most people will have that installed by default). If you're using VS 2010 or 2011, static linking is recommended.
Q: Is it possible to build native mods for Linux?
A: Yes, it is in fact possible but I strongly discourage you to do so unless you really know what you're doing. If you ABSOLUTELY need a native mod for Linux then here's what you need to keep in mind:
  • UT's native Linux client was compiled using the the ancient GCC 2.95.x compiler. Code generated by this compiler is binary incompatible with code that was generated by GCC 3.x or later. This is mainly due to a change in the C++ name mangling conventions. I do believe that there were some changes in the exception frame format and in the calling conventions as well but I never really checked this. In short, just install GCC 2.95.4...
  • UT's original v436 Linux client does not export the __Context::Env symbol in Core.so. A quick peek at UnFile.h will show you that this has some serious implications. If you want a native mod to work with v436, you should NOT use the guard/unguard/unguardf macros (they all rely on that __Context::Env symbol). If you don't necessarily want compatibility with this version then guard/unguard/unguardf is allowed...
  • Unlike the windows version, the linux version will not automagically cast FStrings to TCHAR* pointers. As such, this will work in Windows but not in Linux:

    Code: Select all

    FString Test(TEXT("123"));
    GLog->Logf(TEXT("Test = %s"), Test);
    
    This however works fine for both platforms:

    Code: Select all

    FString Test(TEXT("123"));
    GLog->Logf(TEXT("Test = %s"), *Test);
    
  • For reasons I won't post in public, please don't ask me for help if you're having problems with your Linux mods.
Q: Which compiler flags do I need for GCC?
A: Here's a list:
  • Mandatory compiler flags: -D__USE_GNU -D_GNU_SOURCE -D_REENTRANT -D__LINUX_X86__ -fno-for-scope -fexceptions
  • Optional compiler flags: -O2 -fomit-frame-pointer
  • Mandatory linker flags: -Wl,--traditional-format -Wl,--eh-frame-hdr -shared -lm -ldl -lpthread
Q: Is it possible to build native mods for MacOS?
A: Only in theory. It would take a ludicrous amount of time to actually pull it off. It would probably have worked with the v468 client but that was never released in public.
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Native Coding FAQ

Post by Feralidragon »

Very nice, that's way more than I expected Anth, thanks for the contribution. :mrgreen:
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: Native Coding FAQ

Post by Higor »

I had to grab Visual Studio 6 when I started native coding, at least I'll know what to do if I want to use a newer compiler now.
Thanks for the guidelines.
User avatar
anth
Adept
Posts: 257
Joined: Thu May 13, 2010 2:23 am

Re: Native Coding FAQ

Post by anth »

I just released the demo manager source code here:

http://www.unrealadmin.org/forums/showt ... p?p=165775

I'm posting this here because Demo Manager is a nice example of a mod that compiles and works well on both Linux and Windows and due to the high level of hackyness, it might actually answer some native coding questions people might have :)
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Native Coding FAQ

Post by Feralidragon »

Nice, thank you. :D

I don't produce native code, but I am pretty sure this will be lots of help when (if) I do or anyone else.
<downloaded>
iloveut99
Skilled
Posts: 231
Joined: Mon Aug 16, 2010 10:25 pm

Re: Native Coding FAQ

Post by iloveut99 »

I'm also not interested in native coding (right know, since uscript fulfill my needs) but like Ferali said it should be a BIG help for who need to use it. I had a look at code and seems it isn't a very difficult thing (maybe most think it is because of the lack of documentation). Also seems very well structured. :)
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: Native Coding FAQ

Post by Higor »

Native function 'numbers'.
What should i do about them?

Is there a convention about this?
Is there a range on numbers I should avoid?
Should I let the compiler autogenerate them?
Is the universe infinite?

AUTOGENERATE_FUNCTION(AClass,-1,execNativeTest);
IMPLEMENT_FUNCTION(AClass,1234,execNativeTest);

I could use a list of known ranges to avoid if you guys suggest me to manually specify those.
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Native Coding FAQ

Post by Feralidragon »

^ About those:
http://web.archive.org/web/200104120448 ... ative.html
And I quote:
IMPLEMENT_FUNCTION( AClassName, UniqueID, AFunctionName);

where AClassName is the name of your class, UniqueID* is an integer that is to uniquely identify the function. This number must be unique to any package loaded in Unreal. For example you can have multiple functions with the same name in your package, they could be in different classes, the numbers are what tells the Unreal which function to call. Unreal uses several numbers for its functions throughout the Engine/Unreali/UnrealShare/Core/Fire etc package files. However, most of those stay below approximately 500, and depending on which packages are loaded by Unreal, you may use those, too. Personally, I try and keep all of mine above 1000.
On this note, I am going to try to do a few native experiments in UT, as my next project may or may not demand some native coding (most of them are possible in UScript, but need lots of work and would be pushy in performance, some of them would be just very bothersome to make).
I found the link above through UnrealWiki: http://wiki.beyondunreal.com/Legacy:Native_Coding
It's been ages since I last touched C++, and when I did I didn't go past cin and cout (console stuff) lol

EDIT: :barf:

Code: Select all

LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification
     Creating library C:\UnrealTournament\UTTest\Release\UTTest.lib and object C:\UnrealTournament\UTTest\Release\UTTest.exp
xUTTest.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) class FMalloc * GMalloc" (__imp_?GMalloc@@3PAVFMalloc@@A)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class UObject * __cdecl UObject::StaticAllocateObject(class UClass *,class UObject *,class FName,unsigned long,class UObject *,class FOutputDevice *,class UObject *)" (__imp_?StaticAllocateObject@UObject@@SAPAV1@PAVUClass@@PAV1@VFName@@K1PAVFOutputDevice@@1@Z) referenced in function "public: static void * __cdecl AuNTest::operator new(unsigned int,class UObject *,class FName,unsigned long)" (??2AuNTest@@SAPAXIPAVUObject@@VFName@@K@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) class FOutputDeviceError * GError" (__imp_?GError@@3PAVFOutputDeviceError@@A)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall AActor::~AActor(void)" (__imp_??1AActor@@UAE@XZ) referenced in function __unwindfunclet$??1AuNTest@@UAE@XZ$0
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall UObject::~UObject(void)" (__imp_??1UObject@@UAE@XZ) referenced in function "public: virtual __thiscall AuNTest::~AuNTest(void)" (??1AuNTest@@UAE@XZ)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) const AActor::`vftable'" (__imp_??_7AActor@@6B@) referenced in function "public: virtual __thiscall AuNTest::~AuNTest(void)" (??1AuNTest@@UAE@XZ)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: int __thiscall UObject::ConditionalDestroy(void)" (__imp_?ConditionalDestroy@UObject@@QAEHXZ) referenced in function "public: virtual __thiscall AuNTest::~AuNTest(void)" (??1AuNTest@@UAE@XZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual unsigned long __stdcall UObject::QueryInterface(class FGuid const &,void * *)" (?QueryInterface@UObject@@UAGKABVFGuid@@PAPAX@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual unsigned long __stdcall UObject::AddRef(void)" (?AddRef@UObject@@UAGKXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual unsigned long __stdcall UObject::Release(void)" (?Release@UObject@@UAGKXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::ProcessEvent(class UFunction *,void *,void *)" (?ProcessEvent@AActor@@UAEXPAVUFunction@@PAX1@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::ProcessState(float)" (?ProcessState@AActor@@UAEXM@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall AActor::ProcessRemoteFunction(class UFunction *,void *,struct FFrame *)" (?ProcessRemoteFunction@AActor@@UAEHPAVUFunction@@PAXPAUFFrame@@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall UObject::Modify(void)" (?Modify@UObject@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::PostLoad(void)" (?PostLoad@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::Destroy(void)" (?Destroy@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::Serialize(class FArchive &)" (?Serialize@AActor@@UAEXAAVFArchive@@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall AActor::IsPendingKill(void)" (?IsPendingKill@AActor@@UAEHXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual enum EGotoState __thiscall UObject::GotoState(class FName)" (?GotoState@UObject@@UAE?AW4EGotoState@@VFName@@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall UObject::GotoLabel(class FName)" (?GotoLabel@UObject@@UAEHVFName@@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::InitExecution(void)" (?InitExecution@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall UObject::ShutdownAfterError(void)" (?ShutdownAfterError@UObject@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::PostEditChange(void)" (?PostEditChange@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall UObject::CallFunction(struct FFrame &,void * const,class UFunction *)" (?CallFunction@UObject@@UAEXAAUFFrame@@QAXPAVUFunction@@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall UObject::ScriptConsoleExec(char const *,class FOutputDevice &,class UObject *)" (?ScriptConsoleExec@UObject@@UAEHPBDAAVFOutputDevice@@PAV1@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall UObject::Register(void)" (?Register@UObject@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall UObject::LanguageChange(void)" (?LanguageChange@UObject@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int * __thiscall AActor::GetOptimizedRepList(unsigned char *,struct FPropertyRetirement *,int *,class UPackageMap *,int)" (?GetOptimizedRepList@AActor@@UAEPAHPAEPAUFPropertyRetirement@@PAHPAVUPackageMap@@H@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall AActor::ShouldDoScriptReplication(void)" (?ShouldDoScriptReplication@AActor@@UAEHXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall AActor::NoVariablesToReplicate(class AActor *)" (?NoVariablesToReplicate@AActor@@UAEHPAV1@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall AActor::CheckRecentChanges(void)" (?CheckRecentChanges@AActor@@UAEHXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual float __thiscall AActor::UpdateFrequency(class AActor *,class FVector &,class FVector &)" (?UpdateFrequency@AActor@@UAEMPAV1@AAVFVector@@1@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual float __thiscall AActor::GetNetPriority(class AActor *,float,float)" (?GetNetPriority@AActor@@UAEMPAV1@MM@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual float __thiscall AActor::WorldLightRadius(void)const " (?WorldLightRadius@AActor@@UBEMXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall AActor::Tick(float,enum ELevelTick)" (?Tick@AActor@@UAEHMW4ELevelTick@@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::PostEditMove(void)" (?PostEditMove@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::PreRaytrace(void)" (?PreRaytrace@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::PostRaytrace(void)" (?PostRaytrace@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::Spawned(void)" (?Spawned@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::PreNetReceive(void)" (?PreNetReceive@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::PostNetReceive(void)" (?PostNetReceive@AActor@@UAEXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual class UTexture * __thiscall AActor::GetSkin(int)" (?GetSkin@AActor@@UAEPAVUTexture@@H@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual struct FMeshAnimSeq * __thiscall AActor::GetAnim(class FName)" (?GetAnim@AActor@@UAEPAUFMeshAnimSeq@@VFName@@@Z)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual class FCoords __thiscall AActor::ToLocal(void)const " (?ToLocal@AActor@@UBE?AVFCoords@@XZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual class FCoords __thiscall AActor::ToWorld(void)const " (?ToWorld@AActor@@UBE?AVFCoords@@XZ)
xUTTest.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall AActor::performPhysics(float)" (?performPhysics@AActor@@UAEXM@Z)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall UObject::UObject(void)" (__imp_??0UObject@@QAE@XZ) referenced in function "protected: __thiscall AuNTest::AuNTest(void)" (??0AuNTest@@IAE@XZ)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall AActor::AActor(class AActor const &)" (__imp_??0AActor@@QAE@ABV0@@Z) referenced in function "public: __thiscall AuNTest::AuNTest(class AuNTest const &)" (??0AuNTest@@QAE@ABV0@@Z)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class AActor & __thiscall AActor::operator=(class AActor const &)" (__imp_??4AActor@@QAEAAV0@ABV0@@Z) referenced in function "public: class AuNTest & __thiscall AuNTest::operator=(class AuNTest const &)" (??4AuNTest@@QAEAAV0@ABV0@@Z)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static void __cdecl UObject::operator delete(void *,unsigned int)" (__imp_??3UObject@@SAXPAXI@Z) referenced in function "public: virtual void * __thiscall AuNTest::`scalar deleting destructor'(unsigned int)" (??_GAuNTest@@UAEPAXI@Z)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl appUnwindf(char const *,...)" (__imp_?appUnwindf@@YAXPBDZZ) referenced in function __catch$?execdoSum@AuNTest@@QAEXAAUFFrame@@QAX@Z$0
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall FFrame::Step(class UObject *,void * const)" (__imp_?Step@FFrame@@QAEXPAVUObject@@QAX@Z) referenced in function "public: void __thiscall AuNTest::execdoSum(struct FFrame &,void * const)" (?execdoSum@AuNTest@@QAEXAAUFFrame@@QAX@Z)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall UClass::UClass(enum ENativeConstructor,unsigned long,unsigned long,class UClass *,class UClass *,class FGuid,char const *,char const *,char const *,unsigned long,void (__cdecl*)(void *),void (__thiscall UObject::*)(void))" (__imp_??0UClass@@QAE@W4ENativeConstructor@@KKPAV0@1VFGuid@@PBD33KP6AXPAX@ZP8UObject@@AEXXZ@Z) referenced in function "void __cdecl `dynamic initializer for 'private: static class UClass AuNTest::PrivateStaticClass''(void)" (??__E?PrivateStaticClass@AuNTest@@0VUClass@@A@@YAXXZ)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static char const * __cdecl UObject::StaticConfigName(void)" (__imp_?StaticConfigName@UObject@@SAPBDXZ) referenced in function "void __cdecl `dynamic initializer for 'private: static class UClass AuNTest::PrivateStaticClass''(void)" (??__E?PrivateStaticClass@AuNTest@@0VUClass@@A@@YAXXZ)
xUTTest.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) private: static class UClass AActor::PrivateStaticClass" (__imp_?PrivateStaticClass@AActor@@0VUClass@@A)
xUTTest.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) private: static class UClass UObject::PrivateStaticClass" (__imp_?PrivateStaticClass@UObject@@0VUClass@@A)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall UObject::StaticConstructor(void)" (__imp_?StaticConstructor@UObject@@QAEXXZ) referenced in function "void __cdecl `dynamic initializer for 'private: static class UClass AuNTest::PrivateStaticClass''(void)" (??__E?PrivateStaticClass@AuNTest@@0VUClass@@A@@YAXXZ)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) unsigned char __cdecl GRegisterNative(int,void (__thiscall UObject::*const &)(struct FFrame &,void * const))" (__imp_?GRegisterNative@@YAEHABQ8UObject@@AEXAAUFFrame@@QAX@Z@Z) referenced in function "void __cdecl `dynamic initializer for 'AuNTestexecdoSumTemp''(void)" (??__EAuNTestexecdoSumTemp@@YAXXZ)
xUTTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall UClass::~UClass(void)" (__imp_??1UClass@@UAE@XZ) referenced in function "void __cdecl `dynamic atexit destructor for 'private: static class UClass AuNTest::PrivateStaticClass''(void)" (??__F?PrivateStaticClass@AuNTest@@0VUClass@@A@@YAXXZ)
C:\UnrealTournament\UTTest\Release\UTTest.dll : fatal error LNK1120: 59 unresolved externals
I am using VS2010 (or trying to). Made all the changes needed and now I am stuck at this... I will probably dig out my VS6.0 and try again with it... I suck at this... :lol2:
I am using anth's modified headers btw...
User avatar
Wormbo
Adept
Posts: 258
Joined: Sat Aug 24, 2013 6:04 pm
Contact:

Re: Native Coding FAQ

Post by Wormbo »

A note about the UniqueID part of IMPLEMENT_FUNCTION: That parameter gives the function an opcode number, but most of the game's own native functions don't have one. I recommend not specifying an opcode number (i.e. use -1 instead), your function will still work as usual, except that the compiler creates a standard function call opcode for it instead of the function's own (potentially conflicting) opcode.
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Native Coding FAQ

Post by Feralidragon »

So, I finally managed to make it work (in VB6), and been toying with it since. While I set it up, I realized I was doing something wrong in the 2010 version as well.
Basically, my steps to make it work (for what is worth for anyone else), was:
- getting the original headers released by Epic;
- putting them in my C++ workspace;
- open the project file from the released headers;
- then, for any new project of my own, copy the settings over from their SampleNativeTest project;
- remove the _DEBUG preprocessor (because of the macro, otherwise it would be like anth pointed out to add the _REALLY_WANT_DEBUG flag).

From there everything went out nicely and I was able to compile a new dll of my own, test a few functions (from simple function like sum integers and give default values to mess up with stuff in the native classes like obtain data of bone coordinates in skeletal meshes and stuff).
However, I had to attribute a numeric code (UniqueID) to my native functions, otherwise they wouldn't bind and the ucc make would flip out saying that it was expecting the function to have another name, so I still have to figure this one out.

I also noticed there were things that are not necessary at all. like that "RegisterNames" there and some macros which were a bit redundant with the ones in the header generated by ucc, and only a few are needed for override like the DLL_EXPORT one.
I am still figuring my way out in the native realm, but I am going to start to take notes as I get to understand more of this, to build a tutorial later on, because so far there isn't a single proper page explaining these things, and there were tons of questions like the basic: how to even setup all this in VS for someone who never used or didn't touch it in ages? I had to figure that one by myself, and I think I may have missed something although it all works as intended.

Having that said, I don't know if I am going to pursue the native coding for my next project, but it's really really tempting, and what I would do natively wouldn't involve too much dependency on windows itself since most of the stuff I am planning is simple, it's just not possible or entirely viable in UScript alone. The possibilities from here are endless, but I have just 1 worry:
- the kind of stuff I am planning to do needs also to run native code server side, however there are Linux based UT servers afaik. My worry is that: for the ones who already provided native code for servers, did you have to add Linux native support, or were these servers mainly Windows based? Should I really worry about Linux systems?
I have no problem to spend some time with Linux, but from what anth said it sounds like a frustrating waste of time?

On that note, if someone has open source examples of native mods for both platforms, and links to tutorials to explain better what certain functions do (like guard and unguard, which is written to be a "try catch" type of deal, but I didn't quite get its logic, as I work with try catching everyday and it consists in catching the exception and handle things gracefully, but here it seems you have no control and I have no idea what would happen during an exception).
Even links to native mods with just Windows support would be great, as I really want to start to learn this stuff through. :mrgreen:
User avatar
The_Cowboy
Skilled
Posts: 165
Joined: Mon Jan 24, 2011 3:22 am
Personal rank: Codezilla

Re: Native Coding FAQ

Post by The_Cowboy »

I have not started native coding yet (have been resisting this temptation), but I have collected some information about it over time. The reason people "knowing the way" dont discuss it is that it would render all the anticheats useless.
Feralidragon wrote: - the kind of stuff I am planning to do needs also to run native code server side, however there are Linux based UT servers afaik. My worry is that: for the ones who already provided native code for servers, did you have to add Linux native support, or were these servers mainly Windows based? Should I really worry about Linux systems?
AFAIK, you have to compile the code using gcc (and obtain .so instead of dll) if you want you mod to run in LINUX machine. Anthrax has already mentioned the required settings for it.
Feralidragon wrote: I have no problem to spend some time with Linux, but from what anth said it sounds like a frustrating waste of time?
I wouldnt say so :).
Feralidragon wrote: On that note, if someone has open source examples of native mods for both platforms, and links to tutorials to explain better what certain functions do (like guard and unguard, which is written to be a "try catch" type of deal, but I didn't quite get its logic, as I work with try catching everyday and it consists in catching the exception and handle things gracefully, but here it seems you have no control and I have no idea what would happen during an exception).
Even links to native mods with just Windows support would be great, as I really want to start to learn this stuff through. :mrgreen:
Maybe you can start from this unsuccessful example
http://wiki.beyondunreal.com/Legacy:Nat ... g_On_Linux.
I gather one needs lot of research and time to work out a way. An example of a working mod in linux (besides ACE) is Qvalidate (EDIT: It is not opensource). Here is the thread when they first figured it out http://www.unrealadmin.org/forums/showthread.php?t=7215.

I too intend to learn native coding, especially for LINUX, but in far future.
Feralidragon wrote:Trial and error is sometimes better than any tutorial, because we learn how it works for ourselfs, which kills any doubts about anything :tu:
Patreon: https://www.patreon.com/FreeandOpen
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Native Coding FAQ

Post by Feralidragon »

The_Cowboy wrote:I have not started native coding yet (have been resisting this temptation), but I have collected some information about it over time. The reason people "knowing the way" dont discuss it is that it would render all the anticheats useless.
I strongly disagree. Cheat-makers often know the engine better than the ones trying to protect it from them.
Everytime an anti-cheat is released, the veteran cheat-maker will reverse engineer it and bypass it in a fairly short amount of time, while the novice cheat-makers will ask info about the engine and how things work natively to those same veterans.
I even go as far as to state the following: when I started to make my first experiments (last Friday), some of my questions were answered by cheat making forums. I didn't go there directly, but as I searched in google certain terms and certain errors and problems, some of them directed me straight to a cheating site, where one guy was trying to develop a cheat, and the veterans were helping him by giving him info about it.
I would even dare to say that there's a greater deal of public information on native coding in a cheating forum than ever was in every non-cheating UT community.
So I don't really see what the harm would be to level up the discussion here as well... when in fact some interesting things may be discovered to nullify some of these anti-cheats and even engine crashes. Discussing or not discussing it won't make a dent on the cheating possibilities.
Of course, anything that I personally find to crash the engine or that could be exploited, I won't post to public either, since some of these cannot be fixed, instead I may only discuss it with some trusted parties, like anth for example.
The_Cowboy wrote: AFAIK, you have to compile the code using gcc (and obtain .so instead of dll) if you want you mod to run in LINUX machine. Anthrax has already mentioned the required settings for it.
Yes, he also mentioned that it takes a good deal of work and hacks to make something work there without giving problems. In Linux v436, it seems some essential things for any native mod are not even possible and will crash the engine from the boot up of the package.
So I have my doubts in whether is it worth it or not. What's the latest Linux version where a mod without any major hacks (no Windows specific libraries, no Windows specific code, no modifications in the headers) is able to run without issues?
The_Cowboy wrote: Maybe you can start from this unsuccessful example
http://wiki.beyondunreal.com/Legacy:Nat ... g_On_Linux.
I gather one needs lot of research and time to work out a way. An example of a working mod in linux (besides ACE) is Qvalidate (EDIT: It is not opensource). Here is the thread when they first figured it out http://www.unrealadmin.org/forums/showthread.php?t=7215.

I too intend to learn native coding, especially for LINUX, but in far future.
Thanks for the links. I also looked into anth's demo manager source (which he posted above as an example of cross-OS compatibility), but they use the guard and unguard functions, so I assume the UT Linux version it works with is not the v436 one, but one below that one.

Either ways, I am getting the hang of it. I had to (and still am) reading in the C++ syntax, and so far things look a lot clearer now, and they are actually rather easier than I imagined them to be. Atm I am trying to read skeletal meshes bone information and trying to figure it all out. Raven wrote a native mod to do so, but unfortunately he didn't continue and his mod doesn't really work at all, since he misunderstood how the skeletal mesh coordinates worked (for example, he reads only the skeletal accumulated relative positions to give a bone position, however he also needed to consider their orientation otherwise all the locations (except the root bone) will be off from their real positions, and for this I need cumulatively rotate the quartenions in each bone to know the real position of the next in each branch... I still didn't finish it, as I am trying to figure out which native functions I should use for this, some of them are confusing).
I know it's possible, with some heavy math in the mix, but possible nonetheless, and fairly important to what I want to do.

I wanted to make it work under Linux too, but the problem is that there's a greater lack of information about Linux than for Windows in this, and even if it ends up working nicely, there's a greater chance of crashes and glitches in the Linux version. I am not even worried about the Linux client (I discarded that a long time ago), but the Linux server as I don't know how many server admins use Linux to host UT (probably most of them since I guess gameservers use Linux for all their games).


EDIT: I already understood what the guard/guardSlow do exactly. Anth talked about UnFile.h and that's where I should have looked into first, the source itself is like a manual.
If I understood right, it's simply for the engine to catch the exception and present it with full info during a GPF (in other words, it's the one of the things that trigger a GPF instead of letting it crash on its own). But from what I understood by looking at the code, I can use them in Linux, but I have to redefine DO_SLOW as false whenever the OS is Linux from my headers, or alter the UnFile.h header to detect that on their own.

3 questions though:

1 - I intend to manipulate files sooner or later, as well create directories (to keep things organized). Should I use the functions from the UT headers or should I write my own functions for it, given this UnFile.h limitation in Linux? (I know that creating directories is OS-dependent, but in case I add support for Linux, I will search how it is done in each system and then create a generic function with both simply separated by preprocessing conditions and OS flags, I guess that's the correct way to do it?)

2 - I also intend to use multi-threading for a few things (gotta use the CPU power available nowadays)... is std::thread safe to use in both operating systems?

3 - Does anyone know about this: https://github.com/stephank/surreal ? (it seems to be for the OpenUT project, specifically for Linux... could it be that perhaps I could compile everything safely for the Linux version of UT using the modified headers from that place?)

(probably I should create another thread just for this stuff)
User avatar
Wormbo
Adept
Posts: 258
Joined: Sat Aug 24, 2013 6:04 pm
Contact:

Re: Native Coding FAQ

Post by Wormbo »

While native coding is not really a topic for UT2004, the "cheaters will figure things out" is really quite the opposite way in that game as well. They have tools to generate headers from DLLs, probably know how to properly decompile UT2004 bytecode (unlike UTPT and WOTgreal) and generally are able to reverse-engineer anything the anti-cheat side will come up with. In fact, I already thought about no longer applying obfuscation, should I ever decide to create another anti-cheat mod again. (Then again, I probably already asked someone to shoot me, should I ever attempt to do that... ;))
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Native Coding FAQ

Post by Feralidragon »

Generally cheaters are the reason to go native as they go native first, because realistically, if cheaters kept themselves to UScript based cheats, UScript based anti-cheats would be more than enough, even though a native one would always be more powerful, and that's the leap that ACE single handendly achieved, but from the first version onwards, cheaters kept trying to bypass it.
Fortunately, ACE is now so evolved that it can prevent most cheaters, and although obfuscation (even at native level) helps securing the anti-cheat for a little while, we're talking about people that go as far as to code in Assembly directly as rendering code to build up cheats, so decompiling ACE (or any other mod for that effect) is simply a "here we go again" type of deal to some of them already.

The curse of anti-cheats is always relying on client-side modules, and in a FPS game there isn't much to do on that other than building perhaps a genetic algorithm which, in the server, is able to flag cheaters, but they wouldn't still be as accurate (at least during the first months where the algorithm evolves itself with the hits and misses). Still, open-sourced or not, anti-cheats are always very useful as long as their effectiveness is kept high enough to catch most.


On another note, I guess I have to find out the answers for those 3 questions myself... but, if someone knows this one at least: is it possible to write new native latent functions? If so, how exactly?
I will be honest, I have a theory in how it might work and I still didn't put it to the test (no time so far + other priorities when I do), but at the same time I think it won't work because probably there's some hardcoding into those. Regardless even if it's impossible, they're not a major problem, they would just make code a bit more pretty and intuitive to understand from the outside when I get to hopefully implement some native stuff.
Post Reply