<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Darius Fang</title>
    <description>The latest articles on DEV Community by Darius Fang (@darfang).</description>
    <link>https://dev.to/darfang</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2275219%2F02d7aa29-7465-4b57-8325-18068bb464bb.png</url>
      <title>DEV Community: Darius Fang</title>
      <link>https://dev.to/darfang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/darfang"/>
    <language>en</language>
    <item>
      <title>Procedural Map Generation: From ASCII to Prefabs</title>
      <dc:creator>Darius Fang</dc:creator>
      <pubDate>Tue, 12 Aug 2025 21:07:15 +0000</pubDate>
      <link>https://dev.to/darfang/procedural-map-generation-from-ascii-to-prefabs-5fnn</link>
      <guid>https://dev.to/darfang/procedural-map-generation-from-ascii-to-prefabs-5fnn</guid>
      <description>&lt;p&gt;(Completed Dec 2024) This project was a vertical slice from the Indie Game Startup Landing Company.&lt;/p&gt;

&lt;h2&gt;
  
  
  Constraints for Map Generation
&lt;/h2&gt;

&lt;p&gt;Before diving into the workflow and the steps taken to build the procedural map generation system, it’s important to understand the key constraints that guided the design process. These constraints ensured that the generated maps were functional, playable, and aligned with the overall game design goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initial Constraints
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Hallways&lt;/strong&gt;: Rooms are placed adjacent to one another without gaps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filling of Rooms&lt;/strong&gt;: Rooms are required to fill a rectangle of size &lt;code&gt;n x n&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Random Door Placement&lt;/strong&gt;: Doors initially spawned randomly along room edges.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Evolved Constraints
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fixed Door Placement&lt;/strong&gt;: Doors now adhere to specific rules for alignment and connectivity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Designer Control&lt;/strong&gt;: Procedural rules were adjusted to balance randomness with designer input.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenges Addressed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Room Placement&lt;/strong&gt;: Ensuring rooms of varying sizes fit seamlessly within the grid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Door Placement&lt;/strong&gt;: Avoiding edge cases where doors spawn in inaccessible or illogical locations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design Flexibility&lt;/strong&gt;: Balancing procedural generation with the need for designer control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Process of my workflow.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Building the Foundation: Initial Steps
&lt;/h3&gt;

&lt;p&gt;I started with the basics, creating an ASCII map system to visually represent the map grid. This approach allowed me to quickly prototype and debug the layout. While researching existing solutions, I found that none met my current constraints, prompting me to develop my own. By using a monospaced typewriter font, I crafted a simple yet effective debug view, offering clarity and precision for initial development. Next I implemented random room placement. A key challenge here was ensuring no two rooms overlapped. By addressing this early on, I maintained the integrity of the map layout, laying a solid foundation for future system expansion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Expanding the System: Adding Doors
&lt;/h3&gt;

&lt;p&gt;Initially, I added doors at random positions along room edges. However, I quickly realized this approach was impractical for functional layouts. I introduced constraints to prevent doors from spawning at corners and implemented logic to place doors on opposite edges for better connectivity. These refinements significantly improved room-to-room traversal and laid the groundwork for structured room relationships.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transitioning to Prefabs
&lt;/h3&gt;

&lt;p&gt;Moving from ASCII representation to actual prefabs was a pivotal step. Translating grid positions into world positions introduced complexity, requiring precise calculations to ensure rooms aligned perfectly in the game world. This transition marked the beginning of blending the generated maps with the game environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing Door Logic and Room Properties
&lt;/h3&gt;

&lt;p&gt;To improve functionality, I refactored door logic and introduced a container system for room properties, such as size, type, and door positions. This allowed me to shift from random door placement to fixed door logic, offering greater control over room connectivity. I also created room prefab templates, ensuring consistent design and usability for level designers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Designer-Focused Usability Features
&lt;/h3&gt;

&lt;p&gt;Understanding the importance of designer-friendly tools, I added gizmos and visual indicators to enhance the workflow. For instance, doors in the ASCII map translated to actual door openings in the world. These visuals provided clarity and made adjustments easier for designers, ensuring a smooth collaborative process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxs6sd3c6ywxgg0lpmx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxs6sd3c6ywxgg0lpmx4.png" alt=" " width="625" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Thematic and Gameplay Elements
&lt;/h3&gt;

&lt;p&gt;To enrich gameplay, I incorporated specialized rooms, such as entrances, exits, and puzzles. Logic was added for defining start and exit rooms, creating a structured flow within the system. Expanding the room library with unique templates ensured a cohesive and engaging map generation pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improvements on the system in the future:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Optimization of spawning rooms due to &lt;strong&gt;O(n²)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;More precise gizmos for better visuals.&lt;/li&gt;
&lt;li&gt;More unique rooms if the designers wanted more types of rooms like puzzles.&lt;/li&gt;
&lt;li&gt;Add more unity features like nav mesh for AI to be used.&lt;/li&gt;
&lt;li&gt;Have rooms be possibly rotatable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Details About the ASCII Map System
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Definition and Representation
&lt;/h3&gt;

&lt;p&gt;The ASCII map serves as a grid where each character represents specific elements of the map, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; for corners
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;#&lt;/code&gt; for walls
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~&lt;/code&gt; for traversable (filled) space
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A monospaced font is used for consistent and clear debug visualization of the ASCII map.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Monospaced Font&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2t0lfwrw6fg4z2mf5jcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2t0lfwrw6fg4z2mf5jcy.png" alt="Monospaced font" width="165" height="201"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Unity Default Font&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fek2ynmim6nju9bwwntrx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fek2ynmim6nju9bwwntrx.png" alt="Default" width="162" height="180"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+########+
#~~~~~~~~#
#~~~~~~~~#
#~~~~~~~~#
#~~~~~~~~#
#~~~~~~~~#
#~~~~~~~~#
#~~~~~~~~#
#~~~~~~~~#
+########+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The coordinate system differs from reading a book (a list of strings):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x-positive&lt;/code&gt; moves to the right.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;y-positive&lt;/code&gt; moves downward.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To align with the math-based system (where &lt;code&gt;y-positive&lt;/code&gt; moves upward), the string representation is reversed during rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Room Dimensions and Wall Logic
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Room Size Breakdown:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rooms are defined as &lt;code&gt;n×n&lt;/code&gt;&lt;/strong&gt;, including edges and walls.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traversable space&lt;/strong&gt; inside the room is &lt;code&gt;(n−2)×(n−2)&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grid space&lt;/strong&gt; occupied by the room, including walls, is &lt;code&gt;(n−1)×(n−1)&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Wall Thickness:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Represented as &lt;strong&gt;1 unit in ASCII&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;During prefab generation, walls are scaled to &lt;strong&gt;0.5 units in world space&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;The bottom-left corner of a room (including its wall) starts at &lt;code&gt;(0.5, 0.5)&lt;/code&gt; for proper alignment. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Avoiding Wide Hallways:
&lt;/h4&gt;

&lt;p&gt;Doors placed on ASCII map walls ensure hallways are not unintentionally two tiles wide when connecting rooms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging and Visualization
&lt;/h3&gt;

&lt;p&gt;The ASCII map uses a &lt;strong&gt;bottom-left origin (pivot)&lt;/strong&gt; at &lt;code&gt;(0, 0)&lt;/code&gt; for rooms, ensuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistency in ASCII generation.
&lt;/li&gt;
&lt;li&gt;Smooth transition to prefab placement. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxs6sd3c6ywxgg0lpmx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxs6sd3c6ywxgg0lpmx4.png" alt=" " width="625" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flo4ckkv9rmu5jd9q36vu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flo4ckkv9rmu5jd9q36vu.png" alt=" " width="611" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Room Alignment:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Walls have a consistent offset of &lt;strong&gt;0.5 units&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;The ASCII map structure aligns perfectly with traversable spaces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example ASCII Map Representation
&lt;/h3&gt;

&lt;p&gt;For a 5×5 room at position &lt;code&gt;(1, 1)&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt;: Room corners.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;#&lt;/code&gt;: Walls.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~&lt;/code&gt;: Traversable space (player walkable area).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
--------
-+###+--
-#~~~#--
-#~~~#--
-#~~~#--
-+###+--
--------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Room Placement and Validation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Room Placement Algorithm
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Grid Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialize a grid large enough to fit the room at its specified position.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Room Boundaries:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Place corners (&lt;code&gt;+&lt;/code&gt;) at the four corners of the room with the initial given position:&lt;br&gt;&lt;br&gt;
&lt;code&gt;(0, 0), (0, 4), (4, 0), (4, 4)&lt;/code&gt; for a 5x5 room.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(1, 1), (1, 5), (5, 1), (5, 5)&lt;/code&gt; for a 5x5 room with initial position &lt;code&gt;(1,1)&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Place walls (&lt;code&gt;#&lt;/code&gt;) along the edges, excluding corners: &lt;/p&gt;

&lt;p&gt;Along &lt;code&gt;x = 1, y = 1, x = 5, y = 5&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fill the inner traversable space (&lt;code&gt;~&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;This is a 3x3 starting at position &lt;code&gt;(2,2)&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Room Placement Check:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ensure the grid has enough space to fit the room.
&lt;/li&gt;
&lt;li&gt;Verify that none of the room's traversable spaces (&lt;code&gt;~&lt;/code&gt;) overlap with previously occupied spaces.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;If placement is invalid:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Return a message indicating the issue.
&lt;/li&gt;
&lt;li&gt;Skip the room placement.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Code Adjustments for Placement Validation
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;CanPlaceRoom&lt;/code&gt; Method:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checks if the room fits within grid bounds and if the traversable spaces are unoccupied.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;GenerateRoom&lt;/code&gt; Method:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Places walls, corners, and traversable spaces if &lt;code&gt;CanPlaceRoom&lt;/code&gt; returns true.
&lt;/li&gt;
&lt;li&gt;Otherwise, skips placement and prints a message.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;DisplayGrid&lt;/code&gt; Method:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visualizes the grid in the console for debugging purposes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Door Placement and Room Connectivity
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Door Logic for Random Room Generation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Doors (&lt;code&gt;D&lt;/code&gt;)&lt;/strong&gt; are placed on walls (&lt;code&gt;#&lt;/code&gt;), excluding corners (&lt;code&gt;+&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;The door's placement must:

&lt;ol&gt;
&lt;li&gt;Be aligned with a wall.
&lt;/li&gt;
&lt;li&gt;Avoid overlap with corners or traversable spaces.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;After placing a door, the corresponding wall changes from &lt;code&gt;#&lt;/code&gt; to &lt;code&gt;D&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Fixed Door Placement Logic
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Predefined Door Positions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each room has a list of fixed door locations along its edges.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example for a 4×4 room:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Doors (&lt;code&gt;D&lt;/code&gt;) connect to other rooms via corresponding door positions.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;New Room Placement Logic:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose a door from the current room (e.g., &lt;code&gt;(1, 0)&lt;/code&gt; in Room A).
&lt;/li&gt;
&lt;li&gt;Choose a corresponding door in the new room (e.g., &lt;code&gt;(0, 1)&lt;/code&gt; in Room B).
&lt;/li&gt;
&lt;li&gt;Align the new room’s position by subtracting the door coordinates:
&lt;code&gt;(1, 0) - (0, 1) = (1, -1)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Validate the placement:

&lt;ul&gt;
&lt;li&gt;Ensure the new room does not overlap with filled (&lt;code&gt;~&lt;/code&gt;) spaces.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If valid, place the room.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Optimization and Complexity
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Current Complexity:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Checking every door for every possible new room results in &lt;strong&gt;O(n²)&lt;/strong&gt;, where &lt;code&gt;n&lt;/code&gt; is the number of doors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Potential Optimizations:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Limit door checks to nearby grid areas.&lt;/li&gt;
&lt;li&gt;Assign doors to be NSWE in the room.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example Workflow
&lt;/h3&gt;

&lt;p&gt;Lets assuming we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Room A:&lt;/strong&gt; Size &lt;code&gt;(4,4)&lt;/code&gt; with door positions at &lt;code&gt;(0,1)&lt;/code&gt; and &lt;code&gt;(3,2)&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+##+
#~~D
D~~+
+##+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Room B:&lt;/strong&gt; Size &lt;code&gt;(3,3)&lt;/code&gt; with door positions at &lt;code&gt;(0,1)&lt;/code&gt; and &lt;code&gt;(2,1)&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+#+
D~D
+#+

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Total Level size is &lt;code&gt;(8,5)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Place the First Room:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Start with Room A at &lt;code&gt;(0, 0)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Door Pair 1: Room A &lt;code&gt;(0,1)&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Check if any room can connect to this door position.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result:&lt;/strong&gt; No room can be placed due to insufficient space.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Door Pair 2: Room A &lt;code&gt;(3,2)&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Select Room B’s door at &lt;code&gt;(0,1)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Calculate the pivot position as &lt;code&gt;(3,1)&lt;/code&gt; to place Room B.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result:&lt;/strong&gt; Room B successfully placed at &lt;code&gt;(3,1)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Door Pair 3: Room B &lt;code&gt;(2,1)&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Map this to global coordinates, &lt;code&gt;(5,2)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Check if another Room B can connect using its door at &lt;code&gt;(0,1)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Calculate the new pivot position as &lt;code&gt;(5,1)&lt;/code&gt; to place Room B.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result:&lt;/strong&gt; Another Room B successfully placed at &lt;code&gt;(5,1)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Result in Debug
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
+##+#+#+
#~~D~X~D
X~~+#+#+
+##+----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benefits of Fixed Door Placement
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic Layouts:&lt;/strong&gt;
Predictable connections between rooms.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex Room Shapes:&lt;/strong&gt;
Supports non-rectangular designs like L-shaped rooms.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable Connections:&lt;/strong&gt;
Designers can adjust door positions to control connectivity.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>What is TDD?</title>
      <dc:creator>Darius Fang</dc:creator>
      <pubDate>Fri, 13 Dec 2024 20:39:55 +0000</pubDate>
      <link>https://dev.to/darfang/what-is-tdd-176a</link>
      <guid>https://dev.to/darfang/what-is-tdd-176a</guid>
      <description>&lt;p&gt;Test-Driven Development (TDD) flips the typical coding process on its head: you write the tests before the code. Think of it like sketching a blueprint before building a house. It sets the foundation for cleaner, more organized work. By starting with tests, TDD encourages modular code, solid design principles (like SOLID), and a clear focus on the problem’s requirements.&lt;br&gt;
The process begins with writing the simplest code necessary to pass a test. As more tests are added, you refine the code step by step. TDD teaches attention to detail and helps you truly understand the boundaries of the problem you’re solving.&lt;/p&gt;

&lt;h4&gt;
  
  
  Personal Insight:
&lt;/h4&gt;

&lt;p&gt;TDD taught me to spot constraints early and tackle challenges methodically. While I don’t always use it, practicing TDD has shaped how I think and code. It is one of many techniques that you can use at your disposal.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Red-Green-Refactor Cycle
&lt;/h3&gt;

&lt;p&gt;TDD revolves around a simple, repeatable cycle:&lt;br&gt;
&lt;strong&gt;Red:&lt;/strong&gt; Write a test for the feature or function you want. It should fail first, proving the feature doesn’t exist yet.&lt;br&gt;
&lt;strong&gt;Green:&lt;/strong&gt; Write just enough code to make the test pass—no fancy extras, just the bare minimum.&lt;br&gt;
&lt;strong&gt;Refactor:&lt;/strong&gt; Clean up the code. Make it readable, optimize where necessary, and remove anything redundant without changing how it works.&lt;br&gt;
This cycle is your guide as you build feature after feature, ensuring reliability and adaptability along the way.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Pros and Cons of TDD
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Pros:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Refactoring Is Safer:&lt;/strong&gt; Tests catch bugs early, making changes easier and less risky.&lt;br&gt;
&lt;strong&gt;Readable Documentation:&lt;/strong&gt; Well-written tests are like instructions, often clearer than the code itself.&lt;br&gt;
&lt;strong&gt;Boosts Confidence:&lt;/strong&gt; Automated tests spot mistakes before they snowball into bigger issues.&lt;br&gt;
&lt;strong&gt;Promotes Good Design:&lt;/strong&gt; You’re encouraged to write modular, flexible code that follows best practices.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cons:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Takes Time Upfront:&lt;/strong&gt; Writing tests first can feel slow, but it pays off long-term, especially for bigger projects.&lt;br&gt;
&lt;strong&gt;Tunnel Vision:&lt;/strong&gt; Over-focusing on tests can narrow your perspective, like overfitting a machine learning model.&lt;br&gt;
&lt;strong&gt;Challenging Edge Cases:&lt;/strong&gt; Complex or unpredictable behaviors can be tricky to test within TDD’s constraints.&lt;br&gt;
&lt;strong&gt;Requires Discipline:&lt;/strong&gt; Sticking to the method takes effort, especially during creative coding bursts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Best Practices for TDD
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Start Small:&lt;/strong&gt; Focus on simple tests and add complexity gradually.&lt;br&gt;
Write Independent Tests: Tests should run fast and not rely on each other.&lt;br&gt;
&lt;strong&gt;Refactor Often:&lt;/strong&gt; Clean up code regularly without changing its functionality.&lt;br&gt;
&lt;strong&gt;Follow SOLID Principles:&lt;/strong&gt; Design code to be testable and flexible.&lt;br&gt;
Be Selective: Don’t test everything—focus on critical functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with TDD: An Example
&lt;/h3&gt;

&lt;p&gt;Let’s say you need a function to add two numbers.&lt;br&gt;
&lt;code&gt;Red: Write a test for Add(int a, int b) to ensure it returns a value. It fails—function doesn’t exist.&lt;br&gt;
Green: Create a minimal function returning null.&lt;br&gt;
Red: Write a test to ensure the return type is an integer. It fails.&lt;br&gt;
Green: Update the function to return 0.&lt;br&gt;
Red: Write a test for Add(1, 1) to return 2. It fails.&lt;br&gt;
Green: Update the function to return 2.&lt;br&gt;
Red: Add a test for Add(1, 2). It fails.&lt;br&gt;
Green: Update the function to return a + b.&lt;/code&gt;&lt;br&gt;
Through each cycle, the function evolves in response to the tests, ensuring it works correctly while staying simple. This is very simple example, but can be applied to a more complex example, and remember to refactor when required.&lt;/p&gt;

&lt;p&gt;TDD isn’t just a coding method; it’s a mindset shift. It forces you to think critically, work incrementally, and stay laser-focused on your goals. Like sharpening a blade before carving wood, it may take extra time upfront, but it makes the process smoother and the results more precise.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
