DevBlog_01: Terrain Generation
π― Project goal: Hobby project, which helps me learn new stuff.
π¨βπ¨βπ§βπ§ Target audience: Gamers and Game Developers
πΊ Platform: PC
π©π»βπ» Language: C++
β³ Timeline: Currently ongoing
Me (game developer) and a friend of mine (artist) are creating a single-player,
Tower Defense, Exploration game in Unreal Engine 5.
Tower Defense with a twist: The player will not be dragging
and dropping defenses on a map from the game interface, like
in traditional TD games. The player will be a character gathering resources,
building defenses and defending along with the defenses he builds
(think of: Orcs Must Die X Minecraft).
Exploration: Every time the player replays a level,
the layout of the level will be different. The goal is to
make the player explore every time the level starts and not
allow him to memorize locations and strategies. Every level
play through must be unique.
Instead of relying on Unreal Engineβs built-in Navigation System, I implemented a custom A* pathfinding solution
tailored to the gameβs procedural, grid-based terrain.
The system operates directly on the centralized grid map and supports 3D movement, including diagonal traversal
across stacked cells. I evaluated multiple heuristic functions (Manhattan, Euclidean, Chebyshev) and selected
Euclidean distance to balance path accuracy and performance.
This allowed enemy agents to navigate dynamically generated environments while maintaining predictable and
tunable computational costs.
You can read more about how I built that in my development blog.
I designed a data-driven pipeline enabling terrain chunks to be constructed in Autodesk Maya and reconstructed
identically inside Unreal Engine at runtime.
Using custom Python export scripts, chunk geometry is serialized into structured JSON data,
including cell order, transforms, and metadata. This data is imported into Unreal as Data Tables
and consumed by chunk construction code.
The pipeline enforces strict ordering and naming conventions
while empowering 3D artists to work independently in Maya.
This results in faster iteration, greater creative freedom,
and a more robust authoring process with reduced potential for human error.
You can read more about how and what got me to built that in my development blog.
Early prototypes used individual Static Mesh Components for terrain cells, which quickly became CPU-bound
due to excessive draw calls during terrain generation.
I refactored the rendering layer to use Instanced Static Mesh Components (and Hierarchical ISMs where applicable),
applying the Flyweight pattern to separate shared mesh data from per-instance transforms.
Profiling with Unreal Insights confirmed that draw calls remained constant regardless
of world size, resulting in a substantial FPS improvement during runtime terrain expansion.
You can read more about my process of doing that in my development blog.