{"record":{"id":"9ecf2816cba3550c","repo":"Anuken/Mindustry","slug":"calling-getpixmap-outside-of-createicons-is-not-su","errorCode":null,"errorMessage":"Calling getPixmap outside of createIcons is not supported!","messagePattern":"Calling getPixmap outside of createIcons is not supported!","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/mindustry/mod/Mods.java","lineNumber":338,"sourceCode":"                    if(u.generateIcons && !c.minfo.mod.meta.pregenerated){\n                        u.createIcons(packer);\n                    }\n                }\n            });\n        }\n\n        waitForMain(() -> {\n            whitePixmap[0].dispose();\n            whiteTex[0].dispose();\n\n            //replace old atlas data\n            Core.atlas = packer.flush(filter, new TextureAtlas(){\n\n                @Override\n                public PixmapRegion getPixmap(AtlasRegion region){\n                    var other = super.getPixmap(region);\n                    if(other.pixmap.isDisposed()){\n                        throw new RuntimeException(\"Calling getPixmap outside of createIcons is not supported!\");\n                    }\n\n                    return other;\n                }\n            });\n\n            textureResize.each(e -> Core.atlas.find(e.key).scale = e.value);\n\n            Core.atlas.setErrorRegion(\"error\");\n            Log.debug(\"Total pages: @\", Core.atlas.getTextures().size);\n\n            packer.printStats();\n\n            Events.fire(new AtlasPackEvent(packer));\n\n            packer.dispose();\n\n            Log.debug(\"Total time to pack and generate sprites: @ms\", Time.timeSinceMillis(startTime));","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/mod/Mods.java#L320-L356","documentation":"After createIcons finishes, Mods flushes the packer into a new atlas whose getPixmap override throws if the underlying pixmap is disposed. A disposed pixmap means the call happened outside the createIcons window where pixmaps are guaranteed live — pixel access is unsupported at runtime.","triggerScenarios":"Code calls Core.atlas.getPixmap(region) after the atlas flush, when pixmaps have been disposed to save memory.","commonSituations":"Mod reads pixel data at runtime (e.g. for collision/procedural effects) instead of during createIcons; calling getPixmap in update/render loops.","solutions":["Read all pixel data you need inside createIcons() and cache the result.","Never call getPixmap in render/update/init-after-load paths.","If you need runtime pixels, ship a separate texture you control."],"exampleFix":"// before (runtime, throws)\nPixmapRegion px = Core.atlas.getPixmap(Core.atlas.find(\"my-block\"));\n\n// after (during createIcons)\n@Override\npublic void createIcons(MultiPacker packer) {\n    cached = packer.get(\"my-block\").pixmap.copy(); // cache for later\n}","handlingStrategy":"validation","validationCode":"// Only touch pixmaps during createIcons; cache what you need.\nif(pixmapRegion.pixmap.isDisposed()) {\n    throw new IllegalStateException(\"Pixmap accessed after disposal; read during createIcons only.\");\n}","typeGuard":"boolean pixmapLive(PixmapRegion r){ return r != null && !r.pixmap.isDisposed(); }","tryCatchPattern":null,"preventionTips":["Read and cache pixel data inside createIcons().","Avoid Core.atlas.getPixmap() in runtime/render paths.","Ship separate runtime textures if you need pixels later."],"tags":["modding","textures","atlas","lifecycle","resources"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}