{"record":{"id":"a00ee90135135eda","repo":"Anuken/Mindustry","slug":"unknown-mesh-type-tname","errorCode":null,"errorMessage":"Unknown mesh type: ${tname}","messagePattern":"Unknown mesh type: (.+?)","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/mindustry/mod/ContentParser.java","lineNumber":1155,"sourceCode":"                data.getFloat(\"colorThreshold\", 0.5f));\n            case \"SunMesh\" -> {\n                var cvals = data.get(\"colors\").asStringArray();\n                var colors = new Color[cvals.length];\n                for(int i=0; i<cvals.length; i++){\n                    colors[i] = Color.valueOf(cvals[i]);\n                }\n\n                yield new SunMesh(planet, data.getInt(\"divisions\", 1), data.getInt(\"octaves\", 1), data.getFloat(\"persistence\", 0.5f),\n                data.getFloat(\"scl\", 1f), data.getFloat(\"pow\", 1f), data.getFloat(\"mag\", 0.5f),\n                data.getFloat(\"colorScale\", 1f), colors);\n            }\n            case \"HexSkyMesh\" -> new HexSkyMesh(planet,\n                data.getInt(\"seed\", 0), data.getFloat(\"speed\", 0), data.getFloat(\"radius\", 1f),\n                data.getInt(\"divisions\", 3), Color.valueOf(data.getString(\"color\", \"ffffff\")), data.getInt(\"octaves\", 1),\n                data.getFloat(\"persistence\", 0.5f), data.getFloat(\"scale\", 1f), data.getFloat(\"thresh\", 0.5f));\n            case \"MultiMesh\" -> new MultiMesh(parseMeshes(planet, data.get(\"meshes\")));\n            case \"MatMesh\" -> new MatMesh(parseMesh(planet, data.get(\"mesh\")), parser.readValue(Mat3D.class, data.get(\"mat\")));\n            default -> throw new RuntimeException(\"Unknown mesh type: \" + tname);\n        };\n    }\n\n    private PartProgress parseProgressOp(PartProgress base, String op, JsonValue data){\n        //I have to hard-code this, no easy way of getting parameter names, unfortunately\n        return switch(op){\n            case \"inv\" -> base.inv();\n            case \"slope\" -> base.slope();\n            case \"clamp\" -> base.clamp();\n            case \"delay\" -> base.delay(data.getFloat(\"amount\"));\n            case \"sustain\" -> base.sustain(data.getFloat(\"offset\", 0f), data.getFloat(\"grow\", 0f), data.getFloat(\"sustain\"));\n            case \"shorten\" -> base.shorten(data.getFloat(\"amount\"));\n            case \"compress\" -> base.compress(data.getFloat(\"start\"), data.getFloat(\"end\"));\n            case \"add\" -> data.has(\"amount\") ? base.add(data.getFloat(\"amount\")) : base.add(parser.readValue(PartProgress.class, data.get(\"other\")));\n            case \"blend\" -> base.blend(parser.readValue(PartProgress.class, data.get(\"other\")), data.getFloat(\"amount\"));\n            case \"mul\" -> data.has(\"amount\") ? base.mul(data.getFloat(\"amount\")) : base.mul(parser.readValue(PartProgress.class, data.get(\"other\")));\n            case \"min\" -> base.min(parser.readValue(PartProgress.class, data.get(\"other\")));\n            case \"sin\" -> base.sin(data.has(\"offset\") ? data.getFloat(\"offset\") : 0f, data.getFloat(\"scl\"), data.getFloat(\"mag\"));","sourceCodeStart":1137,"sourceCodeEnd":1173,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/mod/ContentParser.java#L1137-L1173","documentation":"parseMesh() switches on the mesh config's \"type\" string to instantiate the right mesh class (SunMesh, HexSkyMesh, MultiMesh, MatMesh, etc.). An unrecognized type name hits the default branch and throws, since the mesh cannot be constructed.","triggerScenarios":"A planet \"mesh\" (or \"cloudMesh\") object specifies \"type\": \"<unknown>\" where <unknown> is not one of the cases in parseMesh().","commonSituations":"Typo in the mesh type name; using a mesh class from a newer/older build; referencing a custom mesh not registered for JSON parsing.","solutions":["Use a mesh type name that exists as a case in parseMesh() (SunMesh, HexSkyMesh, MultiMesh, MatMesh, and others listed in ContentParser.java around line 1100-1155).","Check the spelling and capitalization exactly.","For custom meshes, build them in code rather than JSON."],"exampleFix":"// before\n{ \"type\": \"sun-mesh\", \"divisions\": 2 }\n// after\n{ \"type\": \"SunMesh\", \"divisions\": 2 }","handlingStrategy":"validation","validationCode":"// Whitelist mesh type names before constructing mesh configs.\nSet<String> meshTypes = Set.of(\"SunMesh\",\"HexSkyMesh\",\"MultiMesh\",\"MatMesh\" /* + others in parseMesh() */);\nString mt = meshObject.getString(\"type\", \"\");\nif(!meshTypes.contains(mt)) throw new IllegalStateException(\"Unknown mesh type '\" + mt + \"'\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cross-check mesh type names with parseMesh() cases.","Build custom meshes in code."],"tags":["mindustry","modding","json","content-parser","planet","mesh","unknown-type"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}