From 16c7ccac8a8b6cafc974a1d6b04eeaea5c81641a Mon Sep 17 00:00:00 2001 From: Aner Zakobar Date: Fri, 19 Jun 2026 18:09:39 +0300 Subject: [PATCH] backup: 2026-06-19 18:09 --- impl.org | 3 +- implpaper-beyond-rebalancing.org | 47 +++++++++++++++ implpaper-tabpfn.org | 37 ++++++++++++ implresearch.org | 73 ++++++++++++++++++++++ thesis.org | 49 +++++++++++++++ trmn.org | 20 ++++--- trmnassets.org | 100 ++++++++++++++++++++++++------- 7 files changed, 299 insertions(+), 30 deletions(-) create mode 100644 implpaper-beyond-rebalancing.org create mode 100644 implpaper-tabpfn.org create mode 100644 implresearch.org create mode 100644 thesis.org diff --git a/impl.org b/impl.org index 38b1391..28f7ab6 100644 --- a/impl.org +++ b/impl.org @@ -1,6 +1,6 @@ * impl -ROLL (Ranking via Optimized Label Learning) — PyTorch research project implementing custom loss functions for binary classification using kernel density estimation (KDE) to optimize TPR at target FPR thresholds. Targets imbalanced classification problems. +ROLL (Rate Optimized Likelyhood-based Loss) — PyTorch research project implementing custom loss functions for binary classification using kernel density estimation (KDE) to optimize TPR at target FPR thresholds. Targets imbalanced classification problems. ** Architecture @@ -42,3 +42,4 @@ ROLL (Ranking via Optimized Label Learning) — PyTorch research project impleme - [[id:001430d5-e1e7-4e72-baf6-17399bfd6447][impl/loss-functions]] — Loss variants, KDE internals, gradient computation - [[id:a53cbe84-cd8d-45c2-a8cf-34ab520a3ea5][impl/experiments]] — Experiment structure, training flow, metrics, output layout - [[id:b8a9886a-d349-43e5-a745-817a148c1fd8][impl/datasets]] — Dataset catalog, KEEL list, eval metrics +- [[id:151d5686-6f40-4158-a59a-b0be94cdc969][impl/research]] — Literature survey: competing methods, dataset gaps, key papers diff --git a/implpaper-beyond-rebalancing.org b/implpaper-beyond-rebalancing.org new file mode 100644 index 0000000..a100cbd --- /dev/null +++ b/implpaper-beyond-rebalancing.org @@ -0,0 +1,47 @@ +* impl/paper-beyond-rebalancing + +[[id:151d5686-6f40-4158-a59a-b0be94cdc969][impl/research]] + +*Beyond Rebalancing: Benchmarking Binary Classifiers Under Class Imbalance Without Rebalancing Techniques* +2024 — arXiv:2509.07605 + +** Problem + +The imbalanced learning literature almost exclusively evaluates methods *with* rebalancing (SMOTE, oversampling, etc.). This paper asks: which classifiers are intrinsically robust to class imbalance, with no rebalancing at all? + +** Setup + +- 19 real-world UCI/Kaggle datasets (IR 0.0015–0.54) + 5 synthetic datasets +- Synthetic decision boundaries of increasing complexity: linear → moderate non-linear → non-linear+redundancy → Gaussian quantiles → XOR (hardest) +- Minority class progressively reduced to 100%, 50%, 25%, 10%, 5%, 1%, plus one-shot/few-shot (k=1,3,5) +- 12 classifiers; 2×5-fold stratified CV + +** Classifiers Tested + +Traditional: Decision Tree, k-NN, SVM +Ensemble: Random Forest, XGBoost, LightGBM, CatBoost, BaggingRF, RUSBoost +Advanced: [[id:bf0fc08a-e806-48df-b188-7a2c4c41c693][impl/paper-tabpfn]] +One-class: OCSVM, Isolation Forest, LOF + +** Metrics + +AUC-ROC, AUC-PR, F1, G-mean, Accuracy, Precision, Recall + +** Key Findings + +1. *TabPFN wins overall* — best performer at all imbalance levels including extreme; only method that holds up one-shot/few-shot +2. *Ensembles second* — CatBoost, XGBoost, LightGBM degrade moderately; RF degrades faster +3. *Traditional classifiers collapse* — DT and k-NN fail sharply below 25% minority +4. *Decision boundary complexity is a major factor* — on linear data, most classifiers survive extreme imbalance; on XOR, nearly all collapse +5. Practical advice: use [[id:bf0fc08a-e806-48df-b188-7a2c4c41c693][impl/paper-tabpfn]] or CatBoost/SVM when rebalancing is not feasible + +** Datasets Used (real-world) + +Breast Cancer, Pen Local/Global, Letter, Annthyroid, Satellite, Glass, Segment, Pima, Yeast4/5/6, Abalone/Abalone9-18, Ecoli4, PC1/CM1/KC1/KC2 — all UCI + +** Relevance to ROLL + +- Directly in ROLL's territory: binary tabular classification under imbalance, AUC/G-mean metrics +- Strong candidate as a baseline paper to cite +- Does *not* use any custom loss or ROC-optimization — ROLL's TPR-at-FPR objective is orthogonal and potentially more practically useful +- Dataset list is a good target for ROLL coverage: Annthyroid, Abalone9-18, Satellite, Yeast4/5/6 are missing from ROLL (see [[id:151d5686-6f40-4158-a59a-b0be94cdc969][impl/research]] gap table) diff --git a/implpaper-tabpfn.org b/implpaper-tabpfn.org new file mode 100644 index 0000000..72b8078 --- /dev/null +++ b/implpaper-tabpfn.org @@ -0,0 +1,37 @@ +* impl/paper-tabpfn + +[[id:151d5686-6f40-4158-a59a-b0be94cdc969][impl/research]] + +*TabPFN: A Transformer That Solves Small Tabular Classification in a Second* +Hollmann et al. — ICLR 2023 — arXiv:2207.01848 + +** Problem + +Small tabular datasets demand expensive hyperparameter search and still often lose to boosted trees. TabPFN asks: can you eliminate tuning entirely while matching AutoML? + +** Core Method + +A Transformer pre-trained *offline* on millions of synthetic datasets sampled from structural causal models. At inference, the full training set is passed as context — no gradient updates. The model receives =(X_train, y_train, X_test)= as one sequence and outputs predictions in a single forward pass (in-context learning). + +** Evaluation + +- 18 OpenML-CC18 datasets + 67 small numerical OpenML datasets +- Up to 1,000 training points, 100 features, 10 classes +- Compared against AutoML systems (Auto-sklearn), XGBoost, random forests + +** Key Results + +- Outperforms boosted trees on small datasets; matches top AutoML +- 230× faster than AutoML baselines; 5,700× with GPU +- No hyperparameter tuning required + +** Limitations + +- v1: numerical features only, no missing values, max ~1,000 training samples +- TabPFN v2 (2025, arXiv:2502.17361) lifts most constraints — handles larger datasets, mixed types, missing values + +** Relevance to ROLL + +- [[id:8f59b736-04ea-4d11-9195-30d125a127f8][impl/paper-beyond-rebalancing]] identifies TabPFN as the best-performing classifier on imbalanced tabular data without rebalancing — it is the current bar to beat +- ROLL's niche (optimizing TPR at a specific FPR threshold) is orthogonal: TabPFN uses no custom loss or ROC objective +- If evaluating on small KEEL datasets (≤1,000 samples), TabPFN is the strongest baseline to include diff --git a/implresearch.org b/implresearch.org new file mode 100644 index 0000000..4454f42 --- /dev/null +++ b/implresearch.org @@ -0,0 +1,73 @@ +* impl/research + +Survey of academic literature on class imbalance in deep learning, relevant to ROLL's thesis positioning. + +** Key Papers + +| Paper | Venue | Node | +|-------|-------|------| +| CLIMB (arXiv:2505.17451) | NeurIPS 2025 | — | +| [[id:8f59b736-04ea-4d11-9195-30d125a127f8][impl/paper-beyond-rebalancing]] | 2024 | detailed node | +| Simplifying NN Training Under Class Imbalance (arXiv:2312.02517) | 2023 | — | +| Investigating Group DRO (arXiv:2303.02505) | 2023 | — | +| [[id:bf0fc08a-e806-48df-b188-7a2c4c41c693][impl/paper-tabpfn]] | ICLR 2023 | detailed node | +| Survey on Imbalanced Learning (Springer 2024) | Springer AI Review | — | +| Rethinking Class Imbalance (arXiv:2305.03900) | 2023 | — | + +** Competing Strategies + +Methods the literature benchmarks against (relevant as ROLL baselines): + +- *Resampling*: SMOTE, ADASYN, CSMOUTE, BorderlineSMOTE, ROSE +- *Cost-sensitive*: class weighting, focal loss, asymmetric loss +- *Ensemble*: BalancedBagging, EasyEnsemble, RUSBoost, BalancedRandomForest +- *Threshold moving*: post-hoc calibration on decision threshold +- *DL-specific*: LDAM-DRW, M2m, MiSLAS, BBN (mostly image long-tail) +- *Tabular DL baselines*: XGBoost, LightGBM, CatBoost, MLP, ResNet, FT-Transformer, [[id:bf0fc08a-e806-48df-b188-7a2c4c41c693][impl/paper-tabpfn]] +- *CLIMB finding*: ensembles dominate; naive rebalancing (SMOTE alone) often underperforms + +Metrics used: AUC-ROC, G-Mean, F1, Precision/Recall. AUC and G-Mean are the standard for imbalanced eval. +ROLL's TPR-at-FPR framing is non-standard but more practically useful — position this as an advantage. + +** Dataset Coverage vs Literature + +*** Well Covered by ROLL +- All glass variants (glass0–6) — standard KEEL +- Yeast3, ecoli-0-1_vs_5, wisconsin, cleveland, pima, haberman, iris0, vowel0, vehicle2, page-blocks, new-thyroid1, led7digit +- Adult, Forest Cover, Bank Marketing (medium tabular) +- Credit Card Fraud (~285K, IR 577:1) — common in fraud literature + +*** Gaps vs Literature (datasets in papers ROLL doesn't have) + +| Dataset | IR | Samples | Appears In | +|---------|----|---------|------------| +| Abalone9-18 | ~130 | 731 | [[id:8f59b736-04ea-4d11-9195-30d125a127f8][Beyond Rebalancing]], CLIMB | +| Annthyroid | 7.2 | 6916 | [[id:8f59b736-04ea-4d11-9195-30d125a127f8][Beyond Rebalancing]], many UCI surveys | +| Satellite | 22 | 6435 | [[id:8f59b736-04ea-4d11-9195-30d125a127f8][Beyond Rebalancing]] | +| Segment | 6 | 2310 | [[id:8f59b736-04ea-4d11-9195-30d125a127f8][Beyond Rebalancing]] | +| Yeast4/5/6 | 8–33 | ~1484 | [[id:8f59b736-04ea-4d11-9195-30d125a127f8][Beyond Rebalancing]], CLIMB | +| Ecoli4 | 15.8 | 336 | [[id:8f59b736-04ea-4d11-9195-30d125a127f8][Beyond Rebalancing]] | +| KC1/KC2/PC1/CM1 (software) | 5–13 | 415–1783 | [[id:8f59b736-04ea-4d11-9195-30d125a127f8][Beyond Rebalancing]] | +| Pen-local/Pen-global | 9–671 | 7291 | [[id:8f59b736-04ea-4d11-9195-30d125a127f8][Beyond Rebalancing]] | + +*** Non-Standard or Unusual in ROLL +- *Higgs*: ROLL samples 500K balanced (50/50) — not a standard imbalanced benchmark; physics ML context +- *Home Credit*: Kaggle competition dataset; rare in academic imbalance papers +- *CIFAR-10 binary* (class 1 vs rest, IR ~9): DL imbalance papers use long-tail formulation instead — results not directly comparable to LDAM/MiSLAS tables + +** Recommendations for Baseline Strengthening + +Priority additions (available in KEEL, low effort): +1. Yeast4, Yeast5, Yeast6 — stress-test high IR range +2. Annthyroid — one of the most cited UCI imbalanced datasets +3. Abalone9-18 — extreme IR (130:1), covers the hard regime +4. Ecoli4 — rounds out ecoli coverage at IR 15.8 + +Lower priority (useful if sweeping many baselines): +5. Satellite, Segment, Pen-local — common in full KEEL sweeps +6. KC1/PC1 — software metrics datasets; different domain from biology/finance + +** Paper Subnodes + +- [[id:bf0fc08a-e806-48df-b188-7a2c4c41c693][impl/paper-tabpfn]] — TabPFN: in-context learning for small tabular classification (ICLR 2023) +- [[id:8f59b736-04ea-4d11-9195-30d125a127f8][impl/paper-beyond-rebalancing]] — benchmark of 12 classifiers under imbalance, no rebalancing (2024) diff --git a/thesis.org b/thesis.org new file mode 100644 index 0000000..6143663 --- /dev/null +++ b/thesis.org @@ -0,0 +1,49 @@ +:PROPERTIES: +:ID: 6294e2be-6189-4473-b363-a1dd9a75ff9b +:END: + +#+title: thesis +#+filetags: :project: :knowledge: + +* thesis + +BGU MSc thesis on the ROLL method (Ranking via Optimized Label Learning). See [[id:d23011c5-d925-4f14-b05a-0a1f4bdbe860][impl]] for the implementation project this thesis documents. + +** Architecture + +- =main.tex= — root document; defines all title/author/supervisor commands, includes all chapters +- =Main_pages/= — cover_page, title_page, abstract, acknowledgements, abstract_heb, cover_heb +- =content//= — one folder per chapter with its own .tex file +- =content/images/= — shared image path (set via =\graphicspath=) +- =bibliography/thesis.bib= — references +- =bibliography/unsrtnat_adjusted_for_bgu_thesis.bst= — custom BGU bibliography style (do not edit) + +** Conventions + +- Thesis metadata (title, author, supervisor, month, year) defined as commands at top of =main.tex= +- Hebrew title/author/supervisor have =he= suffix commands (=\thesistitlehe=, etc.) +- Both English and Hebrew ToC, abstract, and cover pages are required by BGU +- Chapters added via =\input{content//}= with a matching =\addtocontents{tocheb}= line for the Hebrew ToC +- Build engine: pdflatex (uses =\usepackage[utf8x]{inputenc}=, not xelatex) + +** Gotchas + +- Template uses =utf8x= inputenc, which requires the =ucs= nix/texlive package +- Hebrew rendering via =babel-hebrew= (pdflatex approach, not fontspec/xelatex) +- Example images in =content/related_work/images/= are from the template — safe to delete +- =flake.nix= uses =rec= on the derivation so =buildInputs= is in scope for PATH export + +** Key Files + +- =flake.nix= — Nix build; =nix build= produces =result/main.pdf=; =nix develop= for dev shell +- =flake.lock= — pinned to nixpkgs-unstable as of 2026-06-16 +- =main.tex= — fill in =\thesistitle=, =\thesisauthorname=, =\thesissupervisername=, =\thesismonth=, =\thesisyear= + +** Subnodes + +(none yet) +* todo + +** TODO Basic structure - take it into account +** TODO Import and make sense of all references +** TODO Continue to auto-summarize references continuously diff --git a/trmn.org b/trmn.org index 48ce090..27e934d 100644 --- a/trmn.org +++ b/trmn.org @@ -6,25 +6,27 @@ #+filetags: :project: :knowledge: ** Architecture -Static site (no backend). ~index.html~ + ~life.js~ + ~schedule.js~ as ES modules. Three.js + onnxruntime-web from CDN. +Static site (no backend). ~index.html~ + ~life.js~ + ~schedule.js~ + ~locations.js~ as ES modules. Three.js + onnxruntime-web from CDN. Served by Caddy via ~nix run~ on port 8080. Built by ~nix build~ (includes model weights in ~$out/model/~). Domains: -- *Life generation*: ~life.js~ — deterministic 36,500-day procedural simulation → [[id:9465af82-4383-466c-bf09-5be19c328f0b][trmn/life]] +- *Life generation*: ~life.js~ — deterministic 36,500-day procedural simulation → [[id:9465af82-4383-406c-bf09-5be19c328f0b][trmn/life]] - *NPC people*: family tree + tracked friends/children, each with deterministic PersonRecord → [[id:423cac95-a80d-4db6-8bef-14297fb38437][trmn/people]] - *Daily schedule*: ~schedule.js~ — 96-slot day, 68 scenes, deterministic from (masterSeed, currentDay) → [[id:ff8aa6b7-61ff-444c-9301-c0b666b0b573][trmn/schedule]] - *Rendering*: Three.js low-poly 3D scenes, flat shading, cinematic 2.39:1 viewport - *LLM dialogue*: TinyStories-8M ONNX INT8 bundled in ~/model/TinyStories-8M/~ → [[id:4b44cf43-6106-4498-81a3-b23ebb25dabf][trmn/llm]] -- *Assets*: SVG face sprites + GLB objects → [[id:4d5e6bc8-32eb-469f-a69f-84b14458c55b][trmn/assets]] +- *Assets*: SVG face sprites + GLB objects + Blender location scenes → [[id:4d5e6bc8-32eb-469f-a69f-84b14458c55b][trmn/assets]] ~window.__life~ exposes ~{traits, buf, eventLog, people, today, currentDay, masterSeed, schedule}~. +~window.__sceneLoader~ exposes ~{ loadAndShow(locationId, props) }~ for the debug panel. ** Conventions - Determinism: ALL randomness seeded from absolute time, never ~Math.random()~; use ~makeRng(masterSeed, day)~ - Low-poly aesthetic: ~MeshLambertMaterial~ with ~flatShading: true~, BoxGeometry for characters - Cinematic viewport: ~aspect-ratio: 2.39/1~, FOV 26°, vignette via CSS ~::after~ - Scene background via CSS gradient on ~#stage~ div; canvas is ~alpha: true~ -- Static assets: copy to ~$out/assets/~ in flake installPhase; generated assets built via Node.js in buildPhase +- Static assets: copy to ~$out/assets/~ in flake installPhase; generated assets built via Node.js/Blender in buildPhase +- ~.blend~ files are source of truth for location scenes; GLBs are build artifacts never committed ** Gotchas - ~header Content-Type text/html~ in Caddyfile is wrong for multi-asset setups — omit it @@ -36,16 +38,18 @@ Domains: - All ONNX build/inference gotchas → [[id:4b44cf43-6106-4498-81a3-b23ebb25dabf][trmn/llm]] ** Key Files -- ~index.html~ — Three.js scene + LLM inference + life simulation bootstrap (three inline module scripts) +- ~index.html~ — 4 inline module scripts: life sim bootstrap, Three.js scene (+ pack loader + debug exposure), debug panel UI, LLM inference - ~life.js~ — full life simulation: PRNG, 31 events, 36,501-day loop, NPC people system - ~schedule.js~ — daily schedule: 68-scene catalog, 10 life stages, forced-event overrides +- ~locations.js~ — ~generateLocationProps(locationId, masterSeed, playerState, eventLog?)~; wall/floor palettes + conditional mesh sets - ~schedule-debug.mjs~ — CLI debug tool; ~nix run .#schedule -- [flags]~ - ~stats.mjs~ — aggregate stats across 1000 lives; ~nix run .#stats~ -- ~flake.nix~ — build + Caddy server + ~tinyStoriesOnnx~ sub-derivation + ~stats~ + ~schedule~ apps +- ~flake.nix~ — build + Caddy server + ~tinyStoriesOnnx~ sub-derivation + ~stats~ + ~schedule~ apps; ~pkgs.blender~ in nativeBuildInputs +- ~ASSETS.md~ — authoring guide: location ID→file mapping, mesh naming conventions, Blender setup, build/test workflow ** Subnodes - [[id:4b44cf43-6106-4498-81a3-b23ebb25dabf][trmn/llm]] — ONNX build pipeline, in-browser inference, TinyStories-8M gotchas -- [[id:9465af82-4383-466c-bf09-5be19c328f0b][trmn/life]] — life simulation: PRNG, state schema, event catalog, packed buffer layout -- [[id:4d5e6bc8-32eb-469f-a69f-84b14458c55b][trmn/assets]] — SVG sprite pipeline, GLB generation, face compositing +- [[id:9465af82-4383-406c-bf09-5be19c328f0b][trmn/life]] — life simulation: PRNG, state schema, event catalog, packed buffer layout +- [[id:4d5e6bc8-32eb-469f-a69f-84b14458c55b][trmn/assets]] — location scene pipeline: Blender→GLB→scenes.pack, naming conventions, debug panel, PRNG offsets - [[id:423cac95-a80d-4db6-8bef-14297fb38437][trmn/people]] — NPC system: family tree, PersonRecord, PRNG isolation, post-apply hooks - [[id:ff8aa6b7-61ff-444c-9301-c0b666b0b573][trmn/schedule]] — daily schedule: slot layout, scene catalog, life stages, forced events, debug CLI diff --git a/trmnassets.org b/trmnassets.org index 640c40c..e4ae40f 100644 --- a/trmnassets.org +++ b/trmnassets.org @@ -5,40 +5,98 @@ #+title: trmn/assets #+filetags: :project: :knowledge: :assets: -:PROPERTIES: -:ID: trmn-assets -:END: - -#+title: trmn/assets -#+filetags: :project: :knowledge: :assets: - -[[id:6293baa2-c8a8-4c49-9284-1fa2eed75032][trmn]] — asset pipeline: SVG sprites + GLB objects +[[id:6293baa2-c8a8-4c49-9284-1fa2eed75032][trmn]] — asset pipeline: SVG sprites + GLB objects + location scenes ** Architecture -Two asset types, both served from ~$out/assets/~ by Caddy: +Three asset types, all served from ~$out/assets/~ by Caddy: - *Sprites*: SVG files in ~assets/sprites/{eyes,nose,mouth}/~, static/committed, no build step - *3D objects*: GLB files in ~assets/objects/~, generated during ~nix build~ by Node.js scripts in ~scripts/~ +- *Location scenes*: ~.blend~ files in ~assets/scenes/**~ are the source of truth; Blender exports GLBs at build time, then packed into ~assets/scenes/scenes.pack~ (single binary, one browser fetch) Face compositing at runtime: load SVG parts → draw onto ~OffscreenCanvas(128,128)~ → ~THREE.CanvasTexture~. Applied to the +z front face (index 4) of the head ~BoxGeometry~ via a material array. +** Location Scene Pipeline +~.blend~ files are the source of truth (edit in Blender, commit ~.blend~, GLBs are build artifacts): +1. ~flake.nix~ buildPhase: ~blender --background file.blend --python scripts/export-glb.py -- out.glb~ for each ~.blend~ in ~assets/scenes/**~ +2. ~scripts/pack-scenes.mjs glb_tmp assets/scenes/scenes.pack~: validates all SCENES location IDs have a GLB (warn by default, ~STRICT_LOCATIONS=1~ to error), concatenates into ~scenes.pack~ +3. Pack format: ~[4-byte LE uint32: manifest len][JSON manifest][...GLB bytes]~ +4. Runtime: ~loadPack()~ fetches once, ~loadLocationScene(id)~ slices + parses per scene, cached + +34 unique location IDs (e.g. ~home/bedroom~, ~office~, ~school/classroom~). Directory mirrors IDs: ~assets/scenes/home/bedroom.blend~ → ID ~home/bedroom~. Full mapping in ~ASSETS.md~. + +** Blender Naming Conventions (procedural overrides) +- ~IF_~ meshes: toggled visible/hidden at runtime by ~applyLocationProps()~ + Examples: ~IF_CRIB~ (age<3), ~IF_ADULT_BED~ (age≥13), ~IF_TV_LARGE~ (wealthLevel>70) +- ~WALLS~, ~FLOOR~: material color replaced at runtime with deterministic palette color +- All other mesh names: always visible, untouched +Full ~IF_*~ table and authoring guide in ~ASSETS.md~. + +** Blender Scene Setup +- Character is ~2 units tall; typical interior: 5–8 units wide, 3 units tall +- Camera: pos ~(0.5, 1.6, 6.5)~, looks at ~(0, 1.0, 0)~, FOV 26°, aspect 2.39:1 +- No lights in .blend files — runtime adds ambient + two directional lights +- Materials: Diffuse BSDF (flat color); Principled BSDF works but is overkill under Lambert +- ~export_apply=True~ in export script — modifiers applied; no armatures/animations +- Poly budget: ~500 triangles/scene; outdoor scenes skip WALLS/FLOOR (no runtime error) +- Run ~nix develop~ to get a shell with ~blender~ on PATH for authoring + +** Runtime API (~index.html~ Three.js block) +- ~loadPack()~: called once at init; gracefully no-ops if pack not built yet +- ~loadLocationScene(locationId)~: returns ~THREE.Group~ (cloned from cache), or ~null~ if not in pack +- ~applyLocationProps(threeScene, props)~: traverses scene, applies ~IF_*~ visibility + WALLS/FLOOR colors +- ~generateLocationProps(locationId, masterSeed, playerState, eventLog?)~ from ~locations.js~ +- ~window.__sceneLoader.loadAndShow(locationId, props)~: removes previous loc scene, loads + applies new one + +** Debug Panel (~▸ scene debug~ in browser) +Collapsible ~
~ panel below the chat box. Controls: +- Location dropdown (all 34 IDs, populated from ~SCENES~ at runtime) +- Sliders: age, wealth, children, job tier, moves (home move count) +- *sync from today*: pulls actual simulated state from ~window.__life~ +- *load scene*: calls ~window.__sceneLoader.loadAndShow()~; shows ~[not in pack]~ if .blend missing +- Live props display: wall/floor color swatches + hex, visible ~IF_*~ mesh names +Props update on every slider move even without a loaded scene. + +** locations.js +ES module, imported by Three.js block and debug module. Exports ~generateLocationProps~. +- Home: seeded from ~makeRng(masterSeed, 200000 + moveIndex)~ where moveIndex = count of ~move_city~ events ≤ currentDay → new house each time player moves +- Office: offset 300000; School: 301000; University/dorm: 302000; others: hash into 303000–399999 +- ~playerState~ fields: ~{ age, wealthLevel, numChildren, jobTier, inCollege, retired, currentDay }~ + +** PRNG Offset Allocation (all streams) +| Range | Owner | +|---|---| +| -2 to -1 | Family layout + protagonist traits | +| 0 – 36,500 | Life simulation daily | +| 50,000+ | Schedule (per-day, offset 50000) | +| 200,000 + moveIndex | Home appearance (per house) | +| 300,000 | Workplace | +| 301,000 | School | +| 302,000 | University / dorm | +| 303,000–399,999 | Other locations (hashed from ID) | + ** Conventions -- All sprite SVGs are 128×128; each draws its feature in the region it occupies on the face canvas - (eyes ~y≈35–55~, nose ~y≈65–85~, mouth ~y≈90–110~) so all layers composite with ~drawImage(img, 0, 0, 128, 128)~ -- Face part selection seeded from ~window.__life.masterSeed~ via inline ~mulberry32~ in the Three.js script block -- ~window.__life~ exports ~masterSeed~ (added alongside traits/buf/eventLog/today/currentDay) -- GLB generators: pure Node.js stdlib only (no npm), accept output path as ~process.argv[2]~ -- Three.js importmap includes ~"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/"~ for GLTFLoader +- All sprite SVGs are 128×128; composite with ~drawImage(img, 0, 0, 128, 128)~ +- Face part selection seeded from ~window.__life.masterSeed~ via inline ~mulberry32~ in Three.js block +- GLB generators: pure Node.js stdlib only (no npm), accept output path as arg +- ~pkgs.blender~ in ~nativeBuildInputs~ (build) and ~devShells.buildInputs~ (~nix develop~ shell) ** Gotchas -- *Critical*: Nix flake ~src = ./.~ only includes git-tracked files (~git ls-files~). - New ~assets/~ and ~scripts/~ dirs must be ~git add~-ed before ~nix build~ or they are silently excluded. -- ~BoxGeometry~ material array face order: ~[+x, -x, +y, -y, +z, -z]~ → index 4 is the front face (camera-facing) -- GLB generator runs in Nix buildPhase and writes to the build dir; installPhase ~cp -r assets $out/assets~ picks up both committed sprites and the generated ~book.glb~ +- ~src = ./.~ only includes git-tracked files. Run ~git add assets/scenes/ scripts/export-glb.py scripts/pack-scenes.mjs locations.js~ before ~nix build~ or they are silently excluded. +- ~BoxGeometry~ material array face order: ~[+x, -x, +y, -y, +z, -z]~ → index 4 is front face +- GLB generator runs in Nix buildPhase and writes to build dir; ~cp -r assets $out/assets~ picks up generated files +- ~locations.js~ imports ~makeRng~ from ~./life.js~; served by Caddy alongside other JS modules +- Blender headless needs ~--background~ flag; no X11 required in stdenvNoCC sandbox ** Key Files - ~assets/sprites/eyes/eyes_{1,2}.svg~ — wide-open vs narrow/tired eyes - ~assets/sprites/nose/nose_{1,2}.svg~ — dot vs nostrils nose - ~assets/sprites/mouth/mouth_{1,2}.svg~ — smile vs neutral mouth -- ~assets/objects/book.glb~ — generated at build time (not committed); dark-red flat box 0.14×0.18×0.03 -- ~scripts/gen-book.mjs~ — pure Node.js GLB writer, no npm deps; ~node scripts/gen-book.mjs ~ +- ~assets/objects/book.glb~ — generated at build time; dark-red flat box 0.14×0.18×0.03 +- ~assets/scenes/~ — ~.blend~ source files, mirroring location ID hierarchy +- ~assets/scenes/scenes.pack~ — build artifact; binary pack of all location GLBs +- ~scripts/gen-book.mjs~ — pure Node.js GLB writer for book object +- ~scripts/export-glb.py~ — Blender Python: exports active scene to GLB +- ~scripts/pack-scenes.mjs~ — validates + concatenates GLBs into ~scenes.pack~ +- ~locations.js~ — ~generateLocationProps(locationId, masterSeed, playerState, eventLog?)~ +- ~ASSETS.md~ — full authoring guide: location→file map, IF_* table, Blender setup, workflow