{"record":{"id":"33c87bbccca68ca3","repo":"Anuken/Mindustry","slug":"max-image-size-exceeded","errorCode":null,"errorMessage":"Max image size exceeded","messagePattern":"Max image size exceeded","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/mindustry/mod/DataManager.java","lineNumber":87,"sourceCode":"\n        //remove content that doesn't need to be packed\n        contentToPack.removeAll(u -> imagesWithHashes.contains(hashes.get(u)));\n\n        ObjectMap<String, ImageAsset> imageMap = new ObjectMap<>();\n        for(var image : images){\n            imageMap.put(DataImagePacker.regionPrefix + image.name, image);\n        }\n        int[] packed = {0};\n        ObjectMap<String, PixmapRegion> imagePixmaps = new ObjectMap<>();\n        PixmapRegion error = new PixmapRegion(Pixmaps.blankPixmap());\n        UnlockableContent[] currentContent = {null};\n        String[] currentHash = {null};\n\n        MultiPacker saver = new MultiPacker(false){\n            @Override\n            public void add(PageType type, String name, PixmapRegion region, int[] splits, int[] pads){\n                try{\n                    if(region.pixmap.width > 2000) throw new IllegalArgumentException(\"Max image size exceeded\");\n\n                    //strip duplicate prefix\n                    if(name.startsWith(DataImagePacker.regionPrefix)) name = name.substring(DataImagePacker.regionPrefix.length());\n                    String path = \"generated/\" + currentHash[0] + \"/\" + name + \".png\";\n                    ImageAsset newImage = new ImageAsset();\n                    newImage.setPath(path);\n                    //it would be nice to do this async, but the pixmap typically gets disposed right after add() exist\n                    byte[] bytes = PixmapIO.writePngBytes(region.pixmap);\n                    newImage.updateData(bytes);\n\n                    images.add(newImage);\n                    packed[0] ++;\n                }catch(Exception e){\n                    Log.err(\"Failed to pack image \" + name, e);\n                }\n            }\n\n            @Override","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/mod/DataManager.java#L69-L105","documentation":"While packing generated data images into the atlas, DataManager installs a MultiPacker.add override that rejects any region whose pixmap width exceeds 2000 pixels. Oversized textures are refused to keep atlas pages within safe GPU limits.","triggerScenarios":"A data image (sprite) contributed to the packer is wider than 2000px during the data-image packing pass.","commonSituations":"Mod or generated asset includes an oversized sprite sheet; full-resolution artwork not downscaled; accidentally bundling a UI screenshot as a sprite.","solutions":["Resize the offending image so its width is at most 2000px.","Split a large sheet into several smaller textures.","Identify the culprit from the packing log / currentHash path."],"exampleFix":"// before: sprite.png is 4096x4096 -> 'Max image size exceeded'\n// after: downscale to <=2000px width (e.g. 1024x1024) and re-export","handlingStrategy":"validation","validationCode":"// Reject oversized textures before packing.\nif(region.pixmap.width > 2000) {\n    throw new IllegalArgumentException(\"Texture too wide (\" + region.pixmap.width + \" > 2000): \" + name);\n}","typeGuard":"boolean withinAtlasLimit(PixmapRegion r){ return r != null && r.pixmap.width <= 2000; }","tryCatchPattern":null,"preventionTips":["Cap sprite widths at 2000px during asset authoring.","Split large sheets into multiple textures.","Automate size checks in the mod build pipeline."],"tags":["modding","textures","assets","validation","atlas"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}