backup: 2026-06-19 18:09
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
+49
@@ -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/<chapter>/= — 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/<chapter>/<chapter>}= 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
|
||||
@@ -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
|
||||
|
||||
+79
-21
@@ -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_<NAME>~ 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 ~<details>~ 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 <outpath>~
|
||||
- ~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
|
||||
|
||||
Reference in New Issue
Block a user