space-game/public/levels/enemy-territory.json
Michael Mainguy 244a25fff5
All checks were successful
Build / build (push) Successful in 1m34s
Implement hybrid level storage system with JSON-based defaults and configurable orbit constraints
Major changes:
- Add LevelRegistry for managing default (JSON) and custom (localStorage) levels
- Default levels now load from /public/levels/*.json files
- Add 6 default level JSON files (rookie-training through final-challenge)
- Implement version-based automatic cache invalidation
- Add LevelVersionManager for tracking level updates
- Add LevelStatsManager for performance tracking (completion rate, best time, etc.)
- Add legacy migration tool for existing localStorage data
- Update level selector UI with stats display and version badges
- Add configurable orbit constraints per level (useOrbitConstraints flag)
- Hide copy button in level selector UI (TODO: re-enable later)
- Add extensive debug logging for velocity troubleshooting
- Add cloud sync infrastructure interfaces (future-ready)

Technical improvements:
- Hybrid storage: immutable defaults from JSON, editable custom levels in localStorage
- Automatic cache refresh when directory.json version changes
- Cache API for offline support
- Fresh start migration approach with export option
- Level loading now initializes before router starts

Physics configuration:
- Add useOrbitConstraints flag to LevelConfig
- Rookietraining.json uses constraints (velocities will create orbital motion)
- Debug logging added to verify velocity application

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 18:40:01 -06:00

1011 lines
22 KiB
JSON

{
"version": "1.0",
"difficulty": "commander",
"timestamp": "2025-11-11T23:44:24.811Z",
"metadata": {
"author": "System",
"description": "Navigate through hostile space with high-speed asteroids and limited resources.",
"estimatedTime": "10-15 minutes",
"type": "default"
},
"ship": {
"position": [
0,
1,
0
],
"rotation": [
0,
0,
0
],
"linearVelocity": [
0,
0,
0
],
"angularVelocity": [
0,
0,
0
]
},
"startBase": {
"position": [
0,
0,
0
],
"baseGlbPath": "base.glb"
},
"sun": {
"position": [
0,
0,
400
],
"diameter": 50,
"intensity": 1000000
},
"planets": [],
"asteroids": [
{
"id": "asteroid-0",
"position": [
-55.77595863866099,
-60.516937558451644,
-101.10676378079069
],
"scale": 6.78524105501735,
"linearVelocity": [
9.957817407488125,
10.982768322162109,
18.05083618398419
],
"angularVelocity": [
-0.5965819832055597,
0.49764293312500696,
-0.23489500768751137
]
},
{
"id": "asteroid-1",
"position": [
51.01366656736156,
61.89083382225282,
-140.23316787747007
],
"scale": 7.375114439254016,
"linearVelocity": [
-8.803899321799005,
-10.508493246288012,
24.20133220457591
],
"angularVelocity": [
0.808562143760696,
0.892530315002241,
0.3166286328627703
]
},
{
"id": "asteroid-2",
"position": [
-89.27497643869671,
-96.70426975205562,
75.94393244559606
],
"scale": 6.561114427119078,
"linearVelocity": [
14.389417639263389,
15.748058399847189,
-12.240708479806575
],
"angularVelocity": [
-0.6727262347775067,
-0.45885844690986977,
0.552666584138167
]
},
{
"id": "asteroid-3",
"position": [
-25.37856560403051,
-100.51083367976476,
-6.739363736000233
],
"scale": 4.9465969460962835,
"linearVelocity": [
8.87451897700385,
35.496876928280116,
2.3566584613658033
],
"angularVelocity": [
0.41251734660501693,
-0.8931037557961039,
0.4850034783280015
]
},
{
"id": "asteroid-4",
"position": [
-26.989345064641896,
-85.27489498304212,
-188.91293387811623
],
"scale": 6.124075184348532,
"linearVelocity": [
4.500266822056823,
14.385678738728325,
31.499786547353967
],
"angularVelocity": [
0.2273175647575063,
-0.558081045771968,
0.6888867594728239
]
},
{
"id": "asteroid-5",
"position": [
-115.02553443028832,
79.71278214944606,
-108.48885721755033
],
"scale": 7.105706173930612,
"linearVelocity": [
21.213862611510503,
-14.516795375552855,
20.008320094245736
],
"angularVelocity": [
0.24455593269979614,
0.5225958731494473,
-0.9505917169340652
]
},
{
"id": "asteroid-6",
"position": [
-58.73254228240268,
97.33604894977107,
44.80612177977446
],
"scale": 6.192900812956161,
"linearVelocity": [
13.77476533702421,
-22.59405801639833,
-10.508549250445865
],
"angularVelocity": [
-0.7251515649183213,
0.3639719415853704,
0.3068612022321786
]
},
{
"id": "asteroid-7",
"position": [
-70.14667472965473,
-65.94017376177376,
22.986547856821872
],
"scale": 3.4112336692142384,
"linearVelocity": [
24.747687153438573,
23.616436340536257,
-8.10963452352621
],
"angularVelocity": [
0.7613217987150223,
0.11150995152395415,
0.14568352473357216
]
},
{
"id": "asteroid-8",
"position": [
79.2290471781825,
-143.9244337160095,
-15.954683414183584
],
"scale": 6.46375274913997,
"linearVelocity": [
-10.55858200565614,
19.313579709881175,
2.1262256609508765
],
"angularVelocity": [
0.6522444033491315,
-0.03232919151178004,
0.4219260501045876
]
},
{
"id": "asteroid-9",
"position": [
116.13499636175685,
95.47973669791692,
220.8617737797589
],
"scale": 2.501874975790654,
"linearVelocity": [
-16.085623431031888,
-13.086197218723925,
-30.591117532431028
],
"angularVelocity": [
0.6031234836811801,
0.5684191890733206,
-0.9904258206536913
]
},
{
"id": "asteroid-10",
"position": [
63.57764356124894,
53.77881563585659,
-58.567256433949154
],
"scale": 2.23322286614361,
"linearVelocity": [
-13.633297129650531,
-11.317646194632621,
12.558892785374262
],
"angularVelocity": [
-0.4944078136639898,
-0.9584237700533875,
0.47027253530042534
]
},
{
"id": "asteroid-11",
"position": [
102.27037541868664,
15.560392453883118,
-81.51315729604673
],
"scale": 7.75860618723746,
"linearVelocity": [
-18.19446375780478,
-2.5903741109488996,
14.501640187938293
],
"angularVelocity": [
0.9605188929395894,
-0.6334777108349012,
0.525904915560369
]
},
{
"id": "asteroid-12",
"position": [
115.21102333931695,
-78.2543653246074,
46.9710092970659
],
"scale": 6.649739604058236,
"linearVelocity": [
-23.054955749256447,
15.859644611547127,
-9.399400417201324
],
"angularVelocity": [
-0.8894416579885833,
-0.275711818504079,
-0.20094485130940143
]
},
{
"id": "asteroid-13",
"position": [
85.45260567087442,
-171.56840934311765,
-43.995359799249194
],
"scale": 5.027088485841676,
"linearVelocity": [
-16.665751938392873,
33.65587602550644,
8.580379113056557
],
"angularVelocity": [
0.5791200871773885,
0.9948458194569811,
0.6752235620302218
]
},
{
"id": "asteroid-14",
"position": [
-201.6451256292486,
-116.83464574331083,
-45.56327068442538
],
"scale": 6.847256970480096,
"linearVelocity": [
32.40905988593899,
18.938767196162928,
7.32307693331418
],
"angularVelocity": [
0.4489158407801095,
-0.30785248430337786,
0.06966719871324889
]
},
{
"id": "asteroid-15",
"position": [
85.37928578884734,
-32.329837349443885,
17.588472801747493
],
"scale": 5.67030120172992,
"linearVelocity": [
-30.49724091488736,
11.905324223651178,
-6.282553050237677
],
"angularVelocity": [
0.43098798216538814,
0.6791524480822151,
-0.20345735159289857
]
},
{
"id": "asteroid-16",
"position": [
41.62347705955282,
26.826253110998344,
-130.2721310353636
],
"scale": 2.141873334996801,
"linearVelocity": [
-7.933668230199513,
-4.922628725098157,
24.830598986166386
],
"angularVelocity": [
0.33962081485859796,
-0.30979450103903305,
0.8301360843526173
]
},
{
"id": "asteroid-17",
"position": [
-141.98260412068652,
-199.72384481237484,
11.591066713457069
],
"scale": 3.3776179066595953,
"linearVelocity": [
16.48437146006362,
23.30430857548461,
-1.345738448074897
],
"angularVelocity": [
-0.5290118589487647,
0.32440659674099415,
-0.3326984041883576
]
},
{
"id": "asteroid-18",
"position": [
37.5577466655546,
-109.58099721777445,
52.26126229755586
],
"scale": 5.650170406789071,
"linearVelocity": [
-7.664970032722214,
22.56791488079716,
-10.665735965208647
],
"angularVelocity": [
-0.7569816537054126,
0.9991120604875028,
-0.6590140356101544
]
},
{
"id": "asteroid-19",
"position": [
-182.03520027071275,
4.919397511425062,
-62.68190578694546
],
"scale": 6.0476532751015535,
"linearVelocity": [
33.12760279196319,
-0.7132699815706369,
11.407141443331453
],
"angularVelocity": [
-0.4716081293253884,
-0.041093359645206995,
-0.15360347434194122
]
},
{
"id": "asteroid-20",
"position": [
-45.93737485154738,
70.62468789022887,
-38.38854626942504
],
"scale": 4.83109249387863,
"linearVelocity": [
13.341474419928998,
-20.220920230746255,
11.149087420143319
],
"angularVelocity": [
0.5085973514099549,
0.9174908198903449,
0.4323552877124266
]
},
{
"id": "asteroid-21",
"position": [
-101.01374941001455,
-7.891582023150901,
84.52275167436615
],
"scale": 6.494665864860442,
"linearVelocity": [
16.967425712184347,
1.4935319035553953,
-14.19740895076638
],
"angularVelocity": [
-0.39896802586636504,
-0.265442324858677,
-0.8527977464366554
]
},
{
"id": "asteroid-22",
"position": [
128.87031443740625,
33.53313840278379,
-99.86787765355972
],
"scale": 2.5863911862892928,
"linearVelocity": [
-21.735237593888876,
-5.487031640656312,
16.843693276249866
],
"angularVelocity": [
-0.6122643121320746,
-0.05713552881377337,
0.9023811170464904
]
},
{
"id": "asteroid-23",
"position": [
-62.55555474511086,
231.536066116945,
138.13143289771665
],
"scale": 2.6506038643628553,
"linearVelocity": [
6.852421096849546,
-25.253236255057306,
-15.131106242812898
],
"angularVelocity": [
0.47920660141212146,
0.9382700413655973,
0.6663190275659825
]
},
{
"id": "asteroid-24",
"position": [
84.02473043661874,
188.40365123130843,
33.46175822498513
],
"scale": 7.511520298147304,
"linearVelocity": [
-14.701639630115286,
-32.78964337587202,
-5.854737150092474
],
"angularVelocity": [
-0.8314227729505954,
-0.0915063059645953,
0.7822650726703664
]
},
{
"id": "asteroid-25",
"position": [
93.62899884304426,
30.64398267119048,
-27.13598292639072
],
"scale": 4.2809113321902394,
"linearVelocity": [
-32.387597811753444,
-10.254273784370728,
9.386721123867305
],
"angularVelocity": [
-0.28643370726918205,
0.3824954378342258,
-0.43187555381326925
]
},
{
"id": "asteroid-26",
"position": [
8.305881808224829,
148.22439744797802,
105.94547474365258
],
"scale": 7.742627574483438,
"linearVelocity": [
-1.6628439505666388,
-29.474438033751763,
-21.210365838933765
],
"angularVelocity": [
0.9547910262285431,
0.35016764314831983,
-0.4237510867880898
]
},
{
"id": "asteroid-27",
"position": [
157.09767645144422,
108.13840082559065,
42.0355485743682
],
"scale": 3.2424644031887904,
"linearVelocity": [
-25.967071630662144,
-17.709176809451968,
-6.948161968532809
],
"angularVelocity": [
0.7036903589388861,
-0.06330036051990673,
-0.17475872827856298
]
},
{
"id": "asteroid-28",
"position": [
43.91984051242634,
3.246196407818413,
-236.95247999695144
],
"scale": 5.288565113501959,
"linearVelocity": [
-4.802193030920653,
-0.24559899603125127,
25.908371588434598
],
"angularVelocity": [
0.33623325704835594,
0.8036587426025465,
0.22854371423897568
]
},
{
"id": "asteroid-29",
"position": [
-103.00319864544981,
-22.148739180345533,
-70.13018614417182
],
"scale": 3.9335775528761565,
"linearVelocity": [
28.654511179258094,
6.439759292448371,
19.509551444016196
],
"angularVelocity": [
-0.7856420204712635,
-0.46529446366424,
-0.8620752555779472
]
},
{
"id": "asteroid-30",
"position": [
63.25704678708654,
-186.0084908966402,
5.320347449668389
],
"scale": 4.72275715193363,
"linearVelocity": [
-11.036851265134036,
32.62853712236117,
-0.9282741838781579
],
"angularVelocity": [
-0.8154893741817122,
-0.8473592397801126,
0.02410829719988472
]
},
{
"id": "asteroid-31",
"position": [
121.59110902309624,
25.96647392161014,
23.13855160633822
],
"scale": 7.334708642788891,
"linearVelocity": [
-20.84177070876138,
-4.279470177228415,
-3.96614843788077
],
"angularVelocity": [
-0.29452403825860785,
0.11607308006521144,
0.016418776053258366
]
},
{
"id": "asteroid-32",
"position": [
79.40322114752394,
151.25146721457682,
124.98690191326033
],
"scale": 5.057867707702108,
"linearVelocity": [
-9.994536500426532,
-18.912252571324764,
-15.732184855907006
],
"angularVelocity": [
-0.10387762232765763,
-0.24983303420117142,
0.505433755007731
]
},
{
"id": "asteroid-33",
"position": [
75.05841348453647,
98.86489755496987,
-251.33834436884416
],
"scale": 3.112375640080296,
"linearVelocity": [
-7.504278546403557,
-9.784452096353522,
25.12860128497498
],
"angularVelocity": [
-0.6970085140531799,
0.6944302481856859,
-0.35779221719403775
]
},
{
"id": "asteroid-34",
"position": [
62.12618790923734,
-3.538937829080571,
-68.15533351103707
],
"scale": 3.9560817084240965,
"linearVelocity": [
-19.23558851230661,
1.4053516447957435,
21.10234016374278
],
"angularVelocity": [
-0.5473913868969675,
0.5730823351977983,
0.34838756558874984
]
},
{
"id": "asteroid-35",
"position": [
116.1756732408044,
55.691601789262165,
-83.00693976257432
],
"scale": 5.790391786535567,
"linearVelocity": [
-22.115687740050898,
-10.411322383021089,
15.801548713569543
],
"angularVelocity": [
-0.4347303882306277,
0.9261595614190203,
-0.020272311109515773
]
},
{
"id": "asteroid-36",
"position": [
202.65222744292402,
-69.19813058340729,
-97.67436596402304
],
"scale": 2.919604775164769,
"linearVelocity": [
-28.55002937763528,
9.889645505997791,
13.760549552805454
],
"angularVelocity": [
0.624846304863,
-0.6980451694656935,
0.262148924939285
]
},
{
"id": "asteroid-37",
"position": [
21.052291531932077,
253.14294794744347,
8.435171460322845
],
"scale": 3.235352100231171,
"linearVelocity": [
-2.802520592417765,
-33.56574284484931,
-1.1229058690486347
],
"angularVelocity": [
0.7128661478854434,
0.27389162999399863,
-0.49617905141764984
]
},
{
"id": "asteroid-38",
"position": [
106.13496487476972,
37.70879019675215,
87.53590556500609
],
"scale": 5.303624643451116,
"linearVelocity": [
-23.64338936973513,
-8.17751455364214,
-19.500128930629124
],
"angularVelocity": [
-0.8869435462374473,
-0.2811150680625407,
0.9565202371000203
]
},
{
"id": "asteroid-39",
"position": [
-102.52343593182007,
135.73338350636757,
-166.9420870067364
],
"scale": 3.81912041262033,
"linearVelocity": [
14.061297192085606,
-18.478956835178383,
22.896445850974125
],
"angularVelocity": [
0.33027822875958757,
0.23102989400352536,
-0.3494466798669773
]
},
{
"id": "asteroid-40",
"position": [
162.11131191959453,
-189.4249913585423,
113.89363719819275
],
"scale": 2.431958227282983,
"linearVelocity": [
-21.994376578171963,
25.83582182045546,
-15.452466066261982
],
"angularVelocity": [
0.3043681065855095,
-0.19744749997776978,
0.32696972189941675
]
},
{
"id": "asteroid-41",
"position": [
129.11775008401733,
-52.86681458051011,
64.15884326963163
],
"scale": 3.0433763109851872,
"linearVelocity": [
-24.665472195546855,
10.290222811609501,
-12.256317692461373
],
"angularVelocity": [
-0.9503568009196837,
-0.31292037634038916,
0.004492000893457693
]
},
{
"id": "asteroid-42",
"position": [
185.05967289629763,
-81.48079487150534,
-1.8481013399568662
],
"scale": 3.020662613857349,
"linearVelocity": [
-26.03407271399907,
11.603343816545628,
0.2599896774606195
],
"angularVelocity": [
0.908750453881332,
-0.2909648784959349,
0.1454952322511609
]
},
{
"id": "asteroid-43",
"position": [
45.60892236115607,
-154.08833936812889,
176.98372346031434
],
"scale": 6.9260118746472825,
"linearVelocity": [
-4.9210202803514,
16.733411441586135,
-19.095835800366732
],
"angularVelocity": [
0.37980155760189005,
-0.5598500116742731,
-0.48253708056293254
]
},
{
"id": "asteroid-44",
"position": [
14.104425185299734,
-22.854499660131754,
152.97105629804378
],
"scale": 5.755154864775539,
"linearVelocity": [
-2.585963326604952,
4.373582084004659,
-28.046342649330466
],
"angularVelocity": [
-0.7069096681256339,
-0.851126848962172,
0.7727105211435448
]
},
{
"id": "asteroid-45",
"position": [
-85.92473911003765,
230.09822167036307,
-37.212595160012135
],
"scale": 6.9599025866429445,
"linearVelocity": [
10.854424842547834,
-28.940785324907925,
4.700873363644876
],
"angularVelocity": [
0.6396974549193719,
-0.744270463323927,
-0.4830902335806382
]
},
{
"id": "asteroid-46",
"position": [
57.07524853608118,
48.604842189265014,
73.81865497533155
],
"scale": 4.079208065005364,
"linearVelocity": [
-17.51913027538697,
-14.612208504457865,
-22.658484482097897
],
"angularVelocity": [
0.2943588150897254,
0.6259462420689661,
-0.8410519641661378
]
},
{
"id": "asteroid-47",
"position": [
-22.974608684732146,
-34.886924563110306,
-135.18860401872973
],
"scale": 3.1168349533124733,
"linearVelocity": [
4.72635807604397,
7.382691825604627,
27.81112658591873
],
"angularVelocity": [
0.0817987574839929,
0.6101801942102383,
0.01853150710343643
]
},
{
"id": "asteroid-48",
"position": [
89.52661935896718,
-60.95315410138144,
-179.05527858955801
],
"scale": 5.653201692959181,
"linearVelocity": [
-15.187454150600228,
10.509842705297656,
30.37525434863282
],
"angularVelocity": [
-0.864004053155587,
-0.40368710501753124,
-0.3158807655172895
]
},
{
"id": "asteroid-49",
"position": [
-50.82991621619616,
27.639926942831284,
-87.79511819204637
],
"scale": 5.977674242247547,
"linearVelocity": [
14.856977108781319,
-7.7865323067980805,
25.661463924002415
],
"angularVelocity": [
0.4391256607855465,
-0.6970641496209811,
-0.7867959684450998
]
}
],
"difficultyConfig": {
"rockCount": 50,
"forceMultiplier": 1.3,
"rockSizeMin": 2,
"rockSizeMax": 8,
"distanceMin": 90,
"distanceMax": 280
}
}