Skip to content
building-construction logo

Building & Construction Patterns

building-construction

Provides patterns for building detailed structures programmatically using Parts and CSG. Use when creating buildings, towers, vehicles, or any brick-by-brick constructions in code.

SKILL.md

Full skill instructions

Building & Construction Patterns


MANDATORY: Stud Material Initialization

CRITICAL: This code block MUST be included at the START of every building script. No exceptions. Always load stud materials BEFORE creating any parts.

--------------------------------------------------------------------------------
-- MANDATORY INITIALIZATION - COPY THIS BLOCK FIRST
--------------------------------------------------------------------------------

local Workspace = game:GetService("Workspace")
local AssetService = game:GetService("AssetService")
local MaterialService = game:GetService("MaterialService")

-- Stud material configuration
local STUD_ASSET_ID = 13719188279  -- 2022 Stud MaterialVariant
local studMaterialName = ""
local studBaseMaterial = Enum.Material.Plastic

-- Load stud materials (MUST run before creating parts)
local function loadStudMaterials()
    -- Check if already loaded in MaterialService
    for _, item in ipairs(MaterialService:GetChildren()) do
        if item:IsA("MaterialVariant") then
            studMaterialName = item.Name
            studBaseMaterial = item.BaseMaterial
            print("[Studs] Found existing: " .. studMaterialName)
            return true
        end
    end

    -- Load via AssetService
    local success, err = pcall(function()
        local asset = AssetService:LoadAssetAsync(STUD_ASSET_ID)
        if asset then
            local matVariant = asset:FindFirstChildWhichIsA("MaterialVariant", true)
            if matVariant then
                matVariant.Parent = MaterialService
                studMaterialName = matVariant.Name
                studBaseMaterial = matVariant.BaseMaterial
                print("[Studs] Loaded: " .. studMaterialName .. " (BaseMaterial: " .. tostring(studBaseMaterial) .. ")")
            end
            asset:Destroy()
        end
    end)

    if not success then
        warn("[Studs] FAILED to load: " .. tostring(err))
        return false
    end

    return studMaterialName ~= ""
end

-- EXECUTE IMMEDIATELY
local studsLoaded = loadStudMaterials()
if not studsLoaded then
    warn("[Studs] Running without stud materials - parts will be smooth plastic")
end

--------------------------------------------------------------------------------
-- STANDARD PART CREATION FUNCTION (Uses loaded stud materials)
--------------------------------------------------------------------------------

local function createPart(size, cframe, color, name, parent)
    local part = Instance.new("Part")
    part.Size = size
    part.CFrame = cframe
    part.Anchored = true
    part.BrickColor = color

    -- Apply stud material (if loaded)
    if studMaterialName ~= "" then
        part.Material = studBaseMaterial
        part.MaterialVariant = studMaterialName
    else
        part.Material = Enum.Material.Plastic
    end

    -- NEVER use legacy studs (causes Z-fighting)
    part.TopSurface = Enum.SurfaceType.Smooth
    part.BottomSurface = Enum.SurfaceType.Smooth

    part.Name = name or "Part"
    part.Parent = parent
    return part
end

--------------------------------------------------------------------------------
-- YOUR CODE STARTS HERE (use createPart function above)
--------------------------------------------------------------------------------

Why This Is Mandatory

IssueLegacy SurfaceType.StudsMaterialVariant (This Pattern)
Z-FightingYES - 3D geometry overlapsNO - flat PBR texture
PerformanceWorse - extra geometryBetter - texture only
Future-proofNO - deprecated 2018YES - modern standard
Visual QualityInconsistentHigh quality PBR

Critical Rules

  1. ALWAYS load materials BEFORE creating parts
  2. ALWAYS use createPart() function, never raw Part creation
  3. NEVER use SurfaceType.Studs - causes Z-fighting
  4. ALWAYS set surfaces to Smooth - MaterialVariant handles appearance
  5. part.Material MUST match studBaseMaterial - or variant won't apply

Quick Reference Links

Official Documentation:

Community Resources:

  • Asset ID 13719188279 - 2022 Stud MaterialVariant (RECOMMENDED)
  • Asset ID 18987102498 - Full 2008-2024 Studs pack
  • Resurface Plugin - For existing builds

Performance Optimization (Community Consensus)

Part Count Guidelines

  • Optimal: Under 5,000 parts in render distance
  • Per Building: 100-600 parts (no interior)
  • Warning: 9,000+ parts = noticeable fps drops

Critical Rules

  • ALWAYS anchor static parts - moving parts = lag
  • Disable CanCollide + CanTouch on decorative parts
  • Avoid Unions - bad topology, breaks instancing
  • Reuse designs - vary with scale/​color/​rotation instead of unique parts
  • Enable Streaming in Workspace for large maps

MeshPart Settings (If Using Meshes)

RenderFidelityUse For
PerformanceDecorative, distant objects
AutomaticInteractive items
PreciseMajor landmarks only
CollisionFidelityUse For
BoxWalkthrough objects, tiny items
HullTrees, varied shapes
DefaultTerrain, complex structures

Layer System (Avoid Z-Fighting)

IMPORTANT: Never place parts with surfaces at exactly the same Y position. Use a layer system.

-- Define layer heights (build from bottom up)
local LAYERS = {
    GROUND = 0,           -- Base ground level
    PLATFORM = 2,         -- Platforms ON TOP of ground (not overlapping)
    SPAWN = 4,            -- Spawn platforms above main platforms
    DECORATION = 5,       -- Decorations on platforms
}

-- Ground: 2 thick centered at Y=0, top surface at Y=1
local GROUND_TOP = LAYERS.GROUND + 1

-- Platforms sit ON TOP of ground (bottom at Y=1, not Y=0)
createPart(Vector3.new(80, 3, 80), CFrame.new(0, GROUND_TOP + 1.5, 0), color, "Platform", parent)

Natural Map Borders (Community Best Practice)

DO NOT use plain walls. Use mountains + forest + invisible collision.

--------------------------------------------------------------------------------
-- NATURAL BORDER PATTERN
--------------------------------------------------------------------------------

local borderFolder = Instance.new("Folder")
borderFolder.Name = "MapBorder"
borderFolder.Parent = workspace

-- Low-poly mountain
local function createMountain(position, baseSize, height, color)
    local mountain = Instance.new("Model")
    mountain.Name = "Mountain"

    -- Base (wide)
    createPart(Vector3.new(baseSize, height * 0.4, baseSize),
        CFrame.new(position + Vector3.new(0, height * 0.2, 0)),
        color, "Base", mountain)

    -- Middle (narrower)
    createPart(Vector3.new(baseSize * 0.7, height * 0.35, baseSize * 0.7),
        CFrame.new(position + Vector3.new(0, height * 0.55, 0)),
        color, "Mid", mountain)

    -- Peak with snow cap
    createPart(Vector3.new(baseSize * 0.35, height * 0.3, baseSize * 0.35),
        CFrame.new(position + Vector3.new(0, height * 0.85, 0)),
        BrickColor.new("Institutional white"), "Peak", mountain)

    mountain.Parent = borderFolder
    return mountain
end

-- Dense forest cluster
local function createForestCluster(centerX, centerZ, groundY, radius, density)
    for i = 1, density do
        local angle = math.random() * math.pi * 2
        local dist = math.random() * radius
        local x = centerX + math.cos(angle) * dist
        local z = centerZ + math.sin(angle) * dist
        local height = math.random(6, 14)
        createTree(Vector3.new(x, groundY, z), height, borderFolder)
    end
end

-- Invisible collision wall
local function createInvisibleWall(size, cframe)
    local wall = Instance.new("Part")
    wall.Size = size
    wall.CFrame = cframe
    wall.Anchored = true
    wall.Transparency = 1
    wall.CanCollide = true
    wall.Name = "InvisibleBarrier"
    wall.Parent = borderFolder
    return wall
end

-- Add atmosphere fog
local atmosphere = Instance.new("Atmosphere")
atmosphere.Density = 0.3
atmosphere.Haze = 1
atmosphere.Parent = game:GetService("Lighting")

Border Placement Pattern

  1. Mountains - Far outside map edge (50+ studs beyond)
  2. Forest - Dense trees inside map edge
  3. Invisible Wall - At exact map boundary
  4. Atmosphere - Fog to obscure distant edges

Building Patterns

Simple Tree

local function createTree(position, height, parent)
    local tree = Instance.new("Model")
    tree.Name = "Tree"

    -- Trunk
    createPart(Vector3.new(2, height, 2),
        CFrame.new(position + Vector3.new(0, height / 2, 0)),
        BrickColor.new("Reddish brown"), "Trunk", tree)

    -- Leaves (stacked, tapering)
    local leafSizes = {8, 6, 4}
    for i, size in ipairs(leafSizes) do
        createPart(Vector3.new(size, 3, size),
            CFrame.new(position + Vector3.new(0, height + i * 3 - 1, 0)),
            BrickColor.new("Bright green"), "Leaves" .. i, tree)
    end

    tree.Parent = parent
    return tree
end

Castle Components

-- Foundation (widest, ground level)
createPart(Vector3.new(40, 2, 40), CFrame.new(0, 1, 0), BrickColor.new("Dark stone grey"), "Foundation", castle)

-- Walls
createPart(Vector3.new(wallLength, wallHeight, wallThickness), wallCFrame, BrickColor.new("Medium stone grey"), "Wall", castle)

-- Crenellations (on top of walls)
for i = -n, n do
    createPart(Vector3.new(1.5, 2, 1.5), CFrame.new(i * spacing, wallTop + 1, wallZ), BrickColor.new("Medium stone grey"), "Crenel", castle)
end

-- Corner towers (taller than walls)
createPart(Vector3.new(towerSize, towerHeight, towerSize), cornerCFrame, BrickColor.new("Medium stone grey"), "Tower", castle)

-- Tower roofs (stacked, tapering)
for i, size in ipairs({4, 3, 2}) do
    createPart(Vector3.new(size, 1, size), CFrame.new(roofX, roofY + i - 1, roofZ), BrickColor.new("Bright red"), "Roof" .. i, castle)
end

Dragon/​Creature (Static Decoration)

-- For STATIC decorations: keep all parts Anchored
-- DO NOT use WeldConstraint for static models

local function createDragon(position, color, scale, parent)
    local dragon = Instance.new("Model")
    dragon.Name = "Dragon"
    local s = scale or 1

    -- Body (main mass)
    createPart(Vector3.new(6*s, 4*s, 10*s), CFrame.new(position), color, "Body", dragon)

    -- Head
    createPart(Vector3.new(3*s, 3*s, 4*s), CFrame.new(position + Vector3.new(0, 1*s, -6*s)), color, "Head", dragon)

    -- Snout
    createPart(Vector3.new(2*s, 1.5*s, 2*s), CFrame.new(position + Vector3.new(0, 0.5*s, -8.5*s)), color, "Snout", dragon)

    -- Neck
    createPart(Vector3.new(2*s, 3*s, 2*s), CFrame.new(position + Vector3.new(0, 2*s, -4*s)) * CFrame.Angles(math.rad(-30), 0, 0), color, "Neck", dragon)

    -- Tail segments
    local tailPos = position + Vector3.new(0, 0, 5*s)
    for i = 1, 4 do
        local tailSize = (5 - i) * s
        createPart(Vector3.new(tailSize, tailSize, 3*s), CFrame.new(tailPos + Vector3.new(0, 0, i * 3*s)), color, "Tail" .. i, dragon)
    end

    -- Wings
    for side = -1, 1, 2 do
        createPart(Vector3.new(8*s, 0.5*s, 6*s),
            CFrame.new(position + Vector3.new(side * 6*s, 2*s, 0)) * CFrame.Angles(0, 0, math.rad(side * 20)),
            color, (side == 1 and "RWing" or "LWing"), dragon)
    end

    -- Legs
    for _, offset in ipairs({{-2, -3}, {2, -3}, {-2, 3}, {2, 3}}) do
        createPart(Vector3.new(1.5*s, 3*s, 1.5*s),
            CFrame.new(position + Vector3.new(offset[1]*s, -2*s, offset[2]*s)),
            color, "Leg", dragon)
    end

    dragon.Parent = parent
    return dragon
end

Model Organization

Workspace/
  MapName/
    Terrain/          -- Ground, borders, natural features
      MainGround
      MapBorder/
        Mountains/
        Trees/
        InvisibleWalls/
    HubArea/          -- Spawn, shops, etc
    ObbyCourse/       -- Stages
    WinnerArea/       -- Victory zone

Rules

  • Use Folders for organization (not Models)
  • Use Models only for geometric objects that move together
  • Set PrimaryPart only for physics-joined models
  • Anchor all static parts

Color Palette (Classic Style)

ColorBrickColor NameUse For
Grey"Medium stone grey"Neutral, backgrounds, stone
Dark Grey"Dark stone grey"Shadows, metal, dark accents
Brown"Reddish brown"Wood, doors, trunks
Green"Bright green"Grass, leaves, nature
Red"Bright red"Lava, danger, accents
Blue"Bright blue"Water, ice, sky elements
Yellow"Bright yellow"Gold, highlights, rewards
White"Institutional white"Snow, clean surfaces

Checklist Before Building

  • Stud materials loaded at script start?
  • Using createPart() function (not raw Instance.new)?
  • All surfaces set to Smooth?
  • Layer system defined to avoid Z-fighting?
  • All static parts anchored?
  • Map border uses mountains + forest (not plain walls)?
  • Part count reasonable (<5000 in view)?

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View