Hmm… maybe it would be better to first figure out a way to experiment without losing your bearings?
:
Your follow-up changes how I would answer this.
After four weeks of wrestling with this, I would pause the six original questions for a moment and make the experiments themselves cheap to try, easy to compare, and easy to undo.
That seems more useful than adding another layer of architecture right now.
I also would not assume “renaming projects a hundred times” points to one particular underlying problem.
If you literally mean folders/projects turning into things like:
museum-final
museum-final2
museum-lighting-test
museum-lighting-test-fixed
museum-real-final
then yes, version control is designed to replace that kind of history-by-filename.
But if you mean something broader — an AI-assisted change keeps turning into a different project, or after enough edits you no longer know which world / .spz / collider / code state actually belongs together — Git alone will not solve that.
Because you are coming to this from graphic design and using AI coding assistants, I would not turn the answer into “first, become a developer.”
I would give the project a very small memory outside the chat.
The whole idea would be:
Keep one place called HOME, change one main idea at a time, and always know how to get back.
A checkpoint is a little like taking a photo before rearranging a room. You are still free to move everything around; the point is that “before” never becomes ambiguous.
If I were starting tomorrow morning
I would put five small guardrails around the project:
|
The small version |
| 1. HOME |
Pick one working room you understand and record the code + Marble/SPZ/collider/transform state that belongs to it. |
| 2. Visible history |
Make one untouched backup; if folder/project copies are multiplying, let Git history replace final-final2 naming. |
| 3. Project note |
Keep one tiny PROJECT_STATE.md: current question, what stays fixed, how you will check it, what happened, and what you meant to do next. |
| 4. One-room laboratory |
Test a new idea in one representative room first. The other ten scenes are the later “does this generalize?” test. |
| 5. AI workbench |
Let the chat explore, but keep HOME, decisions, tried ideas, and next action in the project rather than only in the conversation. |
That is the system in miniature.
If those five lines already make sense, I would start there and ignore the rest until something specific hurts.
The concrete version — including the tiny files/checklists I mean — is below.
The concrete HOME / Git / PROJECT_STATE / AI setup
1. Pick one room and call it HOME
Not the most beautiful room.
Not the final architecture.
Just the working room you understand best.
HOME means:
“If everything gets confusing, I can return here and I know what this state is supposed to do.”
For your project I would write down, at minimum:
HOME ROOM:
____________________
CODE CHECKPOINT:
____________________
MARBLE WORLD / VERSION:
____________________
SPZ:
____________________
COLLIDER:
____________________
PLACEMENT / TRANSFORM DATA:
____________________
THREE.JS / SPARK VERSION:
____________________
That is enough to establish a coordinate on the map.
And I would be slightly conservative about moving HOME.
A candidate becomes the new HOME only when:
the intended thing improved
+
the little regression checks still pass
+
you have recorded which asset/dependency state belongs to it
If it merely looks promising, keep it as a candidate for now.
That avoids a subtle version of getting lost where HOME itself moves every time an experiment looks interesting.
A project name is not quite enough here, because your visible room is really a bundle of independently changeable things.
2. If project copies are part of the problem, give the code a visible history
Before changing the workflow, I would make one untouched backup copy of the current working folder and then stop editing that copy. That is simply the emergency return point while you set up a better history.
After that, I would probably use GitHub Desktop if command-line Git is not something you want to learn right now.
It lets you make a visible checkpoint (“commit”) and later inspect the history of exactly what changed.
The Changes view is useful with AI coding in another way too: before accepting a checkpoint, scan the changed-file list. If you asked for a spotlight experiment and suddenly see the collider loader, camera system, package configuration, and placement code changing too, that is a good moment to ask why.
The repository can stay local on your computer; publishing it is optional, and GitHub Desktop can publish it privately later if you want (walkthrough).
Before the first commit, make sure API keys, tokens, passwords, .env files, etc. are not entering history; GitHub recommends excluding such files and not hard-coding secrets (guidance).
For now I would not start with:
- complicated branching strategies;
- rebasing;
- pull requests;
- CI pipelines;
- issue-tracker rituals.
You can learn those if you actually need them.
The useful minimal rule is much smaller:
Make a checkpoint whenever you reach a state you might want to return to.
Names such as:
gallery-03 baseline works
painting placement works
before spotlight experiment
spotlight prototype works
before room-switch cleanup
tell you much more than v17 or final-final2.
One caveat: large .spz / .glb histories do not necessarily belong directly in ordinary Git. Initially I would simply record which exact asset files belong to the code checkpoint. If large binary history later becomes a real problem, Git LFS is one possible next step.
3. Keep one tiny PROJECT_STATE.md
This is the part I would consider more important than Git.
Something like:
HOME
gallery-03 / checkpoint: __________
CURRENT QUESTION
What am I trying to learn?
___________________________________
ONE MAIN CHANGE
___________________________________
KEEP FIXED
What should NOT be redesigned in this experiment?
___________________________________
HOW I WILL CHECK
___________________________________
RESULT / LEARNED
___________________________________
NEXT INTENDED ACTION
___________________________________
IF THIS FAILS, RETURN TO
___________________________________
PARKED IDEAS
___________________________________
Before you stop for the day, leave the next intended action there.
It is the project equivalent of leaving yourself a note on the desk saying, “I stopped here; this is what I meant to do next.”
There is even research on interrupted programming work showing that developers use contextual cues and notes to reconstruct where they were when they resume: Evaluating Cues for Resuming Interrupted Programming Tasks.
And I would keep rejected ideas very briefly too:
TRIED:
RESULT:
WHY I STOPPED:
RETRY ONLY IF:
That prevents a fresh AI conversation from rediscovering last week’s dead end and presenting it as a new idea.
I would also save maybe three fixed screenshots of HOME:
G1: entrance / whole-room view
G2: one painting at interaction distance
G3: seated/fixed viewing position
When an experiment changes something visual, capture the same three views again.
You do not need automation: HOME/ and candidate/ screenshot folders already give you a visual before/after. If it later becomes worthwhile, Playwright can maintain visual baselines; its docs also warn that rendering varies by environment, so treat them as controlled comparisons, not absolute truth.
4. Make one room the laboratory
You have 11 scenes. I would not use all 11 to answer the first version of a question.
Think:
one room = laboratory
the other ten = “does this generalize?” later
You would not test a new paint mixture on every wall in a museum at once.
For example:
- Q4 relighting → one painting, one wall, one fixed camera;
- Q5 placement → one wall with windows/recesses/fixtures;
- Q6 spotlight → one painting, one Spark edit;
- Q2 consistency → two rooms, not eleven;
- Q3 outdoor degradation → one exterior;
- Q1 unwanted generation → one prompt / one candidate world.
This is probably the biggest change I would make to the way the six original questions are approached.
They do not have to become one giant architecture problem.
Each can be a small experiment that starts from HOME and either earns its way into the project or gets discarded.
5. Treat the AI chat as a workbench, not the archive
A workbench is where things get spread out, tested, taken apart and sometimes abandoned.
That is useful.
But I would not let the chat be the only place that knows:
- what HOME is;
- which asset bundle belongs to it;
- what has already been tried;
- what the AI is allowed to change;
- what the next intended action is.
Those belong somewhere durable in the project.
Before a substantial AI-generated edit I would give it a small contract like this:
GOAL
Prototype one local spotlight in gallery-03.
ALLOWED TO CHANGE
- spotlight prototype code
- one scene hook if necessary
KEEP FIXED
- Marble world / SPZ / collider
- coordinate conversion
- artwork placement
- camera interaction
- data schema
BEFORE EDITING
Tell me which files you intend to change and why.
AFTER EDITING
Tell me:
1. which files actually changed;
2. what behavior changed;
3. how I can compare this with HOME;
4. whether you discovered a reason a protected boundary must change.
Do not automatically continue into a second redesign.
If it discovers that the experiment really does require changing a protected part, that becomes a new explicit decision rather than an invisible side effect.
If those five habits already make the project feel more legible, I would stop there for a while. The rest is only for when a specific kind of confusion still survives.
Three questions that tell me it is time to stop branching
At any point, ask:
- Which exact state is HOME?
- What single question is the current experiment answering?
- What observation would make me keep this change rather than return HOME?
If one answer becomes “I’m not sure,” stop adding changes for a moment.
Not forever. Just long enough to recover the map.
This is not only a beginner phenomenon: studies of experienced developers describe disorientation when navigation context disappears, views are revisited repeatedly, or side tasks displace the original task (field study, follow-up).
So I would treat orientation as something the workflow should preserve.
The nice thing is that you do not need to know why you became lost before you recover.
Google’s incident-response guidance makes a similar separation: restoring/mitigating toward a known-good state and understanding the complete root cause can be different jobs (Incident Response).
Then I would turn the six original questions into six small experiments
Give each one its own small card rather than letting one AI conversation redesign the whole museum around all six.
The card can use the same five lines every time:
QUESTION:
KEEP FIXED:
CHANGE:
KEEP IT IF:
GO HOME IF:
That last line matters. A stop condition prevents “one more tweak” from quietly turning a small experiment back into a project rewrite.
| Original question |
Smallest experiment I would run |
| Q1 — unwanted generated content |
One generation requirement + explicit forbidden-content checklist. Compare a small number of prompt/reference/edit strategies; accept/reject the result rather than endlessly modifying the whole pipeline. |
| Q2 — cross-scene consistency |
Two representative rooms. Compare one stronger shared-state strategy — e.g. shared reference/geometry, Marble Expand, or explicit Compose alignment — against independent generation. |
| Q3 — exterior degradation |
One bad exterior. Check where the problem first appears: pano → Marble world → exported SPZ/mesh → Spark. |
| Q4 — painting looks like a decal |
One painting. First verify Three.js color handling; then compare your current grading against one local environment-map approach. |
| Q5 — automatic hanging |
One difficult wall. Validate the existing three-height test against a small set of manually judged “usable / unusable” positions before making the algorithm cleverer. |
| Q6 — selective spotlight |
One painting in HOME. Prototype one local splat edit and measure visual result + frame time before integrating it with the rest of the interaction system. |
That changes the mental model from:
"I am rebuilding a complicated 11-scene system"
to:
"I am answering one small question,
then deciding whether its answer belongs in HOME."
And every experiment only needs one of three endings:
KEEP IT -> it worked + the small checks still pass -> it can become HOME
GO HOME -> it failed or answered the question negatively -> record that and return
PARK IT -> interesting but unclear -> save the idea without building on top of it
PARK IT is especially useful with AI: a plausible idea can be remembered without becoming code today.
If you want the current Marble/Spark shortcut for each experiment
For Q2, Marble now gives you several different ways to share more state than a seed:
- Chisel lets you block walls/doorways or import GLB/FBX geometry, so the experiment can hold structure fixed while Marble supplies detail.
- Expand grows from an existing world and preserves earlier versions if the expansion is bad.
- Compose explicitly lets you join separate worlds by positioning, rotating and scaling them, then check floor levels, lighting and transitions.
Those answer different consistency hypotheses. I would test one, not “adopt Marble Studio.”
For Q4, there is now a pleasantly concrete Spark experiment: current SparkRenderer exposes renderEnvMap({ scene, worldCenter }). It updates/sorts the splats around a chosen point, renders six cube faces, prefilters them with Three.js PMREM, and returns a texture that can go directly on MeshStandardMaterial.envMap.
That is much cheaper to test than jumping directly into inverse rendering. I would call it an appearance-matching probe, not recovered physical illumination.
For Q6, current Spark SplatEdit explicitly describes MULTIPLY/ADD_RGBA as simple-lighting effects and INFINITE_CONE as a spotlight-like region. That makes:
one room
one painting
one cone
one intensity
an unusually clean first experiment.
I would benchmark it on the actual target machine, though. Spark’s own performance guide notes that even roughly 500k splats concentrated in a small screen area can bottleneck transparent blending despite larger overall desktop splat budgets.
For Q5, I would not throw away your existing wall detector just because it is heuristic. If the three-height coplanarity test is already separating walls from windows/recesses reliably, validate it first. Add normals/full-artwork clearance only if the mistakes you observe justify it.
The larger architectural win may be to turn accepted wall regions into a stable wall-local 2D layer:
generated collider
↓ preprocess once
wall_id + plane + usable intervals
↓
monthly artwork IDs / sizes
Then the monthly exhibition data no longer has to “understand” noisy generated geometry every time.
If you no longer know which version is HOME
Do not start by diagnosing the root cause.
Freeze first
Do not delete the current state. Save/checkpoint it.
Find the last state you can describe in plain language
For example:
“This room loads, I can walk, collision works, artwork placement works, and I know which SPZ/collider it uses.”
It does not need to be beautiful.
It needs to be reproducible and understandable.
If no such state exists, deliberately build the smallest one:
one room
one known SPZ
one matching collider
one camera path
one painting
no new experiment
Then rebuild one question
Not:
“fix the museum”
but:
“Does this specific spotlight approach work in one room?”
Only branch again after HOME exists.
A failed experiment is still useful if you know where it began, what it taught you, and where to return.
If folders/projects keep multiplying
If final, final2, new-final, etc. is literally the problem, this is the most direct route: let version history carry the history instead of filenames.
I would begin with only one habit:
checkpoint a working state before a risky AI change.
Good checkpoint names describe what became true:
gallery-03 baseline works
before Spark spotlight test
spotlight works, placement unchanged
before collider regeneration
room switching cleanup works
You do not need a branch for every thought.
You do not need to understand rebasing.
You do not need to publish the repository publicly.
The job of the history is simply to answer:
“What did this state contain, and can I get back to it?”
For large generated assets, keep the asset identity in the project map even if the binaries themselves are stored elsewhere.
If the AI keeps turning one fix into a redesign
This is where I would tighten the change boundary, not write a more elaborate prompt.
Before it edits, make it state:
current question
files it plans to touch
behavior it plans to change
things it intends to keep fixed
Afterward, make it state:
files actually changed
behavior actually changed
new dependency / schema / architecture decisions introduced
how to compare against HOME
If it says:
“To solve this properly I should also refactor the scene manager, rewrite the placement system and change the coordinate abstraction…”
that is not automatically wrong.
But it is a new branch of the decision, not permission to silently do all three.
I also like a small PARKED_IDEAS section:
PARKED
- possible scene-manager refactor
- replace collider representation
- investigate another LoD strategy
The idea is saved, so you do not feel forced to implement it immediately.
That is especially useful with AI because an assistant is very good at generating another plausible next step.
Your project needs a way to say:
“interesting; not this experiment.”
For the occasional change that really alters the shape of the project, I would leave one tiny decision note:
DECISION:
WHY NOW:
ALTERNATIVE I DID NOT CHOOSE:
REVISIT IF:
That is the basic idea of an Architecture Decision Record: preserve why an important choice was made so a future you — or a fresh AI — does not “fix” it back into an old problem.
And if your coding assistant supports repository instructions, put stable rules there rather than repeating them in every chat. GitHub Copilot, for example, supports repository/path-specific instructions.
Keep that entry point short. OpenAI reports the same pattern in Harness Engineering: a short AGENTS.md serves as a map to deeper project knowledge, not one giant instruction manual.
If the 'same room' may not actually be the same room
This is the 3D-specific part I would keep even if you never adopt much formal software process.
For this project, a “room version” is really something like:
Marble world / generation
+
SPZ
+
collider mesh
+
coordinate/export convention
+
scene transforms
+
placement data
+
code checkpoint
+
Three.js / Spark / dependency versions
So I would keep a tiny scene manifest.
A spreadsheet is completely fine:
| scene |
Marble world/version |
SPZ |
collider |
code checkpoint |
transform note |
status |
| gallery-03 |
… |
g03.spz |
g03.glb |
home-03 |
… |
HOME |
| gallery-04 |
… |
g04.spz |
g04.glb |
home-03 |
… |
untested |
If an asset is regenerated, I would avoid silently overwriting the old file with the same name.
This is also one place where I would not trust a remembered coordinate rule.
World Labs’ current export specs and release notes show that coordinate/export behavior has changed and that export choice matters. The open-source SPZ format also has its own coordinate-system convention/metadata, and Spark’s loading guide shows explicit reorientation in some cases.
So instead of:
“Marble/SPZ always needs transform X”
I would record:
Marble export option:
SPZ convention / metadata:
collider convention:
loader conversion:
scene transform:
It is the luggage-tag idea: enough information to tell whether this really is the same bag.
Also remember that World Labs describes the collider mesh as coarse physics geometry rather than the visual representation. “The collider is correct” and “the splat is correct” are separate checks.
If a room works fresh, but breaks/slows after switching or reloading
Then I would hold the world/assets fixed and test runtime state separately.
A boring reproduction sequence is useful:
load HOME room
wait until splat is ready
record behavior / FPS / memory indicators
leave room
load another room
return HOME
record the same things
repeat
Do not regenerate Marble or rewrite placement during this test.
The question is only:
“Does something accumulate, survive, or initialize differently across transitions?”
Three.js resources often need explicit lifecycle handling; removing an object from a scene is not the same as disposing its geometry/material/resources. The official disposal guide also points to renderer.info as a useful inspection point.
Spark likewise has explicit loading/readiness and disposal state. Current SplatMesh exposes onLoad, initialized, isInitialized and dispose(), while SparkRenderer has its own dispose().
So I would distinguish:
not loaded yet
vs
loaded but wrong
vs
old state not cleaned up
before changing the scene architecture.
If yesterday's checkpoint changes after reinstalling/updating
Then freeze the dependency state before debugging the room.
I would record:
Node version
package.json
package-lock.json
Three.js version
Spark version
browser used for the baseline
npm’s package-lock.json records the resolved dependency tree and is intended to make later installs reproducible.
npm ci is useful for the question:
“Does this old checkpoint still reproduce from its lockfile?”
During a scene-debugging experiment, I would avoid upgrading Three.js, Spark, the build tool and the scene code simultaneously.
If you want to update dependencies, fine — but then the update is the experiment.
Same cake, same oven principle.
If you keep trying plausible fixes but are not learning anything
Then I would stop asking:
“What should I try next?”
and ask:
“What are the two or three possibilities I am currently unable to distinguish?”
Example:
OBSERVATION
painting looks too bright compared with the splat wall
POSSIBILITY A
Three.js color/material pipeline is mismatched
POSSIBILITY B
color pipeline is correct; baked room appearance simply needs local adaptation
CHEAP TEST
render a neutral reference through exactly the same Three.js pipeline
Or:
OBSERVATION
two rooms do not read as the same building
POSSIBILITY A
independent generation is re-imagining architecture
POSSIBILITY B
the rooms are acceptable, but scale/registration/transition makes them feel unrelated
CHEAP TEST
compare fixed views / dimensions before changing generation again
This is essentially the hypothesis → controlled test → observation loop in Google SRE’s troubleshooting chapter.
The experiment does not need to fix the museum.
It only needs to make you less uncertain than before.
I would keep the creative decisions flexible and make only the project state precise
I would not try to turn questions like these into fake metrics:
- does this room actually feel Renaissance?
- does the spotlight feel theatrical rather than artificial?
- does the transition feel architectural?
- does a normalized painting size look curatorially acceptable?
Those are design judgments.
What I would make precise is:
which room
which world
which SPZ
which collider
which code checkpoint
which experiment
which result
That gives you a nice middle ground:
creative judgment can remain subjective while the route to each candidate stays recoverable.
If you ask another person or AI for help, give them the map pin, not four weeks of footprints
A compact handoff is usually enough:
QUESTION:
HOME:
candidate:
expected:
actual:
shortest reproduction:
what changed:
what stayed fixed:
screenshot / golden view:
relevant error/log:
what I already tried:
That is the minimal reproducible example idea adapted to a visual/3D project — and a clean way to start a fresh AI conversation.
Instead of:
“Please understand this enormous chat and remember what happened three projects ago…”
you can say:
“Here is HOME. Here is the candidate. Here is the one thing that changed. Here is what I observed.”
Links I would keep around, but not try to learn all at once
For keeping your bearings
For this particular Marble / SPZ / Spark / Three.js stack
Treat these as a shelf, not a syllabus: open the one that matches the problem in front of you.
So, if I had to answer “how do I start?” in one checklist
If I were in front of the project tomorrow, I would do this:
1. choose one working room
2. call it HOME
3. make one visible code checkpoint
4. write down the exact SPZ/collider/world that belongs to it
5. create PROJECT_STATE.md
6. choose ONE of the six original questions
7. define the smallest experiment that answers it
8. tell the AI what it must not change
9. run the same small checks / fixed views
10. KEEP IT, GO HOME, or PARK IT
Then repeat.
If that already stops the project from turning into final-final-really-final-27, I would not add more process.
And if it does not help, that is still a useful result: now the problem is more specific. It is probably time to open only the relevant detour — asset identity, AI change scope, runtime lifecycle, dependency drift, or an experiment that is not separating the possibilities.
That is much easier to work with than “the whole project no longer fits.”