[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f1h3l37ulqx7a1":3},{"_id":4,"slug":5,"title":6,"subtitle":7,"kind":8,"cards":9,"tags":53,"categories":55,"source":57,"lang":60,"author":61,"audioState":64,"stats":65,"publishedAt":68,"renderer":69},"6abb2cb8ca21c797c7e9c028","building-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6","Building ShipCheck: a static preflight scanner for Unity projects","How I went from noisy project scanning to shipping graphs, confidence-aware readiness, and legacy Unity support.","news",[10,13,18,23,28,33,38,43,48],{"headline":6,"body":11,"imageUrl":12,"sourceImageUrl":12},"How I went from noisy project scanning to shipping graphs, confidence-aware readiness, and legacy Unity support. Building ShipCheck: a static preflight scanner for Unity projects How I went from noisy project scanning to shipping graphs, confidence-aware readiness, and legacy Unity support. How I went from noisy project scanning to shipping graphs, confidence-aware readiness, and legacy Unity support. I’ve been building ShipCheck, a local, read-only preflight scanner for Unity projects. The original goal sounded simple: Point the tool at a Unity project folder and tell me what could prevent this project from shipping. Point the tool at a Unity project folder and tell me what could prevent this project from shipping. The implementation turned out to be much more interesting.","https:\u002F\u002Fmedia2.dev.to\u002Fdynamic\u002Fimage\u002Fwidth=1200,height=627,fit=cover,gravity=auto,format=auto\u002Fhttps%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7yheme8u1golaqbn92jp.png",{"headline":14,"body":15,"imageUrl":16,"images":17},"A Unity project can look structurally healthy while","A Unity project can look structurally healthy while still being incomplete. A completed legacy project can look suspicious because modern static analysis cannot parse its scenes properly. Third-party assets can generate hundreds of findings that have absolutely nothing to do with the final build. That forced me to separate several concepts that initially looked like one problem. Project Health is not Release Readiness One of the first mistakes was treating all findings as part of a single score. while still being perfectly shippable. Conversely, a structurally clean project may only contain one unfinished gameplay scene. So ShipCheck now separates: Observable technical defects and project hygiene. Evidence that the current project configuration represents something that could actually ship. How much reliable evidence ShipCheck was able to inspect.","\u002Fapi\u002Fmedia\u002Fposts\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6\u002F1.webp",{"local":16},{"headline":19,"body":20,"imageUrl":21,"images":22},"This distinction became especially important with old Unity","This distinction became especially important with old Unity projects. Sometimes the correct score is no score Some older Unity projects use scene serialization that cannot be reliably inspected offline. An early version of ShipCheck would still calculate something like: That looked precise, but it wasn’t honest. Now, if structural evidence is insufficient, ShipCheck reports: instead of inventing a readiness number. The internal diagnostic score may still exist for debugging, but it is not presented as a reliable release score. Building a Shipping Dependency Graph Another major issue was third-party noise. A Unity project may contain: Scanning everything equally produced terrible results.","\u002Fapi\u002Fmedia\u002Fposts\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6\u002F2.webp",{"local":21},{"headline":24,"body":25,"imageUrl":26,"images":27},"For example, a small WebGL trivia project looked","For example, a small WebGL trivia project looked badly broken because unresolved references inside TextMesh Pro example scenes were being treated as project release problems. The fix was to build a shipping dependency graph. ShipCheck starts from enabled build scenes and follows serialized GUID references through the project. That lets it distinguish:","\u002Fapi\u002Fmedia\u002Fposts\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6\u002F3.webp",{"local":26},{"headline":29,"body":30,"imageUrl":31,"images":32},"A broken GUID inside an unused demo scene","A broken GUID inside an unused demo scene can still be reported, but it should not reduce the release readiness of the actual game. Static analysis also needs to understand Unity runtime loading The dependency graph introduced another problem. Not everything used at runtime has a direct serialized reference from a scene. Unity projects often load content from: So dimensional analysis and project intelligence also include these standard runtime-loading locations. This mattered for an AR project that contained: The scene graph alone initially classified it as UNKNOWN. After including runtime resources, ShipCheck correctly classified it as: This was another surprisingly tricky distinction. One completed memory game had: cards implemented as physical 3D objects A naive signal counter saw strong 2D and strong 3D evidence and called it: But visually and structurally it was really a 2.5D game.","\u002Fapi\u002Fmedia\u002Fposts\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6\u002F4.webp",{"local":31},{"headline":34,"body":35,"imageUrl":36,"images":37},"The difference I ended up using is roughly","The difference I ended up using is roughly: A primarily flat or 2D presentation implemented partly with 3D mechanics. Independent 2D and 3D content modalities coexist in the project. plus an independent 3D model That distinction improved classification significantly. Missing dependency detection is harder than matching names At one point ShipCheck reported this as a blocker: DOTween was actually installed under: The detector was matching names too literally.","\u002Fapi\u002Fmedia\u002Fposts\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6\u002F5.webp",{"local":36},{"headline":39,"body":40,"imageUrl":41,"images":42},"Now ShipCheck also indexes namespaces declared by installed","Now ShipCheck also indexes namespaces declared by installed third-party source code, packages, assemblies and plugins before deciding that a dependency is missing. That removed false blockers without weakening real missing-dependency detection. Release states instead of only scores ShipCheck now uses several explicit release states: A deterministic missing dependency or similarly critical release problem exists. No effective enabled build-scene topology could be found. A build configuration exists, but static evidence is insufficient to assign a reliable numeric readiness score. I found these states much more useful than trying to force every project into a 0–100 number.","\u002Fapi\u002Fmedia\u002Fposts\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6\u002F6.webp",{"local":41},{"headline":44,"body":45,"imageUrl":46,"images":47},"ShipCheck currently analyzes: Shipping dependency graph Unresolved GUID","ShipCheck currently analyzes: Shipping dependency graph Unresolved GUID references Large and duplicate assets First-party vs third-party content 2D \u002F 2.5D \u002F 3D \u002F mixed project structure Rendering and physics signals Content completeness signals","\u002Fapi\u002Fmedia\u002Fposts\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6\u002F7.webp",{"local":46},{"headline":49,"body":50,"imageUrl":51,"images":52},"It also generates an AI Context Pack: a","It also generates an AI Context Pack: a compact project brief designed to be pasted into tools such as ChatGPT, Claude or Codex without uploading the entire Unity project. No telemetry. No cloud upload. No API key. Read-only analysis. Testing it on real projects I tested the current version against several real Unity projects: projects with large third-party asset packages The interesting part was not getting every project to score highly. The useful part was getting each project to fail differently for the correct reason. That became the main design rule: A scanner should explain what it knows, what it suspects, and what it cannot reliably prove. A scanner should explain what it knows, what it suspects, and what it cannot reliably prove. I’ve just released the first public Windows build.","\u002Fapi\u002Fmedia\u002Fposts\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-proj-40c7e8a6\u002F8.webp",{"local":51},[54],"dev",[56],"Technology",{"name":58,"url":59},"Dev.to","https:\u002F\u002Fdev.to\u002Fthunderdanoae\u002Fbuilding-shipcheck-a-static-preflight-scanner-for-unity-projects-3b51","en",{"handle":62,"displayName":63},"spots","Spots","queued",{"views":66,"likes":67,"saves":67,"shares":67,"completions":67,"opens":67,"skips":67,"depthSum":67},3,0,"2026-09-29T03:12:56.684Z","local"]