Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Feb 2, 2025

Abiotic Factor Community Localization

Team of 4
August 2024 - December 2024
Skills Utilized: Python, Unreal Engine, Binary Manipulation 

Introduction

I enjoyed playing Abiotic Factor and wanted more of my friends to experience it, but the lack of Korean language support was a barrier. While the game supported eight languages, Korean wasn’t one of them. So, I decided—why not create a patch myself?

I began analyzing the game files and discovered that many texts and images weren’t exposed for localization. To work around this, I directly modified binary .uasset files and dealt with Unreal Engine’s IO Store files (.utoc and .ucas) as well as .pak archives. Using various tools, I unpacked and repacked these files and extracted .usmap data from the game.

Through this process, I gained a deeper understanding of how Unreal Engine packs and stores game assets.


Showcase


Technical Highlights

Overwriting Texts and Encoding

When replacing text with Korean, the game failed to display it correctly. Suspecting an encoding issue, I created a test Unreal Engine project and discovered that the game stored text in UTF-16 with the size recorded as a negative integer. Understanding this allowed me to properly overwrite text while maintaining compatibility.

UObject and Export Map Entry Manipulation

For assets containing multiple UObjects, such as levels and widgets, Unreal Engine stores individual object offsets and sizes within an export map. Modifying text changed the size of these entries, requiring me to adjust offsets for all subsequent entries to maintain file integrity.

↑Parse the existing entry map

↑And calculate new offsets and sizes after overwriting the strings.

Extracting Images and Dialogue Audio Files

Using CUE4Parse, I iterated through the game’s archive files, performed type checks, and decoded and extracted image and audio assets.

Conclusion

Through this project, I gained a deeper understanding of how Unreal Engine packs and stores files, as well as the intricacies of binary file manipulation. This experience strengthened my ability to analyze and modify game assets at a low level, enhancing my skills in reverse engineering and data structure handling.

Nov 11, 2020

Q

Team of 5
September 2020 - December 2020
Skills Utilized: C++, OpenGL, Python, Graphics Programming, Scripting System, Template Metaprogramming

Introduction

During this semester's GAM class, my group decided to create a 2D action platformer game. I was responsible for constructing the graphics layer of the custom game engine using OpenGL and establishing a Python scripting system.
Built an object-oriented graphics layer encapsulating OpenGL concepts like meshes, textures, and shaders. To enable fast iteration, implemented a Python scripting system by embedding Python into the engine and exposing engine functions using template metaprogramming.

Showcase

↑ Prototype Demo

↑ Graphics showcase




↑ Scripting system showcase







↑ Scripting system showcase (integrated with the engine)




GitHubFunction Property Inspector (Part of the Python Embedder)

Responsibilites

  • Technical Director
  • Graphics Programming
  • Scripting System
  • Part of the Engine Programming
  • Other Gameplay Programming

Technical Highlights

Graphics layer of the engine

One of the challenges when working with OpenGL in an object-oriented language is that it functions as a giant state machine. While efforts have been made to encapsulate some aspects in version 4.5 and above, the core inconvenience remains. Consequently, during the design phase of the engine's graphics layer, I prioritized an object-oriented approach. I encapsulated each distinct concept, such as mesh, texture, and shader, in its own class to maximize encapsulation.


Python scripting system

Last semester, an assignment required the application of template programming. I decided to develop a Python embedder for personal exploration. And in this semester, for the game project, I decided to upgrade and use this embedder instead of relying on existing solutions, well, just for fun.
It automates the cumbersome process of registering C++ functions for using them in Python. All you have to do is one macro or a function call, depending on your preference. It heavily uses template metaprogramming for that automation.
One biggest challenge was iterating over the variadic template parameters. To expose a function to Python, you need to make another function that takes in the PyObjects, parses them then calls the original function with the parsed objects.
I was making that part of the automation and I needed to parse an arbitrary amount of arguments, so I was taking the list of the parameter types as a std::tuple. I needed to iterate over them to parse them. I couldn't use a for loop since the index of the std::tuple_element_t should be complie-time constant.
What should I do? The only thing I know in extra is the count of the parameters. After many trials and errors, I managed to figure out a solution. Make an index sequence with that count, take them with std::index_sequence<ArgumentIndices...>, and call a function for each of them with { parse<Tuple, Indices>(args)... }.




With this, I was able to register all different kinds of functions with various parameter lists with a single function call.

Conclusion

It was fun to design and build a graphics layer of the engine and implement a scripting system, which allowed us to iterate faster on the gameplay programming. Throughout the project, I gained valuable insights into OpenGL and template metaprogramming, as well as the integration of a scripting language into a game engine. These experiences collectively contributed to a significant enhancement of my skillset.