4d-simulation
Create 4D construction simulations by linking BIM elements to project schedules. Generate time-based visualizations, sequence analysis, and construction phasing with Gantt integration.
Install / Use
npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill 4d-simulationInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Development & EngineeringSupported Platforms
Our assessment of 4d-simulation
4d-simulation scores 91/100 on our quality scale, 1218th of 4,663 Development & Engineering skills we index (top 27%).
Its SKILL.md is 19 KB long, well organised into 16 sections with 6 code examples: a thorough specification that gives an agent plenty to work with.
It has 333 GitHub stars, a meaningful sign that others use it.
Maintenance, license and trust
- The repository was last updated about 2 months ago, so 4d-simulation is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
4d-simulation compared with similar skills
All 4 of these similar skills score higher than 4d-simulation; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| 4d-simulation (this skill)by datadrivenconstruction | 91 | 333 | 2mo ago | SKILL.md |
| Agent-Reachby Panniantong | 100 | 106.4k | 5d ago | CLAUDE.md |
| taste-skillby Leonxlnx | 100 | 105.7k | today | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 78.3k | today | CLAUDE.md |
| ai-job-searchby ai-job-search-dev | 100 | 67.6k | 2d ago | CLAUDE.md |
Frequently asked questions
- How do I install 4d-simulation?
- Run
npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill 4d-simulation. The install tabs above show the steps for each supported agent. - Which AI agents does 4d-simulation work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is 4d-simulation safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is 4d-simulation still maintained?
- The repository was last updated about 2 months ago, so 4d-simulation is actively maintained.
Skill content
View source on GitHubname: "4d-simulation" description: "Create 4D construction simulations by linking BIM elements to project schedules. Generate time-based visualizations, sequence analysis, and construction phasing with Gantt integration." homepage: "https://datadrivenconstruction.io" metadata: {"openclaw": {"emoji": "🎬", "os": ["darwin", "linux", "win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}
4D Simulation for Construction
Overview
Based on DDC methodology (Chapter 3.3), this skill implements 4D BIM simulations - linking 3D model elements to the 4th dimension: time. Visualize construction sequences, detect scheduling conflicts, and optimize work phasing.
Book Reference: "4D, 6D-8D и расчет CO2" / "4D-8D BIM and CO2 Calculation"
"4D моделирование позволяет визуализировать последовательность строительства и выявлять конфликты на этапе планирования." — DDC Book, Chapter 3.3
Quick Start
import pandas as pd
from datetime import datetime, timedelta
# BIM elements with schedule data
elements = pd.DataFrame({
'ElementId': ['E001', 'E002', 'E003', 'E004'],
'Category': ['Foundation', 'Column', 'Beam', 'Slab'],
'Level': ['Level 0', 'Level 1', 'Level 1', 'Level 1'],
'Start_Date': ['2024-01-01', '2024-01-15', '2024-02-01', '2024-02-15'],
'End_Date': ['2024-01-14', '2024-01-31', '2024-02-14', '2024-02-28'],
'Phase': ['Structure', 'Structure', 'Structure', 'Structure']
})
elements['Start_Date'] = pd.to_datetime(elements['Start_Date'])
elements['End_Date'] = pd.to_datetime(elements['End_Date'])
elements['Duration_Days'] = (elements['End_Date'] - elements['Start_Date']).dt.days
# Get elements active on a specific date
target_date = pd.to_datetime('2024-01-20')
active_elements = elements[
(elements['Start_Date'] <= target_date) &
(elements['End_Date'] >= target_date)
]
print(f"Elements under construction on {target_date.date()}:")
print(active_elements[['ElementId', 'Category']])
4D Data Model
Schedule-Element Linking
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from typing import List, Dict, Optional
class ScheduleElementLinker:
"""Link BIM elements to schedule activities"""
def __init__(self, elements_df: pd.DataFrame, schedule_df: pd.DataFrame):
self.elements = elements_df.copy()
self.schedule = schedule_df.copy()
self.links = pd.DataFrame()
def auto_link_by_category(self, mapping: Dict[str, str]):
"""Auto-link elements to activities by category mapping
Args:
mapping: Dict mapping element categories to activity names
e.g., {'Wall': 'Structural Walls', 'Slab': 'Floor Construction'}
"""
links = []
for category, activity_name in mapping.items():
# Find elements of this category
category_elements = self.elements[
self.elements['Category'] == category
]['ElementId'].tolist()
# Find matching activity
activity = self.schedule[
self.schedule['Activity'].str.contains(activity_name, case=False)
]
if not activity.empty and category_elements:
for elem_id in category_elements:
links.append({
'ElementId': elem_id,
'ActivityId': activity.iloc[0]['ActivityId'],
'Activity': activity.iloc[0]['Activity'],
'Start_Date': activity.iloc[0]['Start_Date'],
'End_Date': activity.iloc[0]['End_Date']
})
self.links = pd.DataFrame(links)
return self.links
def auto_link_by_level(self):
"""Auto-link elements based on level and construction sequence"""
# Get unique levels in order
levels = sorted(self.elements['Level'].unique())
links = []
for i, level in enumerate(levels):
level_elements = self.elements[self.elements['Level'] == level]
# Find activity for this level
level_activity = self.schedule[
self.schedule['Activity'].str.contains(level, case=False)
]
if not level_activity.empty:
for _, elem in level_elements.iterrows():
links.append({
'ElementId': elem['ElementId'],
'ActivityId': level_activity.iloc[0]['ActivityId'],
'Activity': level_activity.iloc[0]['Activity'],
'Start_Date': level_activity.iloc[0]['Start_Date'],
'End_Date': level_activity.iloc[0]['End_Date']
})
self.links = pd.DataFrame(links)
return self.links
def manual_link(self, element_id: str, activity_id: str):
"""Manually link element to activity"""
element = self.elements[self.elements['ElementId'] == element_id]
activity = self.schedule[self.schedule['ActivityId'] == activity_id]
if element.empty or activity.empty:
raise ValueError("Element or activity not found")
new_link = pd.DataFrame([{
'ElementId': element_id,
'ActivityId': activity_id,
'Activity': activity.iloc[0]['Activity'],
'Start_Date': activity.iloc[0]['Start_Date'],
'End_Date': activity.iloc[0]['End_Date']
}])
self.links = pd.concat([self.links, new_link], ignore_index=True)
return self.links
def get_linked_elements(self):
"""Get elements with schedule data"""
return self.elements.merge(
self.links[['ElementId', 'ActivityId', 'Start_Date', 'End_Date']],
on='ElementId',
how='left'
)
4D Simulation Engine
class Simulation4D:
"""4D construction simulation engine"""
def __init__(self, linked_elements: pd.DataFrame):
self.elements = linked_elements.copy()
self.elements['Start_Date'] = pd.to_datetime(self.elements['Start_Date'])
self.elements['End_Date'] = pd.to_datetime(self.elements['End_Date'])
self.project_start = self.elements['Start_Date'].min()
self.project_end = self.elements['End_Date'].max()
def get_state_at_date(self, target_date: datetime) -> pd.DataFrame:
"""Get element states at a specific date"""
target = pd.to_datetime(target_date)
# Determine state for each element
conditions = [
target < self.elements['Start_Date'], # Not started
(self.elements['Start_Date'] <= target) & (target <= self.elements['End_Date']), # In progress
target > self.elements['End_Date'] # Completed
]
choices = ['not_started', 'in_progress', 'completed']
self.elements['State'] = np.select(conditions, choices, default='unknown')
return self.elements.copy()
def generate_timeline(self, interval_days: int = 7) -> List[Dict]:
"""Generate timeline snapshots"""
timeline = []
current_date = self.project_start
while current_date <= self.project_end:
state = self.get_state_at_date(current_date)
snapshot = {
'date': current_date,
'not_started': len(state[state['State'] == 'not_started']),
'in_progress': len(state[state['State'] == 'in_progress']),
'completed': len(state[state['State'] == 'completed']),
'total': len(state)
}
snapshot['progress_pct'] = (snapshot['completed'] / snapshot['total']) * 100
timeline.append(snapshot)
current_date += timedelta(days=interval_days)
return timeline
def get_elements_in_progress(self, target_date: datetime) -> pd.DataFrame:
"""Get elements currently under construction"""
state = self.get_state_at_date(target_date)
return state[state['State'] == 'in_progress']
def analyze_construction_sequence(self) -> pd.DataFrame:
"""Analyze construction sequence by category and level"""
sequence = self.elements.groupby(['Level', 'Category']).agg({
'Start_Date': 'min',
'End_Date': 'max',
'ElementId': 'count'
}).rename(columns={'ElementId': 'Element_Count'})
sequence['Duration_Days'] = (sequence['End_Date'] - sequence['Start_Date']).dt.days
sequence = sequence.sort_values('Start_Date').reset_index()
return sequence
def detect_parallel_work(self) -> pd.DataFrame:
"""Detect work happening in parallel"""
dates = pd.date_range(self.project_start, self.project_end, freq='D')
parallel_work = []
for date in dates:
state = self.get_state_at_date(date)
in_progress = state[state['State'] == 'in_progress']
if len(in_progress) > 1:
categories = in_progress['Category'].unique().tolist()
levels = in_progress['Level'].unique().tolist()
parallel_work.append({
'date': date,
'parallel_count': len(in_progress),
'categories': ', '.join(categories),
'levels': ', '.join(levels)
})
return pd.DataFrame(parallel_work)
Gantt Chart Integration
Gantt Chart Generator
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.patches import Patch
class GanttChartGenerator:
"""Generate Gantt charts for 4D simulation"""
def __init__(self, elements: pd.DataFrame):
self.elements = elements.copy()
self.colors = {
'Foundation': '#8B4513',
'Column': '#4169E1',
'Beam': '#228B22',
'Slab': '#DC143C',
'Wall': '#FF8C00',
'Roof': '#9932CC',
'MEP': '#20B2AA',
'Finishes': '#FFD700'
}
def create_gantt(self, group_by='Category', figsize=(14, 8)):
"""Create Gantt chart grouped by specified column"""
fig, ax = plt.subplots(figsize=figsize)
# Group elements
groups = self.elements.groupby(group_by)
y_pos = 0
y_labels = []
legend_elements = []
for group_name, group_df in groups:
color = self.colors.get(group_name, '#808080')
for _, row in group_df.iterrows():
start = row['Start_Date']
duration = (row['End_Date'] - row['Start_Date']).days
ax.barh(y_pos, duration, left=start, height=0.6,
color=color, alpha=0.8, edgecolor='black', linewidth=0.5)
y_pos += 1
y_labels.append(group_name)
legend_elements.append(Patch(facecolor=color, label=group_name))
# Formatting
ax.set_yticks(range(len(self.elements)))
ax.set_yticklabels(self.elements['ElementId'])
ax.set_xlabel('Date')
ax.set_title('Construction Schedule - Gantt Chart', fontsize=14, fontweight='bold')
# Date formatting
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=2))
plt.xticks(rotation=45)
# Legend
ax.legend(handles=legend_elements, loc='upper right')
# Grid
ax.grid(axis='x', alpha=0.3)
plt.tight_layout()
return fig
def create_level_gantt(self, figsize=(14, 10)):
"""Create Gantt chart grouped by level"""
fig, ax = plt.subplots(figsize=figsize)
levels = sorted(self.elements['Level'].unique())
for i, level in enumerate(levels):
level_elements = self.elements[self.elements['Level'] == level]
for _, row in level_elements.iterrows():
color
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
106.4kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
taste-skill
105.7kAgent skills that give coding agents taste: art direction, reference images and a browser check instead of generic AI pages
headroom
78.3kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
ai-job-search
67.6kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
