import json import os PROJECT_ROOT = "/Users/davidkotnik/repos/novafarma" LDTK_FILE = os.path.join(PROJECT_ROOT, "AutoLayers_2_stamps.ldtk") def main(): # Load existing (or recreate structure if needed, but let's assume structure from previous step which was correct) # Actually, we want to SWITCH to using the ATLAS. # 1. DEFINE ATLAS TILESET # Path: godot/phases/FAZA_1_FARMA/tilesets/TerrainAtlas.png atlas_def = { "__cWid": 16, # 512 / 32 "__cHei": 16, # 512 / 32 "identifier": "Terrain_Atlas", "uid": 150, "relPath": "godot/phases/FAZA_1_FARMA/tilesets/TerrainAtlas.png", "embedAtlas": None, "pxWid": 512, "pxHei": 512, "tileGridSize": 32, "spacing": 0, "padding": 0, "tags": [], "tagsSourceEnumUid": None, "enumTags": [], "customData": [], "savedSelections": [], "cachedPixelData": None } # 2. INTGRID LAYER (Control) - SAME AS BEFORE intgrid_uid = 200 int_grid_def = { "__type": "IntGrid", "identifier": "Terrain_Control", "type": "IntGrid", "uid": intgrid_uid, "gridSize": 32, "displayOpacity": 1, "pxOffsetX": 0, "pxOffsetY": 0, "intGridValues": [ { "value": 1, "identifier": "Grass", "color": "#36BC29" }, { "value": 2, "identifier": "Dirt", "color": "#8B5F2A" }, { "value": 3, "identifier": "Water", "color": "#388BE7" }, { "value": 4, "identifier": "Farm", "color": "#54301A" } ], "autoRuleGroups": [], "autoSourceLayerDefUid": None, "tilesetDefUid": None, "tilePivotX": 0, "tilePivotY": 0 } # 3. AUTO LAYERS (Visuals) # Now we map to regions in the ATLAS! # Grass: Top-Left (0,0) -> ID 0 (and onwards) # Dirt: Top-Right (256,0) -> Column 8 -> ID 8 # Water: Bottom-Left (0,256) -> Row 8 -> ID 128 # Farm: Bottom-Right (256,256) -> Col 8, Row 8 -> ID 136 # Wait, simple tile arithmetic: # 512 width = 16 tiles. # Grass (0,0): Tile 0 # Dirt (256,0): 256/32 = 8th tile. ID = 8. # Water (0,256): 256/32 = 8th row. 8 * 16 = 128. ID = 128. # Farm (256,256): 8th col, 8th row. 128 + 8 = 136. ID = 136. # We want RANDOM tiles from those 256x256 regions. # Each region is 8x8 tiles = 64 tiles. def get_region_ids(start_id, rows=8, cols=8, stride=16): ids = [] for r in range(rows): for c in range(cols): ids.append(start_id + (r * stride) + c) return ids grass_ids = get_region_ids(0) dirt_ids = get_region_ids(8) water_ids = get_region_ids(128) farm_ids = get_region_ids(136) # We need just ONE AutoLayer "Visuals" that handles all rules! # Or separate layers, but using the SAME tileset is more efficient. # Let's make ONE "Terrain_Visuals" layer with 4 rule groups. rule_uid = 5000 # Rules rules_groups = [] # Helper for group def make_group(name, int_val, tile_ids): nonlocal rule_uid g_uid = rule_uid; rule_uid += 1 r_uid = rule_uid; rule_uid += 1 return { "uid": g_uid, "name": name, "active": True, "isOptional": False, "rules": [{ "uid": r_uid, "active": True, "size": 1, "tileIds": tile_ids, "alpha": 1, "chance": 1, "breakOnMatch": True, "pattern": [int_val], # Match IntGrid value "flipX": True, "flipY": True, "xModulo": 1, "yModulo": 1, "checker": "None", "tileMode": "Random", "pivotX": 0, "pivotY": 0, "outTileIds": [], "perlinActive": False, "perlinSeed": 0, "perlinScale": 0.2, "perlinOctaves": 2 }] } rules_groups.append(make_group("Grass", 1, grass_ids)) rules_groups.append(make_group("Dirt", 2, dirt_ids)) rules_groups.append(make_group("Water", 3, water_ids)) rules_groups.append(make_group("Farm", 4, farm_ids)) visual_layer = { "__type": "AutoLayer", "identifier": "Terrain_Visuals", "type": "AutoLayer", "uid": 300, "gridSize": 32, "displayOpacity": 1, "pxOffsetX": 0, "pxOffsetY": 0, "autoSourceLayerDefUid": intgrid_uid, "tilesetDefUid": 150, # The Atlas "tilePivotX": 0, "tilePivotY": 0, "autoRuleGroups": rules_groups } # Header & Setup data = { "__header__": { "fileType": "LDtk Project JSON", "app": "LDtk", "doc": "https://ldtk.io/json", "schema": "https://ldtk.io/files/JSON_SCHEMA.json", "appAuthor": "David via Antigravity", "appVersion": "1.5.3", "url": "https://ldtk.io" }, "iid": "6440c680-d380-11f0-b813-5db2a94f8a9c", "jsonVersion": "1.5.3", "appBuildId": 473703, "nextUid": 10000, "identifierStyle": "Capitalize", "toc": [], "worldLayout": "Free", "worldGridWidth": 256, "worldGridHeight": 256, "defaultLevelWidth": 512, "defaultLevelHeight": 512, "defaultPivotX": 0, "defaultPivotY": 0, "defaultGridSize": 16, "defaultEntityWidth": 16, "defaultEntityHeight": 16, "bgColor": "#40465B", "defaultLevelBgColor": "#696A79", "minifyJson": False, "externalLevels": False, "exportTiled": False, "simplifiedExport": False, "imageExportMode": "None", "exportLevelBg": True, "pngFilePattern": None, "backupOnSave": False, "backupLimit": 10, "backupRelPath": None, "levelNamePattern": "Level_%idx", "tutorialDesc": None, "customCommands": [], "flags": [], "defs": { "layers": [int_grid_def, visual_layer], # Control on BOTTOM in list = Rendered first? No. List index 0 = Topmost. We want Visuals on top? No, Control on top to see what we paint (transparently) or underneath? Usually Control is hidden or semi-transparent. Let's put Control first (Top). "entities": [], "tilesets": [atlas_def], "enums": [], "externalEnums": [], "levelFields": [] }, "levels": [{ "identifier": "Level_0", "iid": "level_0_iid", "uid": 0, "worldX": 0, "worldY": 0, "worldDepth": 0, "pxWid": 1024, "pxHei": 1024, "__bgColor": "#696A79", "bgColor": None, "useAutoIdentifier": True, "bgRelPath": None, "bgPos": None, "bgPivotX": 0.5, "bgPivotY": 0.5, "__smartColor": "#ADADB5", "__bgPos": None, "externalRelPath": None, "fieldInstances": [], "layerInstances": [ { "__identifier": "Terrain_Control", "__type": "IntGrid", "__cWid": 32, "__cHei": 32, "__gridSize": 32, "__opacity": 1, "__pxTotalOffsetX": 0, "__pxTotalOffsetY": 0, "__tilesetDefUid": None, "__tilesetRelPath": None, "iid": "inst_200", "levelId": 0, "layerDefUid": 200, "pxOffsetX": 0, "pxOffsetY": 0, "visible": True, "optionalRules": [], "intGridCsv": [0]*1024, "autoLayerTiles": [], "seed": 0, "overrideTilesetUid": None, "gridTiles": [], "entityInstances": [] }, { "__identifier": "Terrain_Visuals", "__type": "AutoLayer", "__cWid": 32, "__cHei": 32, "__gridSize": 32, "__opacity": 1, "__pxTotalOffsetX": 0, "__pxTotalOffsetY": 0, "__tilesetDefUid": 150, "__tilesetRelPath": None, "iid": "inst_300", "levelId": 0, "layerDefUid": 300, "pxOffsetX": 0, "pxOffsetY": 0, "visible": True, "optionalRules": [], "intGridCsv": [], "autoLayerTiles": [], "seed": 0, "overrideTilesetUid": None, "gridTiles": [], "entityInstances": [] } ], "__neighbours": [] }], "worlds": [], "dummyWorldIid": "6440c681-d380-11f0-b813-a103d476f7a1" } with open(LDTK_FILE, 'w') as f: json.dump(data, f, indent=2) print("LDtk project updated to connect Atlas with IntGrid!") if __name__ == "__main__": main()