[{"data":1,"prerenderedAt":863},["ShallowReactive",2],{"cycle-doc-qmap-c2-CYCLE.md":3},{"cycle":4,"project":7,"path":10,"title":11,"toc":12,"ast":23},{"id":5,"title":6},"c2","entity-meshes",{"id":8,"label":9},"qmap","Qmap","CYCLE.md","c2.entity-meshes - Cycle Notes",[13,14,15,16,17,18,19,20,21,22],"Summary","Architecture","Entity Shapes & Behaviors","State System","What Works Well","Lessons Learned","Technical Debt \u002F Future Work","Files","Ready for Next Cycle","Visual record",{"type":24,"children":25},"root",[26,34,40,44,49,56,69,75,86,97,102,128,154,170,188,191,196,324,327,332,337,477,482,485,490,560,563,568,594,620,637,662,665,670,738,741,746,755,758,763,775,780,789,858],{"type":27,"tag":28,"props":29,"children":31},"element","h2",{"id":30},"summary",[32],{"type":33,"value":13},"text",{"type":27,"tag":35,"props":36,"children":37},"p",{},[38],{"type":33,"value":39},"Established a solid OOP foundation for actor entity meshes with distinct visual identities, state management, and animation systems.",{"type":27,"tag":41,"props":42,"children":43},"hr",{},[],{"type":27,"tag":28,"props":45,"children":47},{"id":46},"architecture",[48],{"type":33,"value":14},{"type":27,"tag":50,"props":51,"children":53},"h3",{"id":52},"class-hierarchy",[54],{"type":33,"value":55},"Class Hierarchy",{"type":27,"tag":57,"props":58,"children":62},"pre",{"className":59,"code":61,"language":33},[60],"language-text","BaseMesh (abstract)\n├── AppMesh      - Dodecahedron, full tumble spin\n├── ServiceMesh  - Hexagonal prism, grounded spin\n├── DatabaseMesh - Stacked octagon slabs, grounded spin\n└── VendorMesh   - Octahedron + favicon sprite, full tumble\n",[63],{"type":27,"tag":64,"props":65,"children":67},"code",{"__ignoreMap":66},"",[68],{"type":33,"value":61},{"type":27,"tag":50,"props":70,"children":72},{"id":71},"key-patterns",[73],{"type":33,"value":74},"Key Patterns",{"type":27,"tag":35,"props":76,"children":77},{},[78,84],{"type":27,"tag":79,"props":80,"children":81},"strong",{},[82],{"type":33,"value":83},"1. Animation Config Merging",{"type":33,"value":85},"\nSubclasses define their defaults, then spread incoming options on top:",{"type":27,"tag":57,"props":87,"children":92},{"className":88,"code":89,"language":90,"meta":66,"style":91},"language-js","const animation = {\n  bob: false,\n  spin: true,\n  spinMode: \"grounded\",  \u002F\u002F subclass default\n  ...options.animation,   \u002F\u002F caller can override\n};\n","js","undefined",[93],{"type":27,"tag":64,"props":94,"children":95},{"__ignoreMap":66},[96],{"type":33,"value":89},{"type":27,"tag":35,"props":98,"children":99},{},[100],{"type":33,"value":101},"This ensures type-specific behaviors persist even when callers provide partial options.",{"type":27,"tag":35,"props":103,"children":104},{},[105,110,112,118,120,126],{"type":27,"tag":79,"props":106,"children":107},{},[108],{"type":33,"value":109},"2. State Material Registration",{"type":33,"value":111},"\nMaterials that should respond to state changes register via ",{"type":27,"tag":64,"props":113,"children":115},{"className":114},[],[116],{"type":33,"value":117},"registerStateMaterial()",{"type":33,"value":119},". The base ",{"type":27,"tag":64,"props":121,"children":123},{"className":122},[],[124],{"type":33,"value":125},"setState()",{"type":33,"value":127}," iterates and updates color\u002Fopacity. Materials that should stay constant (like vendor favicons) simply don't register.",{"type":27,"tag":35,"props":129,"children":130},{},[131,136,138,144,146,152],{"type":27,"tag":79,"props":132,"children":133},{},[134],{"type":33,"value":135},"3. Disposable Resource Tracking",{"type":33,"value":137},"\nAll geometries, materials, and textures call ",{"type":27,"tag":64,"props":139,"children":141},{"className":140},[],[142],{"type":33,"value":143},"registerDisposable()",{"type":33,"value":145},". The ",{"type":27,"tag":64,"props":147,"children":149},{"className":148},[],[150],{"type":33,"value":151},"dispose()",{"type":33,"value":153}," method cleans up everything - prevents GPU memory leaks.",{"type":27,"tag":35,"props":155,"children":156},{},[157,162,168],{"type":27,"tag":79,"props":158,"children":159},{},[160],{"type":33,"value":161},"4. Edge Line Helpers",{"type":27,"tag":64,"props":163,"children":165},{"className":164},[],[166],{"type":33,"value":167},"createEdgeLines(geometry, options)",{"type":33,"value":169}," centralizes the LineMaterial\u002FLineSegments2 boilerplate. Supports optional material reuse for efficiency (DatabaseMesh shares one edge material across 3 slabs).",{"type":27,"tag":35,"props":171,"children":172},{},[173,178,180,186],{"type":27,"tag":79,"props":174,"children":175},{},[176],{"type":33,"value":177},"5. Canvas Texture Redrawing",{"type":33,"value":179},"\nLabels and favicons store their canvas\u002Fcontext for dynamic updates. On state change, redraw the canvas and set ",{"type":27,"tag":64,"props":181,"children":183},{"className":182},[],[184],{"type":33,"value":185},"texture.needsUpdate = true",{"type":33,"value":187},".",{"type":27,"tag":41,"props":189,"children":190},{},[],{"type":27,"tag":28,"props":192,"children":194},{"id":193},"entity-shapes-behaviors",[195],{"type":33,"value":15},{"type":27,"tag":197,"props":198,"children":199},"table",{},[200,229],{"type":27,"tag":201,"props":202,"children":203},"thead",{},[204],{"type":27,"tag":205,"props":206,"children":207},"tr",{},[208,214,219,224],{"type":27,"tag":209,"props":210,"children":211},"th",{},[212],{"type":33,"value":213},"Type",{"type":27,"tag":209,"props":215,"children":216},{},[217],{"type":33,"value":218},"Geometry",{"type":27,"tag":209,"props":220,"children":221},{},[222],{"type":33,"value":223},"Spin Mode",{"type":27,"tag":209,"props":225,"children":226},{},[227],{"type":33,"value":228},"Visual Meaning",{"type":27,"tag":230,"props":231,"children":232},"tbody",{},[233,257,280,302],{"type":27,"tag":205,"props":234,"children":235},{},[236,242,247,252],{"type":27,"tag":237,"props":238,"children":239},"td",{},[240],{"type":33,"value":241},"App",{"type":27,"tag":237,"props":243,"children":244},{},[245],{"type":33,"value":246},"Dodecahedron",{"type":27,"tag":237,"props":248,"children":249},{},[250],{"type":33,"value":251},"full (tumble)",{"type":27,"tag":237,"props":253,"children":254},{},[255],{"type":33,"value":256},"Complex, multi-faceted internal app",{"type":27,"tag":205,"props":258,"children":259},{},[260,265,270,275],{"type":27,"tag":237,"props":261,"children":262},{},[263],{"type":33,"value":264},"Service",{"type":27,"tag":237,"props":266,"children":267},{},[268],{"type":33,"value":269},"Hexagonal prism",{"type":27,"tag":237,"props":271,"children":272},{},[273],{"type":33,"value":274},"grounded (Y-axis)",{"type":27,"tag":237,"props":276,"children":277},{},[278],{"type":33,"value":279},"Modular, stable backend service",{"type":27,"tag":205,"props":281,"children":282},{},[283,288,293,297],{"type":27,"tag":237,"props":284,"children":285},{},[286],{"type":33,"value":287},"Database",{"type":27,"tag":237,"props":289,"children":290},{},[291],{"type":33,"value":292},"3 stacked octagons",{"type":27,"tag":237,"props":294,"children":295},{},[296],{"type":33,"value":274},{"type":27,"tag":237,"props":298,"children":299},{},[300],{"type":33,"value":301},"Layered data storage",{"type":27,"tag":205,"props":303,"children":304},{},[305,310,315,319],{"type":27,"tag":237,"props":306,"children":307},{},[308],{"type":33,"value":309},"Vendor",{"type":27,"tag":237,"props":311,"children":312},{},[313],{"type":33,"value":314},"Octahedron (diamond)",{"type":27,"tag":237,"props":316,"children":317},{},[318],{"type":33,"value":251},{"type":27,"tag":237,"props":320,"children":321},{},[322],{"type":33,"value":323},"External, valuable third-party",{"type":27,"tag":41,"props":325,"children":326},{},[],{"type":27,"tag":28,"props":328,"children":330},{"id":329},"state-system",[331],{"type":33,"value":16},{"type":27,"tag":35,"props":333,"children":334},{},[335],{"type":33,"value":336},"Four states with distinct visual treatments:",{"type":27,"tag":197,"props":338,"children":339},{},[340,371],{"type":27,"tag":201,"props":341,"children":342},{},[343],{"type":27,"tag":205,"props":344,"children":345},{},[346,351,356,361,366],{"type":27,"tag":209,"props":347,"children":348},{},[349],{"type":33,"value":350},"State",{"type":27,"tag":209,"props":352,"children":353},{},[354],{"type":33,"value":355},"Mesh Color",{"type":27,"tag":209,"props":357,"children":358},{},[359],{"type":33,"value":360},"Mesh Opacity",{"type":27,"tag":209,"props":362,"children":363},{},[364],{"type":33,"value":365},"Label Opacity",{"type":27,"tag":209,"props":367,"children":368},{},[369],{"type":33,"value":370},"Label Border",{"type":27,"tag":230,"props":372,"children":373},{},[374,400,425,450],{"type":27,"tag":205,"props":375,"children":376},{},[377,382,387,392,396],{"type":27,"tag":237,"props":378,"children":379},{},[380],{"type":33,"value":381},"active",{"type":27,"tag":237,"props":383,"children":384},{},[385],{"type":33,"value":386},"Purple",{"type":27,"tag":237,"props":388,"children":389},{},[390],{"type":33,"value":391},"1.0",{"type":27,"tag":237,"props":393,"children":394},{},[395],{"type":33,"value":391},{"type":27,"tag":237,"props":397,"children":398},{},[399],{"type":33,"value":386},{"type":27,"tag":205,"props":401,"children":402},{},[403,408,413,417,421],{"type":27,"tag":237,"props":404,"children":405},{},[406],{"type":33,"value":407},"highlighted",{"type":27,"tag":237,"props":409,"children":410},{},[411],{"type":33,"value":412},"Teal",{"type":27,"tag":237,"props":414,"children":415},{},[416],{"type":33,"value":391},{"type":27,"tag":237,"props":418,"children":419},{},[420],{"type":33,"value":391},{"type":27,"tag":237,"props":422,"children":423},{},[424],{"type":33,"value":412},{"type":27,"tag":205,"props":426,"children":427},{},[428,433,438,442,446],{"type":27,"tag":237,"props":429,"children":430},{},[431],{"type":33,"value":432},"warning",{"type":27,"tag":237,"props":434,"children":435},{},[436],{"type":33,"value":437},"Red",{"type":27,"tag":237,"props":439,"children":440},{},[441],{"type":33,"value":391},{"type":27,"tag":237,"props":443,"children":444},{},[445],{"type":33,"value":391},{"type":27,"tag":237,"props":447,"children":448},{},[449],{"type":33,"value":437},{"type":27,"tag":205,"props":451,"children":452},{},[453,458,463,468,473],{"type":27,"tag":237,"props":454,"children":455},{},[456],{"type":33,"value":457},"ignored",{"type":27,"tag":237,"props":459,"children":460},{},[461],{"type":33,"value":462},"White",{"type":27,"tag":237,"props":464,"children":465},{},[466],{"type":33,"value":467},"0.35",{"type":27,"tag":237,"props":469,"children":470},{},[471],{"type":33,"value":472},"0.3",{"type":27,"tag":237,"props":474,"children":475},{},[476],{"type":33,"value":462},{"type":27,"tag":35,"props":478,"children":479},{},[480],{"type":33,"value":481},"Vendor favicons: icon fades to 0.3 when ignored, white background stays full opacity.",{"type":27,"tag":41,"props":483,"children":484},{},[],{"type":27,"tag":28,"props":486,"children":488},{"id":487},"what-works-well",[489],{"type":33,"value":17},{"type":27,"tag":491,"props":492,"children":493},"ol",{},[494,505,515,525,542],{"type":27,"tag":495,"props":496,"children":497},"li",{},[498,503],{"type":27,"tag":79,"props":499,"children":500},{},[501],{"type":33,"value":502},"Clean separation",{"type":33,"value":504}," - BaseMesh handles lifecycle\u002Fanimation, subclasses define geometry",{"type":27,"tag":495,"props":506,"children":507},{},[508,513],{"type":27,"tag":79,"props":509,"children":510},{},[511],{"type":33,"value":512},"Semantic shapes",{"type":33,"value":514}," - Each type is instantly distinguishable",{"type":27,"tag":495,"props":516,"children":517},{},[518,523],{"type":27,"tag":79,"props":519,"children":520},{},[521],{"type":33,"value":522},"Grounded vs full spin",{"type":33,"value":524}," - Services\u002Fdatabases feel \"infrastructure-like\", apps\u002Fvendors feel \"dynamic\"",{"type":27,"tag":495,"props":526,"children":527},{},[528,533,535,540],{"type":27,"tag":79,"props":529,"children":530},{},[531],{"type":33,"value":532},"State reactivity",{"type":33,"value":534}," - Single ",{"type":27,"tag":64,"props":536,"children":538},{"className":537},[],[539],{"type":33,"value":125},{"type":33,"value":541}," call updates everything consistently",{"type":27,"tag":495,"props":543,"children":544},{},[545,550,552,558],{"type":27,"tag":79,"props":546,"children":547},{},[548],{"type":33,"value":549},"Factory pattern",{"type":33,"value":551}," - ",{"type":27,"tag":64,"props":553,"children":555},{"className":554},[],[556],{"type":33,"value":557},"createEntity(type, options)",{"type":33,"value":559}," for runtime type selection",{"type":27,"tag":41,"props":561,"children":562},{},[],{"type":27,"tag":28,"props":564,"children":566},{"id":565},"lessons-learned",[567],{"type":33,"value":18},{"type":27,"tag":35,"props":569,"children":570},{},[571,576,578,584,586,592],{"type":27,"tag":79,"props":572,"children":573},{},[574],{"type":33,"value":575},"Animation override trap",{"type":33,"value":577},": Initially subclasses overrode ",{"type":27,"tag":64,"props":579,"children":581},{"className":580},[],[582],{"type":33,"value":583},"update()",{"type":33,"value":585}," just to skip spin. Wasteful - the base class already checks ",{"type":27,"tag":64,"props":587,"children":589},{"className":588},[],[590],{"type":33,"value":591},"animState.spin",{"type":33,"value":593},". Removed overrides, used config flags instead.",{"type":27,"tag":35,"props":595,"children":596},{},[597,602,604,610,612,618],{"type":27,"tag":79,"props":598,"children":599},{},[600],{"type":33,"value":601},"Options merging matters",{"type":33,"value":603},": Using ",{"type":27,"tag":64,"props":605,"children":607},{"className":606},[],[608],{"type":33,"value":609},"options.animation ?? defaults",{"type":33,"value":611}," completely replaces defaults. Using ",{"type":27,"tag":64,"props":613,"children":615},{"className":614},[],[616],{"type":33,"value":617},"{ ...defaults, ...options.animation }",{"type":33,"value":619}," preserves type-specific behaviors.",{"type":27,"tag":35,"props":621,"children":622},{},[623,628,630,635],{"type":27,"tag":79,"props":624,"children":625},{},[626],{"type":33,"value":627},"Canvas textures need explicit updates",{"type":33,"value":629},": Three.js caches textures. After redrawing a canvas, must set ",{"type":27,"tag":64,"props":631,"children":633},{"className":632},[],[634],{"type":33,"value":185},{"type":33,"value":636}," or changes won't appear.",{"type":27,"tag":35,"props":638,"children":639},{},[640,645,647,653,655,661],{"type":27,"tag":79,"props":641,"children":642},{},[643],{"type":33,"value":644},"Favicon state handling",{"type":33,"value":646},": Registering favicon as a state material caused unwanted color tinting. Solution: don't register it, handle opacity separately in ",{"type":27,"tag":64,"props":648,"children":650},{"className":649},[],[651],{"type":33,"value":652},"_drawFavicon()",{"type":33,"value":654}," using ",{"type":27,"tag":64,"props":656,"children":658},{"className":657},[],[659],{"type":33,"value":660},"ctx.globalAlpha",{"type":33,"value":187},{"type":27,"tag":41,"props":663,"children":664},{},[],{"type":27,"tag":28,"props":666,"children":668},{"id":667},"technical-debt-future-work",[669],{"type":33,"value":19},{"type":27,"tag":491,"props":671,"children":672},{},[673,683,700,710,720],{"type":27,"tag":495,"props":674,"children":675},{},[676,681],{"type":27,"tag":79,"props":677,"children":678},{},[679],{"type":33,"value":680},"Label text truncation",{"type":33,"value":682}," - Long labels overflow the canvas. Consider auto-sizing or ellipsis.",{"type":27,"tag":495,"props":684,"children":685},{},[686,691,692,698],{"type":27,"tag":79,"props":687,"children":688},{},[689],{"type":33,"value":690},"Edge line resolution",{"type":33,"value":551},{"type":27,"tag":64,"props":693,"children":695},{"className":694},[],[696],{"type":33,"value":697},"LineMaterial",{"type":33,"value":699}," needs window resolution. Currently set at creation time - won't adapt to window resize.",{"type":27,"tag":495,"props":701,"children":702},{},[703,708],{"type":27,"tag":79,"props":704,"children":705},{},[706],{"type":33,"value":707},"Favicon error states",{"type":33,"value":709}," - Failed favicon loads silently. Could show a placeholder icon.",{"type":27,"tag":495,"props":711,"children":712},{},[713,718],{"type":27,"tag":79,"props":714,"children":715},{},[716],{"type":33,"value":717},"Performance at scale",{"type":33,"value":719}," - Each entity creates its own canvas texture. For 100+ entities, consider texture atlasing.",{"type":27,"tag":495,"props":721,"children":722},{},[723,728,730,736],{"type":27,"tag":79,"props":724,"children":725},{},[726],{"type":33,"value":727},"Animation easing",{"type":33,"value":729}," - Current bob uses raw ",{"type":27,"tag":64,"props":731,"children":733},{"className":732},[],[734],{"type":33,"value":735},"Math.sin()",{"type":33,"value":737},". Could add easing functions for more organic motion.",{"type":27,"tag":41,"props":739,"children":740},{},[],{"type":27,"tag":28,"props":742,"children":744},{"id":743},"files",[745],{"type":33,"value":20},{"type":27,"tag":57,"props":747,"children":750},{"className":748,"code":749,"language":33},[60],"entities\u002F\n├── index.js         - Factory + exports\n├── BaseMesh.js      - Base class (~285 lines)\n├── AppMesh.js       - Dodecahedron (~63 lines)\n├── ServiceMesh.js   - Hexagon (~64 lines)\n├── DatabaseMesh.js  - Stacked slabs (~90 lines)\n└── VendorMesh.js    - Diamond + favicon (~185 lines)\n\nshared\u002F\n├── testData.js      - Sample actors + state colors\n├── colorScheme.js   - Color definitions\n└── ExperimentBase.js - Three.js scene setup\n",[751],{"type":27,"tag":64,"props":752,"children":753},{"__ignoreMap":66},[754],{"type":33,"value":749},{"type":27,"tag":41,"props":756,"children":757},{},[],{"type":27,"tag":28,"props":759,"children":761},{"id":760},"ready-for-next-cycle",[762],{"type":33,"value":21},{"type":27,"tag":35,"props":764,"children":765},{},[766,768,773],{"type":33,"value":767},"The entity system is production-ready for connecting actors with traffic flows. Next logical step: ",{"type":27,"tag":79,"props":769,"children":770},{},[771],{"type":33,"value":772},"traffic lines\u002Fflows between entities",{"type":33,"value":774}," (c3?).",{"type":27,"tag":28,"props":776,"children":778},{"id":777},"visual-record",[779],{"type":33,"value":22},{"type":27,"tag":35,"props":781,"children":782},{},[783],{"type":27,"tag":784,"props":785,"children":788},"img",{"alt":786,"src":787},"outcomes","..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2.outcomes.png",[],{"type":27,"tag":790,"props":791,"children":792},"details",{},[793,798,805,813,821,829,837,844,851],{"type":27,"tag":30,"props":794,"children":795},{},[796],{"type":33,"value":797},"All states (9)",{"type":27,"tag":35,"props":799,"children":800},{},[801],{"type":27,"tag":784,"props":802,"children":804},{"alt":381,"src":803},"..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2-active.png",[],{"type":27,"tag":35,"props":806,"children":807},{},[808],{"type":27,"tag":784,"props":809,"children":812},{"alt":810,"src":811},"bright","..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2-bright.png",[],{"type":27,"tag":35,"props":814,"children":815},{},[816],{"type":27,"tag":784,"props":817,"children":820},{"alt":818,"src":819},"dark","..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2-dark.png",[],{"type":27,"tag":35,"props":822,"children":823},{},[824],{"type":27,"tag":784,"props":825,"children":828},{"alt":826,"src":827},"default","..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2-default.png",[],{"type":27,"tag":35,"props":830,"children":831},{},[832],{"type":27,"tag":784,"props":833,"children":836},{"alt":834,"src":835},"grid heavy","..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2-grid-heavy.png",[],{"type":27,"tag":35,"props":838,"children":839},{},[840],{"type":27,"tag":784,"props":841,"children":843},{"alt":407,"src":842},"..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2-highlighted.png",[],{"type":27,"tag":35,"props":845,"children":846},{},[847],{"type":27,"tag":784,"props":848,"children":850},{"alt":457,"src":849},"..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2-ignored.png",[],{"type":27,"tag":35,"props":852,"children":853},{},[854],{"type":27,"tag":784,"props":855,"children":857},{"alt":432,"src":856},"..\u002F..\u002Fdocs\u002Fimages\u002Fcycle-history\u002Fc2-warning.png",[],{"type":27,"tag":859,"props":860,"children":861},"style",{},[862],{"type":33,"value":66},1794599461149]