-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathNOTES
More file actions
2158 lines (1888 loc) · 167 KB
/
NOTES
File metadata and controls
2158 lines (1888 loc) · 167 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Sprites
---------
http://opengameart.org/users/emerald
http://opengameart.org/content/16x18-magic-cast-animations-sheet-1-template
http://opengameart.org/content/98-pixel-art-rpg-icons
http://opengameart.org/content/lots-of-hyptosis-tiles-organized
http://opengameart.org/content/lots-of-free-2d-tiles-and-sprites-by-hyptosis
http://www.deviantart.com/morelikethis/artists/333013048?view_mode=2
http://gaurav.munjal.us/Universal-LPC-Spritesheet-Character-Generator/
http://www.realm667.com/index.php/en/beastiary-mainmenu-136-69621/heretic-hexen-style-mainmenu-137-49102#preview-3
http://www.spriters-resource.com/pc_computer/heretic/
http://www.spriters-resource.com/pc_computer/heroes3/
https://forums.rpgmakerweb.com/index.php?threads/avys-mv-stuff.53317/
Doom style meshes in isometric? https://www.youtube.com/watch?v=YqWWeb5nitc
https://opengameart.org/content/pine-tree-tiles
https://opengameart.org/content/lpc-snowy-tree
https://opengameart.org/content/pine-trees
https://opengameart.org/content/lpc-modified-art
https://opengameart.org/content/lpc-tile-atlas2
https://opengameart.org/content/lpc-tile-atlas
https://opengameart.org/content/lpc-plant-repack
https://opengameart.org/content/lpc-water-fountain
https://opengameart.org/content/enemy-well
http://www.ludicarts.com/free-videogame-asset-desert/
https://opengameart.org/content/pixel-house-and-fence
https://opengameart.org/content/cartoon-tileset
https://opengameart.org/content/statues
https://graphicriver.net/item/isometric-tower-defense-game-kit-pack-sprites-backgrounds/16958247
https://graphicriver.net/item/2d-isometric-game-assets-bundle-towers-castles-houses-more/17427144
https://gameartpartners.com/downloads/cartoon-nature-elements-set/
https://gameartpartners.com/downloads/2d-forest-elements/
https://gameartpartners.com/vendor/acasas/
https://gameartpartners.com/downloads/medieval-top-down-tower-defense-art/
https://gameartpartners.com/vendor/simirk/
https://gameartpartners.com/downloads/snowy-mountains-platformer-tileset/
https://gameartpartners.com/downloads/top-down-tileset-the-quiet-forest/
https://graphicriver.net/item/tower-defence-game-assets-and-sprites/14668129?s_rank=25
https://graphicriver.net/item/frozen-village-isometric-block-tileset/20770975?s_rank=42
https://graphicriver.net/item/topdown-winter-tileset/19292603?s_rank=100
https://graphicriver.net/item/topdown-medieval-forest-game-tileset/19292556?s_rank=102
https://graphicriver.net/item/topdown-dungeon-tileset/19292571?s_rank=101
https://assetstore.unity.com/packages/2d/environments/tabulampot-plants-pack-34715
https://assetstore.unity.com/packages/2d/environments/premium-workshops-tiles-props-100428
https://assetstore.unity.com/publishers/22311?page=1
https://assetstore.unity.com/packages/2d/environments/flowers-2d-vol-1-52810
https://gameartpartners.com/downloads/pixel-art-top-down-dungeon/
https://assetstore.unity.com/packages/templates/maze-game-2d-pack-70901
https://assetstore.unity.com/packages/2d/characters/heroes-and-villains-fantasy-2d-pack-26881
https://assetstore.unity.com/packages/2d/environments/simpleee-isometric-environment-pack-79749
https://assetstore.unity.com/packages/2d/environments/2d-trees-pack-107613
https://assetstore.unity.com/packages/2d/environments/2d-cave-rock-platform-53259
https://assetstore.unity.com/packages/2d/environments/cartoon-farm-building-29911
https://assetstore.unity.com/publishers/34249
https://assetstore.unity.com/packages/2d/environments/2d-fantasy-buildings-and-background-pack-65545
https://assetstore.unity.com/packages/2d/environments/handycraft-forest-pack-38517
https://assetstore.unity.com/packages/2d/environments/magic-village-13902
https://assetstore.unity.com/packages/2d/environments/fruit-village-25959
https://assetstore.unity.com/packages/2d/environments/wonder-forest-18020
https://assetstore.unity.com/packages/2d/environments/2d-isometric-elements-20300
https://assetstore.unity.com/packages/2d/environments/2d-rpg-environment-sprites-37493
https://assetstore.unity.com/packages/2d/environments/trees-2d-vol-2-52809
https://graphicriver.net/item/dark-castle-game-objects/21447559?s_rank=28
https://graphicriver.net/item/tower-defense-grass-pack/20321987?clicked=post_purchase_thumb
https://free-game-assets.itch.io/
https://assetstore.unity.com/packages/3d/environments/fantasy/isometric-pack-3d-62262
https://assetstore.unity.com/packages/2d/environments/2d-cartoon-castles-42750
https://gameartpartners.com/downloads/isometric-forest/
https://graphicriver.net/item/big-game-top-down-tileset/21920127?s_rank=4
https://graphicriver.net/item/fantasy-tower-defense-game-kit/21844669
https://graphicriver.net/item/magic-tower-game-objects/21485308
https://graphicriver.net/item/tower-defense-tile-sets/21135093?s_rank=37
https://assetstore.unity.com/packages/2d/environments/2d-stone-pack-64656
https://assetstore.unity.com/packages/2d/environments/tower-defence-construction-pack-106170
https://gameartpartners.com/downloads/isometric-forest/
https://graphicriver.net/item/big-game-top-down-tileset/21920127
https://graphicriver.net/item/fantasy-tower-defense-game-kit/21844669
https://assetstore.unity.com/packages/2d/environments/2d-stone-pack-64656
https://assetstore.unity.com/packages/2d/environments/tower-defence-construction-pack-106170
https://assetstore.unity.com/packages/2d/environments/2d-forest-buildings-44089
https://assetstore.unity.com/packages/2d/textures-materials/building/builder-game-2d-pack-21783
https://assetstore.unity.com/packages/2d/environments/2d-forest-world-tileset-119496
https://assetstore.unity.com/packages/2d/environments/2d-isometric-trees-60844
Purchaseable Sprites
------------------
Trees: https://www.assetstore.unity3d.com/en/#!/content/60844
NO inventory, use a belt/pack for storing immediate items (scrolls/potions) limited space. Use Messagebox for purchasing items from shops (link texts). Store quest items internally, show a box of what items you have already (unable to drop/interact/sell those items). Pickup armour from ground to put it on; deletes your current armour in favour of this one. Allow for armour/weapon buffs (timed/perma for item): particle system which you can walk into to get effects, quest givers provide this, certain monsters, etc.
HTML elements overlay for UI
Store all json data in localstorage; compare update time of data to check for necessary redownload/setup
NOTE: its MUCH more efficient to redraw individual tiles rather than all tiles; at 75%-90% tiles being redrawn the two methods are equal, 95% tiles redrawn takes slightly longer. Worth it to only redraw where necessary
Epic quests to gain really special things: any spells (eg. heal, buffing, etc.), artifacts; Spells require mana which does not regenerate, and can only be refilled from certain (rare) fountains, hence spellcasting should be a rare and important case
Certain skill trainers around the world can raise your skills -- costs skill points which you gain 1 every 3-5 levels? Each trainer requires you to do an epic quest (story-mode type) to gain that skill :: instruments, necromancy, wands, pet charming, cooking/brewing, planting, fighting(strength, protection, dexterity, agility)?,
Need basic items depending on where you go; those items are stored in your belt. You get those items by killing certain monsters (eg. silk from spiders nest, leather from bulls, etc.). When you die you lose ALL items and ALL gold on you. You may store gold in the bank, and also items in bank; but banks cost money weekly, and each withdrawal may cost money. On death you end up at nearest safe zone (town) which you have previously visited, and also have death sickness, and your god is mad at you
Skills: evocation (items), wand usage, instruments, pet charming, necromancy, planting (medicines, poisons creation/applying), firemaking for cooking, brewing beers & potions, martial arts (feign death, dash, sneak, stun, martial arts attacks), inscriptions (inscribing stuff in dungeons -- dungeon-wide/area buff/debuff?)
* The Stew Pot: a massive stew pot in one of the towns where you dump a bunch of random (edible) items to create a stew; the stew will have certain bonus/negative effects depending on the items and how the items react to each other
Steal ships -- get your own ship and go around the ocean; find tradeships (trading goods between cities) and overtake them. Will have to attack the guards on ththose tradeships, but taking their goods will effect the economy and trade in cities?
Possible to rob banks. Note the massive maze, traps, countless guards, dragons? etc.
A roguelike area where once you enter, you cannot get out through the same entrance. You must travel a long way to reach the end, with LOTS of heavy duty monsters and free player killing, etc. ALL of your items are dropped when you die, and free for other players to take. Perhaps a limited resurrection time with major penalties (eg. group raids). Also lots of treasure will be stored in this area for successful heroes. It is LONG which means people who enter will spend a long time in this place (hence, stores and such...perhaps enemy stores like in goblin towns or something, you will have to gain goblin faction or put on a mask to pretend to be a goblin)
Meat goes bad (necessary for disallowing auctioning/storing food with good benefits); however ice boxes exist and can serve for storing meat (raw and cooked). Ice boxes are really really heavy, so usually you have to go back to find the same ice box (maybe a really snowy mountain which is hugely dangerous where you might freeze..and things snow over..but if you remember where an ice box is, you can walk to the same spot and dig away the snow). Anybody can go into an ice box, unless you stick a lock on it
Gambling: two npc's go to an arena to fight. Players can place bets to whom will win; maybe they can help by passing the NPC some items or potions or buffs?
In-game card game like from M&M
Store maps as BSP tree? then only have to pass events from server to clients which are in sight of a given BSP node. Could extend this into fog of war for client
Store NPC history in local db, if we run into that same NPC or area again, recognize that locally and add some dialog fun, "You again?! You're ready to die again?"
RvR style areas for different factions (you can work your way into factions); taking over keeps/etc. gives a global stat gain/buff to everyone in that faction
Consider some items (core components) drop on a per-player basis? This prevents players farming areas for cash, and forces players to craft or work for their gear/utilities
Combat that actually requires skill/planning: eg. You're a rogue and spot an animal out in the open. You go invisible and sneak up near it, then place a trap w/ some bait (food). Then make a noise to get the animals attention so it spots the bait. When it hits the trap you reveal yourself and fire a dart at it, then run off in a direction. As it chases you you run through a (non-trap?) that you placed on that ground that speeds you up, then quickly activate a rune that will mezz the animal when it reaches you. You have a moment to place some seeds in the ground surrounding the animal, play your flute to quickly grow them into dry grass, and light it on fire to burn the animal (or perhaps keep it trapped). Throw over some napalm to explode on the animal
Equipment that auto enables you for PvP, and some that allows players to find you wherever you are. Maybe they can also steal this item when you log off (drops to the ground whereever you logoff or die). People can setup traps, defensive equipment, bribe monsters, etc. to protect their item. Banks won't accept this item, or perhaps you're kill on sight in towns so you can't deposit that item
Quests
- Romeo & Juliet
- Bridge Troll
- Princess & Frog: go to a dangerous place and collect the right frog which the princess can kiss and turn to a prince
WORKING ON (was previously working on)
- Error handling
- Never return errors (please keep note where it may seem useful); ALWAYS test and throw as much as possible
- throw Err(`Bad coordinates (${x}, ${y})`, requestPos, curPos) // Always throw Err (not new) with a templated string describing as much as possible, with as many args as possible (NOTE: can't pass arguments because of strict mode)
- Walking out of sync (testing with bot)
- Performance on walking/AI/players/scripts (profiler; check movable.js delta's; allocate X time per timestep to AI, may need to have a queue of AI updates and round-robin update -- on AI callback, commit update/details and round-robin update)
- client/game.js checkNewPages
- offload page/map sending to another process
- sleep/wake entities/pages/maps
- Loop issue in map-step: http://pastebin.com/fFrwmKA6
- Page stepping << Map stepping??? (possibly set pages to sleep?)
- Fix camera (currently resets every frame)
- Fix clicking to attack enemies (in lots-of-npcs maps?)
- Recycle Tile
- UI: Defer updates when too much time already spent in UI (round-robin update? webworkers?)
- UI: Hide/Redraw/Show html (to avoid redrawing after every css/html change)
- Clean Profiler mess
- Clean update/step mess
- Player send path (or path progress) rather than walk (inefficient otherwise). Make note of possibility of compressing (dir/dist pair compressed into 1 byte, then path is a string of walks)
- NOTE: NEED To identify map (otherwise if we request a path which has a similar starting point to another map, and we happen to zone into that map on the server right before the request comes through..weird shit happens)
- Clean pathfinding + partial progress mess
- Show "Still logged in.. can't login"
- Idle (animation) goblins when they get bored and finish walking back to spawn
- Debugging:
- Print current brain/neuralnet
- Draw current path (pos/dest & path + actual path written out on the right + recalibration)
- Neural network fixes
- Provide interface to neuralnet: get, has, remove
- Interface to neuron: property (es6 getter/setter)
- On any changes print out current neuralnet state
- Fix: movement new chase calls stop on previous movement which calls cancelPath EVERY time (and broadcasts event to everyone)
- Ranged combat
- Ranged attack (vs. melee) -- show sprite
- filterFunc:
- Option 1: Circular tile expansion, considering collision along expansion
- Option 2: Use precomputed Manhattan heuristic to determine each endpoint which could be reached, and their starting points. The paths between start to end will share common ancestor paths (NOTE: This means we HAVE to have each endpoint always take the same path which correctly shares its ancestor path). We could go through each ancestor path (beginning part) and see which tiles are accepted/unacceptable, then spawn the child paths if accepted, and continue on for however long the range is.
Actually we could spawn from the multiple different ancestors in certain cases.
Rule: Only allowed to follow 2 cardinal directions from startpoint to endpoint, from the startpoint we cna travel 1 direction for a max of X distance, but the first turn disables that and we have to make a turn every tile after
- Fix: entity uses alternate path which takes a completely different path; then path way through the new path (at a point which is much further away than the server position) the entity walks off in another direction. CurPosition & path start position could be drastically different
- Fix player attacks goblin 2 tiles away.. both walk towards each other and end up on top of each other (on evt move could be worth it to check if you could recalibrate to previous tile)
- Fix goblin bored walking back doesn't have sight enabled (ignores users running beside them)
- Setup build pipeline, concat, uglify, minify, SourceMaps, babeljs, jslint/eslint/jsint/jscs, smoke test (Jasmine?), flow
- Testing: use various test scripts (NOTE: there should be test maps for test cases so that we can isolate individual test scenarios)
0:00:00 - Jasmine( world.maps['main'].movables[1].move(4, NORTH) )
0:04:00 - Jasmine.assert( movable[1].position.y == 4 )
- eslint: spaces (4x)
- server.js: clean requirejs (should only require once)
- Logging: output to file, UI, colouring, store in buffer to flush together (or only print if a crash comes up)
- CLEAN: spam clicking movement lags out the entire game (server should ignore noisy players; client should temporarily ignore input between processing); should probably also have client-side check if the near-path has even changed, then only send the later part (updated) path when necessary
- CLEAN: clicking to move while zoning (disallow)
- CLEAN: remove server animations; auto client animations (facing target, etc.)
- CLEAN: Movable setting params before/after Ext
- CLEAN: player/NPC moves to edge of new page; they are still able to attack across pages, but this may cause issues for other clients who don't have the other page/movables in memory
- CLEAN: renderer.js, rendering page & sprites & movables; render only visible portion of pages; clean static rendering; abstract rendering operations
- CLEAN: rendering (set base tile, and sparse sprite/base/items/movables (obj w/ key as coordinate); each tile contains the tile_id and a reference to its sheet)
- CLEAN: convert server tiles to Uint8Array; each references an index of tileRefs which specify the gid; cache and send page data as a blob (for compression/throughput)
- CLEAN: switch from loops to maps/forEach/...
- CLEAN: clean up Promises: Promse.then(...).then(...).then(...).catch(...)
- CLEAN: fix up .call .apply .bind for performance: http://jsperf.com/function-calls-direct-vs-apply-vs-call-vs-bind/6
- CLEAN: replace .hasOwnProperty: use property access (eg. obj['id']) which is significantly faster; unless we can expect undefined/null/0 then use `in` (eg. id in obj)
- CLEAN: switch parseInt w/ Math.floor where necessary: https://jsperf.com/math-floor-vs-math-round-vs-parseint/
- render background canvas as ALL neighbour pages; then simply translate the canvas as you walk around (NOTE: drawImage on background takes up the most CPU in profiling; this would fix that completely)
- server & client initialize gid's separately (in arbitrary order), and then server overwrites client gid for necessary tilesheets. So king sheet has same gid.first as items.sheet in house since house doesn't overwrite items.gid. SHOULD precalculate all sheets gids' into sheets.json
- Safe spot: if entity logs in or respawns to bad tile, relocate to the safe spot instead
- Server jump to client's current path position (ie. server receives client path 0.1s later, so jump to the position that he should be at)
- Client path out of sync: speed avatars up when too far, otherwise teleport
- Clean commenting style (top of file/class, splitting between members/public/private properties of classes, methods)
- Resources.js using 'dist/' directory, should abstract this
- http://bluebirdjs.com/docs/install.html : look at node installation debugging techniques
- Tool for .myquest-globals.json (js script to load globals json, go through game to get keys & "GLOBALS['...']=", add keys if not found in globals, then write to globals)
- player.disconnectPlayer() should unhook everything which may be listening to it.. "Entity page does not contain entity" when user attempted to d/c while a bunch of npcs were attacking
- server.js: Make players an array; also improve eventBuffer (object of mapID, pageID) should be arrays. Perhaps we could map (map,page) pairs to indices which the player could contain? Although maps will soon be threaded anyways
- Look into https://www.joyent.com/node-js/production/debug for debugging techniques http://stackoverflow.com/questions/1911015/how-do-i-debug-node-js-applications/16512303#16512303
- Assertion testing: find a good assertion library (should be easily extendable, readable, minimalistic, compatible through browser+node using native assert) and find a way to easily remove (or disable) asserts from prod. eg. `assert(XXX)` ==> `if (!prod) assert(XXX)`. Assert ALL type checking on functions as much as possible; how to coordinate this with if(XXX) throw Err ?? We may want some asserts to remain in prod and only most of them to be in debug
- Add option to disable asserts in production.. NOTE: NEED To either remove asserts, or prepend (if !prod) to them, otherwise it'll still call the expression before calling the assertion
- Confirm that we can remove onEntityWalking, and focus entirely on onPathProgress
- Fix hooks to not require context (could use arrow functions intead)
- CLEAN: switch from errorInGame to shutdownGame to shutdown server (unless there's an error)
- assert(HiddenClassChecker(1, arg), "...") .. HiddenClassChecker uses the caller/num as an identifier, then checks every property of the arg to determine if the last recorded arg had the exact same hidden class (otherwise throw)
- Area vs. Region?
- Aggro: attacking one person then another person walks right beside you, you ignore them
- Client pathfinding - prefer to move the same direction you're already going (weight of +1 for immediate turn)
- Loggable time; also allow server to extend messages with time (or ID) and client can print out received event (time/id) before handling
- Client loads serialized page/movables w/ path in progress and disregards current walked amount; should shorten walks by amount that has already been walked (to avoid entity walking more than necessary)
- Fix Strategy loading/handling in combat (be conscious of memory); should be able to abstract functionality; should be able to extend w/ Logs
- 2D spritesheets out of 3D models
- 2D texture synthesis https://github.com/mxgmn/WaveFunctionCollapse https://github.com/mxgmn/SynTex
- Can we remove 'static' property? A bunch of scripts are using them but doesn't seem to do anything
- Script initialize should pass itself as the 1st parameter to allow initialize as an arrow function (this context to be what we expect)
- "use strict"
- if checks on north/west/south/east have an else case and throw error
- AbilityState vs Instinct?
- Path Sync: If receiving path for an entity that's out of view, and the path position is also out of view, then teleport entity to that position
- Update "var" to let or const (lots of files still using var)
- Path/Walk destination tile (some places are using it, some aren't.. need to either go all the way and do it or not at all)
- Merge walks w/ same direction (seems to be more than recalibration; and messed up locally)
- On crash dump as much debugging details as possible (.dump() for entities, characters, etc.)
- Cancel character path on respawn: Is this a good idea?
- Clean ServerHandler response from server (loops through entire event archive from 0..n, this seems unecessary)
- Scripts are being loaded twice on startup: client/game.js initialize, then loadAreaIntoGame.. Find a way to only load once on startup
- Debugging
- Open Chromium for bot/server debug (exec chromium)
- Run bots with both --inspect and debug to auto break on debugger statements, but also leave room to debug through dev-tools later
- Error Report: Webpage that takes a report.json and displays it accordingly
- If live: email error reports to me
- Error Report: Fix dumps, and add dumps to *EVERYTHING*
- Cleanup player requests / error checking
- 1) Confirm we have expected and valid args
2) Call handler: handler checks valid args, then attempts to run
If there is any issue in the handler or caller respond to the user with the err msg and return false; do NOT allow subroutines to throw errors, check input before then
Need a routine like, confirm( [dataAssertion], "Invalid argument" ) where confirm acts like an assertion and auto responds to player evt
- Smoke Test
CLIENT: bot.js (loaded via Karma) should load Game as expected (strip renderer/ui)
- Read from some test file
- Server takes in arg to specify that its for testing. If testing then load test world (NOTE: want to do all startup routines at beginning to speed testing up). Extend Player class to accept args from Bot (if in testing mode) rather than loading/saving from DB. Otherwise maybe we could have a test DB/Redis?
- Bot loads test file, sends necessary args to server, then runs through test cases
- Server should run at varying speeds to allow quick testing
- Can we make it so the bot can load/reload in the same instance? eg. new player / map / etc. without reloading base modules?
- Maybe we can have Test framework load base modules, then individual bots under the Test framework are loaded/unloaded as necessary. This way we can also have multiple bots doing things in parallel and even interacting with each other
Testing: use various test scripts (NOTE: there should be test maps for test cases so that we can isolate individual test scenarios)
- Fix error reporting in bots (throw)
- Setup test resources
path/recalibration, signup/login/logout (also double logins) + chat
- rock-recalibrater: spam click around a rock that's between pages
- page-running: runs between neighbouring tiles on the corner of 4 pages
- zoner: zones in/out
- train: many bots running through large map (lots of ents)
- Bot interface to Game/test
- Close server test websocket
- Test framework: Loggable
- Test framework: Do base module loading here instead of on bot
- Bot: Move renderer/ui and clean
- Clean Client/Server testing overrides (messy testing stuff)
- Bot: Debugger option
- Bot interface + tons of tests
0:00:00 - Jasmine( world.maps['main'].movables[1].move(4, NORTH) )
0:04:00 - Jasmine.assert( movable[1].position.y == 4 )
- Need to find a way to organize bot logs
- Integrate into Grunt
- Integrate Mocha
- Fix error reporting
- Abstract stacktrace/error report from client/server/bots
- Timeout on tests
- Consider multiple bots running at the same time: most importantly would be one bot loading or zoning into a page or map where another bot is already doing stuff (running around, attacking, etc.)
- Debugging:
- Area draw map; server.test should be able to return pages/data to test framework, and bot can draw both maps side-by-side to show differences
- Store history of paths for entity: path id/flag, to/from, received path and current state (if client); print this out nicely, potentially with visuals (tiled on left, and zoom-in of recalibration on right)
- Enable log buffering on client
- Add times on logs (min/sec? no need for large timestamps)
- Make requests to server for history of paths on entity; log timestamps (between ranges)
- When bot (or server?) crashes, enter interactive console to allow debugging (eg. printing path history, etc.)
- BUG: If you're queued to d/c and then die before you have a chance to d/c, your queued request will still trigger and crash the server (since dying removes your player from the map and the d/c attempts to get your character)
- BUG: Start test bot then load in part way through; when receiving PathCancelled messages and bot is out of sight shit gets crazy
- BUG: Client throw Err doesn't actually print thrown message, just "uncaught exception" eg. server handler functions (onPathCancelled) (temporarily added console.error in Err class)
- BUG: Disconnecting player says, "Successfully updated player (5) position"
- BUG: Bot: server adds path for player which has its own onFailed function so we lose our onFailed callback
- BUG: On browser when running bots, open console and notice the lag, then we start hitting "Recalibration is longer than our maxwalk"; try suppressing logs to see if that fixes lag, and also turn this error into a warning
- BUG? Clients should not set combat/melee target since server paths will take over and cancel your current paths thus resetting the target
- BUG: UI offset on entities (possibly due to old page and local offset?)
- BUG: DB saves position without open tile checking
- BUG: Suppressed logs w/ LOG_INFO aren't being logged afterwards
- Check Promise/Deprecation errors: --trace-warnings --trace-deprecation
- Roaming bot: preprocess map to build a nav graph; have the bot go between nav points on graph to satisfy his roaming goal
- BUG: Recalibration (working but need to finish)
- Merge walks (note: need to coordinate with ordering recalibrations too. eg. recalibrate north, recalibrate east, path goes south):
1) Prune walked walks
2) Take the 1st (non-walked) walk of the path and subtract its distance from the recalibration + add to that walk distance -- NOTE: This should ONLY be on the recalibrationEnd recalibration
3) Path.PushWalk(..) which unshifts the new walk or otherwise merges it with the current front of array walk
- Fix walks of 0 distance (probably because walk.walked == walk.distance)
- Max Path check (used to be maxWalk)
- List ideas for avoiding spam clicking: request timout (spam click 3x, each path request replaces the previous and the most recent one is used during path check), path check cache (point A -> B checked and cached), map regions (convex hulls) then cache path checks from region A -> B. Otherwise we could accept all paths from people and simply cancel them if they're about to move into a collidable tile (this also helps with dynamic tiles!), then remote players could check the path for collision and if there's a collision simply walk up to that point?
- Complex test: Have variable number of bots zoning in/out of house
- Change item "types" to "attributes", and add a "type" property for abstracted data: eg. "potion" has stack == 8, has attributes "USE" and "PICKUP", etc.
- Try converting AOE triggers into circles added to a trigger list in each page; then just listen to EVT_MOVE_NEW_TILE on the page and check the position against the point/radius
- Get rid of .before on hooks, and just have a 'hookX-pre', 'hookX-post' instead for those specific cases
- Look into if V8 uses symbol tables for strings, or should we implement this? (particularly necessary for hooks in fast str cmp)
- BUG: Change SCRIPT.INJECTION, ./grunt doesn't update all scripts
- Respawning/Zoning should fadeout, then fadein when all scripts have loaded and are ready (mostly so that we don't see UI flicker); Also should pause renderer
- FIXME: Fix SetAsPlayer() on server -- script/game.js calls this everytime the character enters an area, resulting in restoring and re-hooking and other initialization stuff which is unecessary. Should be setting player outside of this, on login. Currently using .initialization to prevent multiple reloads
- FIXME: Find a better name for charComponents on character. We can't use components since character is a script and depends on components (see scripts/game.js using components)
- Look into possibility for utilizing netSerialize/netRestore for dynamic changes on character without having to send events
- Cleanup component serialization/restoring, currently its an array on character but object in db/netSerialize, and we have to find the component name by npc index. Overall gross and needs some cleanup
- FIXME: Cleanup server login control flow to create your character before sending you character info, that way we can netSerialize your character rather than send your serialized db state -- afterwards would be nice to remove netInitialize and use netRestore instead
- Look into async/defer scripts: https://bitsofco.de/async-vs-defer/
- Merge Character/Components netRestore and restore common code somehow (sucks to duplicate code)
- Buff Fading: Death sickness fade (slowly regain con/curMax health) :: fade/tick, send BUFF_MODIFIED_PRIVATE to client
- Look into image rendering tricks for building anims: https://css-tricks.com/almanac/properties/i/image-rendering/
- FIXME: ToolUI.effects tooltip can't get height while its not visible
- Abstract loot into a character component for npcs
- Buff stacking
- Add an icons json; allow spritesheets
- Look into a better solution for Components referencing The.scripting stuff
- Fix server synchronous error reporting: currently sync because if the server crashed and writes, it exits before finishing writing and therefore ends up wtih empty reports. But sync is completely unecessary if the server isn't crashing (for client/bot reports)
- Fix interactables: currently we invoke from Resources interactables list, which runs new every invocation. We should only instantiate the base once, then treat it as a static from then on
- Fix catch on requirejs errors (OR switch to another AMD loader, but still need to catch on script errors)
- QUESTS: How to handle events which affect later quests? Perhaps the quest could be opened/initialized, and then store the questkey or flip some flags in order to
- Quests/Interaction: Client side execution for nodes (eg. killing boss npc, "You feel the evil spirit has disappeared")
- Quests/Interaction: Abstract conditions/executions between interaction/quest (and other stuff later); perhaps some scripting functionality (similar to The.scripting)
- Quests: Listening to other events on character (certain NPCs could have an array of events they trigger on character that kills them; how can quests listen to that? should we save those event keys on questmgr in case later quests depend on it (ie. not needing to kill some boss character again after initiating the quest)).. To prevent unnecessary over-listening, we could instead emit EVT_QUESTKEY with some value which the questmgr forwards to the corresponding quest
- Quests: If quests need to listen to events independently: Might need to store non-active questing stuff in db, and only load quests when necessary: quest node isn't listening to anything, so only load quest into component when we talk to guy. We can improve this later to only load quests from db when we enter the map which affects this quest, or only load parts of the quest from the db as they become necessary (eg. list of steps in the quest which I've achieved)
- Interaction: Conversation shows in UI; able to select options (text on top, spacing, then links underneath for responses)
- Interaction: After running an action don't display dialog options again (ie. repeatedly clicking the interactable shouldn't flood your messagebox with the dialog)
- ExportMap: Support new data format (zlib compression, currently using CSV)
- Interaction: Hook interaction fsm into interactable
- Periodic saving: look into partial saves on dirty components for characters; and saving all players at once. Dirty position when you near a new "safe" checkpoint?
- Projectiles: Add shooting bone/offset from archer's sprite
- Projectiles: Find a better way to determine if the attacker is firing a projectile, and the projectile type
- Projectiles: Better time-to-die calculation for projectile (per projectile number?)
- Map Exporter: If tileset was not embedded in the map (eg. we imported or saved an external tileset) server/area.js cannot read external tileset
- Sprite state (anim) should be maintained on the server. This is sent to clients when they zone in, and prevents from seeing sprites which are attacking when really they're in the middle of attacking
- Pack/Compress/Encrypt resources (in case any are purchased)
- Look into tossing pathfinding / other stuff onto another thread (child process); child processes can access parents, can this help with executing event callbacks?
- Can we netSerialize once on changes, cache the results, and send those cached results to everyone on changes? Or should netSerialize only be done on initial load
- would RMI a netSerialize w/ flags indicating what members have changed
- Rendering background: could probably render each page background to a hidden texture/image/canvas, then when redrawing the background just render each prerendered page to one canvas; moving around the map only involves moving the background canvas. Zoning into another page could involve asynchronously rendering to a buffer background, and then switching the two background canvases when its ready
- Cleanup
- Async render (for new neighbours and buffer background)
- Storing assets: encrypted assets; should pack things together (for now; later we could look into packing things that would likely only change together, or otherwise keep packs small so its a short download); compression; headers in packed assets
- CacheBuilder
need: cached? encrypted? packed (image/sound) w/ coordinates (x/y? time? data json)? compressed (manually -- png -> webp)
5) assetHash
- Cache data files (data/json files)
- Check for changes to cache options (stringify cache options -> hash -> compare to previous cacheOptionsHash)
- Gruntfile watch for changes to raw assets / cache file; rebuild cache
- Client
- Works for headless (server/bot)
- Async (WebWorkers?)
- Decompress
- Webstorage?
- Update git w/ cachefiles
- All PGP -- look into PGP for best solution + architecture for this
- Look into filestreams and if fs.read/write or streams/pipes are better
- Compress (Brotli? Gzip?) + browser to auto ungzip; okay to use XHR request for automating this?
- Pack some sheets together; Pack sounds; reference by cache file + offset + width/height
- How can we handle this w/ static elements whose img src changes (eg. mute/unmute image changing on element). If we create copy of image initially + cache, then we have to make a copy of the image every time we want to change our element image. This copy is probably super inefficient since we're copying a new image every time? Is the only option to have multiple images for each img src, and only switch out the visible image? Could be bad if we plan on having many dynamic icons popping up (eg. buffs over entities heads where we could have utilized an image element pool)
- Look into http2 changes which may make packing images pointless
- BUG: Map Exporter: Adding avatar to base/sprite layer doesn't result in gid error (it should!); should confirm gid's so it doesn't result in a confusing error when starting up server
- Bake Spritesheet: Add / Modify sheets.json (option)
- Sheetedit: adding a new tilesheet but not setting any data yet (no collisions/floating/etc.) results in no data object, which crashes startup
- Adding new tilesheet/spritesheet ==> automatically add empty cache; OR merge cachefile and sheets file
- /teleport zone to another page that we already have: we should only fadeOut if we're teleporting to a spot where we'll be near neighbour pages that we don't have yet (need to wait for onZone pages). However, if we teleport like 3x tiles away that happens to be on another page, that probably doesnt warrant a fadeOut
- ctrl+c kill not working; or resulting in bug in errorReport
- /teleport to another area
- Map Editor: Switch spawns from object layer to normal layer (easier for placement)
- FIXME: sheetedit get rid of tilesize and avatar setup/manipulation
- Clean sprites folder; cache/sprites/scrawnyGoblin.webp , sprites/goblin/{scrawnyGoblin.png,goblin.json}
- Right click on entity; admin features enabled
- Improve appearance
- Server watch for json changes and autoreload those parts? (Specifically npc.json)
- Admin toolbelt
- Improve appearance
- Abstract where we add options (shouldn't be done within the toolbelt ui)
- Command: Reset AI -- specfically remove yourself from enemy neuralnet
- Autocomplete: show "..." ellipses if there's more commands; tab cycles through extra commands
- Admin Commands: Abstract out of player
- Take periodic snapshots of world state; record all player input + time; randomness could come from a class that chooses random numbers (and stores them for later). When we crash we can take the most recent snapshot and playback input w/ provided random numbers. For perf we could only save delta in snapshots, and rebuild from very first snapshot
* - BUG: Reloading files (npcs): sometimes doesn't trigger; sometimes triggers multiple times for 1 change
- BUG: UI.unload -- removeEventListener requires cb to remove; maybe jquery to add/remove/manage events?
- Reloading npcs: need to update players w/ changes? -- need to netRestore changed characters OR trigger an event (similar to regen) w/ reloaded shiz
- netSerialize/Restore overhaul
- Consider removing EVT_REGEN (can just use this system now)
- netSerialize only sends stats to owner; Should stats not be netVars? Or should we also netSerialize stats?
- Look into character.stats usage elsewhere (to fix): db, buffs.statbuff (eg. deathsickness, levelling), client/game, ui.stats
- LOOK INTO: Reloading character for clients when movable moves out of PVS of player, but character is not(?) removed, and then comes back to PVS -- how do we handle this for updating health so far?
- Look into building netSerialize functions by string rather than hand building every permutation
- BUG: Firefox sometimes doesn't start (timeout)
- BUG: Hitch zoning between pages (particularly in Firefox) -- could continue temp pooled page rendering trick + webworker rendering new pages
- Renderer: Look into UI (movable name/health) rendering options; CSS restyling/recalculations causing hitches
- We could use the entities canvas already
- We could have a separate UI canvas and use pooled pages (similar to bg pooled pages), then for movables that move use blitting to clear that part of the canvas and redraw in that region
- Test map w/ lots of entities; how is performance on sprites canvas? Can we benefit from utilizing similar technology to pooled bg, and also use blitting to clear areas where something has changed (animation, etc.)
- Get rid of EVT_ZONE triggering locally for player (possibly for all entities?)
- Can we get away with not triggering this locally? We can rework some logic (UI, camera) to determine your page based off of your global position
- We change our curPage (area.zone(page)) w/ EVT_ZONE locally AND remotely; this seems dangerous depending on the ordering and potential mismatch of things. Would be better to only use reomte curPage
- Renderer.updatePages, UI.updatePages: could update on remote zone
- Renderer: pooledPagesCopyImageData -- consider getting rid of this option
- Grunt monitor filesystem (watch) sometimes not working
* - BUG: Player 2 attacked rhino, player 1 finished off rhino, then rhino respawned; player 1 left PVS of rhino, player 2 started attacking rhino then zoned out, player 1 started walking back and rhino was found to be chasing player 1
- Modify assert (or roll out our own) to make use of waitForInspector
- NPC inheritance
- NPCs: get rid of "damage"
- Fix: statBuff is not very flexible (eg. cannot have max/cur multiplier for same stat in same buff; tick seems questionable), should validate buffRes on startup to confirm its good. Cleaning this up for scalability could instead allow us to overcomplicate buffs
* - Combat: debuff effects (eg. poison arrows, thrown potions, etc.); how to add this to NPCs too? (NOTE: NPCs we want it % of time to happen)
- Handle for ranged
- Map: Layers that auto flatten into sprites layer (eg. fenced off area which is in another area, so we can easily modify fence layer later)
- Idle anim; between attack animations also go to idle anim (in same direction)
- Mesh setup:
- BUG: Placed image in / instead of /sprites
- Fix default avatar to looking to the right; specify avatar by anim name/dir?
- Fix bounds checking (way off for bunnyrat)
- Provide python cmd to create cylinder & circle
- Fix bunnyrat camera placement (seems like he's standing in a different spot for left/right/up/down)
- Come up with a better model -> in-game procedure
* - cache should be automated
* - previewing model+anim should be easier/faster
- render first frame of a particular anim (or by default just first anim); with/without post-processing and with/without texture processing
- render particular anim/camera; with/without post-processing + texture processing
--preview-anim [anim [camera]] --one-frame --variant [sprite texture variant; texture/post/size/etc.] --compare-with [sprite:anim:camera]
--preview-shots for separate renders (as opposed to --preview-anim)
--compare-with depends on --preview-anim; combines anim from another sprite w/ this one; if no camera specified then each camera, and each camera anim should loop until both anims have finished on that camera
- FIX: Clean folders before/after? (if we only render one anim then don't bother creating anim folders; if we only render one camera then don't bother creating camera folders)
- FIX: --compare-with-sprite loopN == max(compareSpriteAnimL, previewSpriteAnimL) (so we don't cut one loop short)
- FIX: preview anim: save in shots.preview
- FIX: --compare-with-sprite camera = all
- FIX: --compare-with-sprite extent
* --side-by-side display preview anims side-by-side in a loop (useful for checking post processing quickly; particularly --side-by-side --one-frame)
- Should hash .blend file and sprite.json to see if we need to re-render or not -- NOTE: Would also need to hash dependent files (eg. texture), might be worth it to restructure folders to keep all blend related files under one folder, then recursive md5sum that folder. Will need to render to separate variant folders (since different preprocess/etc.)
* - node cacheBuilder after sheetEdit should be easier
* - anim compare w/ other sprite (both attacking; chasing, etc.)
* - anim preview should be slower / easier to analyze (perhaps each anim-type side-by-side?)
* - tool for editing textures w/ imagemagick
- set a placeholder texture image; then write texture changes at bake time to that one file
- list of sprite variants + settings: texture changes, post-processing changes
- clut: convert magenta.png josh.gradient.test.png -clut +dither asdf.png
- remap: convert magenta.png +dither -remap josh.gradient.test.png asdf.png
- convert magenta.png -separate -threshold 50% -combine +dither -remap josh.gradient.test.png asdf.png
* - setup imagemagick lookup colour palette
* - fix pixelation step
* - auto add to avatar? auto add to npcs?
- error checking (validate sprite.json: "atk", "walk" anims; spriteSize included, etc. ; blender check valid anim/camera args)
* - Faster trims
- Include .blend file in sprite.json (no need to manually have to specify this)
- Could have a sprites.json file in / which points to each sprite and their sprite.json file
- --compare-with-variant
* - Look into why Bunnyrat is so small for up/down compared to left/right
- Clean folder structure for sprites; git add sprite.json files; encrypt sprite folders + git add?; all sprite images for sheets should be in a git added folder so its easy to see when new ones need to be added (git status)
- /resources/sprites: sprites for sheets in game
- /sprites/...
- sprite.json
- cache folder??
- all art output should be placed here (although structured: tilesheets, spritesheets)
- add directly to resources folder? (no more cache folder, just goes right into here)
- ALL resources added to git (public!)
- need public/private resources (models, maps, raw sounds, etc.)
- /art, /sfx, /maps: private
- resources: public/build (all json files references shit from here) ; NOTE: some raw files here too (eg. data, json)
- we could have ALL data in /resources, then /build for built stuff
- json/data would also go through caching (EVERYTHING goes through caching, even if just a copy)
- this also allows us to force json changes through a JSON validation system
- OR we could put it under dist/ w/ scripts: dist/js, dist/resources
- /js: scripts
- /resources: dev resources (everything)
- /dist
- /js: compiled js
- /resources: cached/processed assets, validated json
- rename cacheBuilder to resourceBuilder; integrate w/ grunt
2) Rename cacheBuilder -> resourcesBuilder/Processor (rename other things accordingly)
3) Integrate to grunt
4) JSON validator; disallow server to run without validated JSON?
5) cacheBuilder: rawAsset "resources/" shouldn't be necessary, should be root folder for assets
-- reload npcs/json: auto move to dist and watch data files there
-- clean cache.json ( "dataList": [ "resources.json", "sheets.json", ... ] ), OR read data files from resources, maps from world, sheets from sheets, etc. and allow cacheOptions in there then get rid of cache.json entirely :O
- Grunt: watch areahashes.json for changes to copy over maps, etc?
- Should only need to rebuild a specific asset group (maps, images, sounds, etc.) or even specific asset
- ./resourceBuilder --checkNeedsRebuild (or a bash script) to go through all cache and see if a rebuild is required (without doing anything); resources.json contains rawAssetHash for each data, sheets.json, sounds.json, etc. so we can just compare hash w/ file to see if rebuild is needed. Run this on server startup, and don't start if rebuild is needed. Grunt watch resources folder for changes and run this script to see if rebuild is needed, and if so then rebuild. NOTE: Need to run resources.json last since updating a sheet will change sheets.json hash which in turn will update resources.json
-- resources/sprites: bunnyrat.json, bat.json, etc. resources/sprites/models/bunnyrat (actual model here); .gitignore resources/sprites/models
- OUTPUT param to override output (for testing/checking)
- Look into achievedXP: seems like we could surpass our achievedXP while not reaching our achievedLevel, and start messing with our achievedXP. Might even be worth it to netSerialize(owner) for the achievedXP/Level
- Fix model -> spritesheet camera/size issue:
- Sprite moving particularly far in one animation: we don't want to extend the sprite size, instead we want to
offset the sprite in-game (by some scale of the actual offset). Since this is on a per-frame-per-anim
situation, need to allow per-frame offsets. eg. Death (body sprawling out), flying
- Center of sprite: We may want to specify the center of the sprite (could use a visual tool like a sphere, and
name in mesh.center), such that the sprite draw location indicates the center of the sprite being drawn there.
Helps for weird situations like long tails (we want those to draw, but the rest of the mesh to draw in the
central part). Would need sprite offset per-frame-per-anim. NOTE: center object may need to change per-frame
(would want it to follow some vertex or something)
* - Combat damage
- Fetch weapon info for calculation (otherwise defaults)
- Separate constants into rules?
- Symbolize item.types (for quicker comparisons than string cmp)
* - BUG: Avatars: ordering was mixed up somehow (bat showed up before bunnyrat)
- Avatars: Make avatars larger to fit titles, but center the sprites such that they appear on the tile w/ a decent size
- Spawn bodyguard: spawns a bodyguard (w/ some characterTemplate) w/ AI that follows you and aggros enemies -- could have different AI strategies for different bodyguard types
* - Sheet Editor
- Large canvas: move the avatar options to the right and allow avatars list to collapse (if we have a not very wide screen: laptop)
- Large canvas: automatically determine maxWidth (should stretch from left -> avatar options box)
- Anim preview overflows
- Anim flipX
- Scroll up in chatbox, when something new is added it automatically scrolls down (if we manually scroll up then should disable that)
- Mouse hovering enemy/item: bigger bounding box rather than just the tile
- Need a better mouse icon when hovering item/interactable/npc
- GodMode: cannot die
- Add character template, buffs, etc. to autoreload
- Validate JSON on startup: validate all JSON data files on startup to ensure we don't run into unexpected issues
* - Combat feel:
- Running towards enemy, they start running towards you, then realize that you're in range and need to move back to center
- If we have a target who's moving towards us, then stand still OR only move to the next tile if we think we can make it there before they get there? This helps with cases where they may not be attacking us, just walking within our aggro range
- damage feels too late: you get hit at the same time that you kill the enemy?
- Animation go back to first idle pos in between hits?
- Animation: Can we anticipate attacks and begin anim early?
- Initial attack (anim issues):
- We receive attack events before entity finishes walking locally
- Could we queue anim? No because its repeating....although what if we stop the walk anim? This may look weird that our health changes BEFORE the animation runs
- We could force the attack anim (higher priority), which would look like attacking while floating/moving
- Reloading npcs:
- We *CANNOT* cache values from old npcs, or npcs in general, otherwise we keep a stale npcs
- brain/components/etc. of character need to have an initializeNPC routine (find a suitable name!) that runs on startup and when we reload NPCs
- Add all media assets (tilesheets, spritesheets, sounds, images), maybe even all assets entirely? to a global assets list for quick lookup
- Look into media storage for git for dist/ (eg. git-lfs); worth it?
- Colour NPC names based off of their level difference
- Players need to start with some piece of armor (at least 1 AC) and already worn
* - canLoseItems for level: cannot lose items < level 5
- Character Template: run sequential commands (either server or client) -- to start out as level 1 and run /level_up so that we don't have to create a character template for each level (accumulating stat gains for each level!); /reload_level to go back to level 1 and /level_up until we hit the same level? Otherwise we could have /reset_to_level
- Command: Set spawn point (sets it to where you're standing if no coords given)
- Command: God mode
- Test script to go through pairs of npcs and put them to battle X number of times, to see what the results are. We can use this for adjusting character stats/items and tweaking npc stats, then go through tests to ensure the results fit within some expected ranges (level 5 kills level 1 in < X seconds, remains w/ > Y% health, etc.)
- Could this script also report stats when obtaining level X
- Should save changes from last run, and only report stats which differ (significantly?) from the last run (eg. only npcs that we've changed), or those which fail our expectations
- Could run under Jasmine, or otherwise extend our smoke tests to allow unit tests
* - Hover over items in inventory to see name/description/icon
- BUG: Furry Gloves dropped on ground has different sprite than when in inventory
- Fountain of healing
* - Determine how to upload media/etc. (does http need /dist ? what do we upload from /resources ? do we upload /dist/resources manually ?)
- /resources/data -- we want local version
- /dist/{icons,sounds,sheets} -- we want compiled/encrypted stuff BUT if we run the resourceBuilder will screw up w/out having source files
- We could have taskRunner monitor source (secret) directories for changes, then compress + encrypt dir; encrypted dir is added to git (/resources/sheets/bunnyrat.zip.gpg)
- NOTE: If we do this then we have no way of safely merging encrypted/compressed sources
- Later on we could also store a json of hashes for each file in directory of its "installed_hash" (the hash of the file when it was installed/updated); then in ./install_assets we check the installed hash against the current file hash to see if its changed since it was installed, then the local file hash against the incoming file hash (in case we manually copied over, or made the same changes in both), then report conflicts and require user input for either manually overriding or skipping those files in install
* - Fix running on server vs. local (root directories, etc.)
* - BUG: avatars.json somehow messed up (bat/bunnyrat were swapped)
* - Fix: easy way to switch between environment testingLocal
* - BUG: cancelPath w/ no path (also happened for player when you're alive -- see screenshot in ~/Pictures) -- Should only be an issue for current player, but probably not an actual issue? (Just need to check if we don't currently have a path, and handle accordingly)
* - Setup server to automatically restart (new server instance) BUT leave the old one running for debugger? -- runserver can check processes to see how many node servers are running (likely paused) and start another one if possible; can current node process disconnect from bash script in some way to allow it to realize its disconnected? Otherwise do we need to use some communication medium, or even have the server touch a file when its either about to shutdown OR waiting for inspector; Could use JQ
* - BUG: 2 users login next to each other, 1st user won't see 2nd user login
- Is this due to server having 2nd character already in game, sends 1st player all movables (including 2nd player), this while the 2nd player is somewhere in the process of disconnecting and loads in
- Possibly due to handling events before we've initialized our client (callbacks for EVT_REMOVED_ENTITY, etc.)
* - BUG: One user levels up, other user hears levelUp ding
* - BUG: One user waiting in page, other user continuously refreshes to load back in, at one point the 1st user witnesses two copies of the same 2nd player (2 separate entities!)
* - BUG: Form autofill doesn't work?
* - FIX: Client errorReport sent to server; server all errors (server + clients) emailed to me; server pops into inspector -- errorReport and email to me w/ message of inspector waiting (or just email that inspector is waiting if no user input w/in X time)
- fuckingtaskrunner running out of memory....why?
- Try node native fs.watch rather than chokidar? OR signal -USR1 to hook in and see what files its watching and why it isn't triggering
- Server: a `killserver` script to sniff out running servers and signal kill them, including runserver script
- Server: runserver: auto run in background w/out having to nohup
- Easier to deploy patches:
- server: git pull js/ directory, possibly other directories, NOT tools/ ; update permissions ; run fuckingtaskrunner
- web: same as above?
- script to ssh into server + web and run the above deploy commands? watch for errors and halt if there's an issue
* - fuckingtaskrunner running out of memory....why?
* - BUG: Have a goblin chasing you while you /suicide while running, hit onEntityCancelledPath w/ no path on entity
* - FIXME: Netcode rework
-- CHECK: Dynamic Handler (outside of page): Is this a thing? If there's an evtid associated w/ it then queue for frame (not always necessary, eg. chat); player.registerHandler ==> wrap this in some way to add event if necessary
-- CHECK: requests -- Do these need to be queued?
-- CHECK: Zone out / respawn into a different page, where the page indices are the same where you were before; could this be an issue for handling events from stale pages? Stale pages could probably also send an area id
- Requests/DynamicHandlers need frameId
- BUG: Died (from buff deactivating -- 44dmg), handled EVT_DIED on character (removed self from area) then NETSERIALIZE for self (same area)
- Not sure if we handled respawn, but it didn't seem like it -- if we got respawn then maybe we respawned -> handled evt_died afterwards (stale page? bad cursor?) -> didn't receive EVT_ADD_ENTITY?
1) Receive respawn (on same page) (frameId: 5)
2) Receive DeathSickness (frameId: 6)
3) Receive PageEvents:
- EVT_DAMAGED (frameId: 1)
- EVT_NETSERIALIZE (frameId: 2)
- EVT_DIED (frameId: 3)
- EVT_REGENERATE (frameId: 4)
4) Receive FRAME_END
- NOTE: I *think* we're handling everything in order, just that we haven't created the character yet. Check where we're creating character, maybe its worth it to createCHaracter sooner? (on respawn)
- 1) Need to halt processingQueue part way through (after respawn/zone/etc.) (probably done already in client/game?); buffer remaining events, and process leftover queue; NOTE: Need to purge remaining stale page events that happen AFTER respawn/zone/etc.
- TODO: (later) ALL messages need to be handled in order, and possibly together. This includes zone/respawn stuff (ie. handle stale pages, then zone/respawn, then current page events starting from cursor when zoned/respawned there)
1) Respawn: use frameEvt on client to purge remaining pageEvents
2) Respawn should include page events cursor; NOTE: if we're purging the same page events that we're loading again, we can splice out the events between frameEvt and cursorPoint
- Can we get away w/ marking all events after frameEvt invalid?
- NOTE: We probably want this for teleport/zone-out as well
3) Respawn is received BEFORE pageEvents, but processed in the same queue; so we probably receive pageEvents from new pages that we haven't loaded yet. Need to check for unexpected pages and store them somewhere else until we reach an event that makes them valid (eg. zone, respawn, teleport). In case we receive multiple events (eg. respawn -> immediately teleport from cleric bringing you back) that change our pages unexpectedly, its probably better to do this during processing time rather than before
- 1) Process some page shiz
2) Process respawn
- new pages: look through queued msg list (NOTE: these haven't been added to frameEvents because unexpected page); add events from this frameEvt point forwards
- old pages: go through frameEvents and remove anything from page from this point forwards
3) Process some more page shiz
4) Process teleport
- old pages: go through frameEvents, remove events from this point forwards
- new pages: (NOTE: Possibly ones we had just removed from respawn) go through queued msg list (still held here) and add back necessary events from this point
5) Process more events
-- DOCS for NetCode stuff
- FIXME: Get rid of finishedRespawning (see scripts/game.js); need to add entity to page within respawned, or move that to part of respawning
- FIXME: Manually deleting a file doesn't trigger fuckingtaskrunner to rebuild on next init
- FIXME: Look into server/player.js changedPages -- if we add the same stale page multiple times; at least assert this or something
* - Start smoke tests again & run continuously
- Cleanup bots old debug -> new debugger protocol
- allow admin/commands; run commands through smokes (buffs, suicide, give_item + wear/drop/unwear)
- chat
- have bots run around aimlessly and randomly kill anything in sight
- Connect online? (for more realistic results/lag)
- More abstracted test script for bots; to take options or JSON that describes behavior of bots (zoning, attacking, running around, etc.), movement areas, waypoints, exploration, etc.
- FIXME: Bot dying breaks responding to some orders?
* - Client error -- halt game
- Fix always send error report (sometimes doesn't send)
- Setup dumps to dump *everything*; including serverHandler stuff
- "Gee ghad, Brain! We seem to have broken the game"
- Unsupported browsers:
- Edge: "Stop trying to make edge happen, its never going to happen!"
- fix DEBUGGER in bot: if we call DEBUGGER we force wait until inspector connects, and cannot kill the bot until we connect AND continue/close the inspector
- Manually kill test: also kill debugger?
* - Client error -- halt game
- Synchronous blocking call?
* - BUG: Player 2 zones away from Player 1's PVS, NetSerializes some changes, zones back to Player 1's PVS (eg. health change, etc.)
- What do we send? If its minimal we could just include it all in _character; perhaps that's what we're already doing?
- We hold onto entities once they've left our PVS, even if they die/dc/zone out, so we need to find a way to be smart about removing these eventually. Probably worth it to just destroy them though (same as what we do when we witness them dying or leaving the area)
- Fix runserver settings (had some old node settings, and node vs. nodejs?)
- ErrorReport
- Check if we have the commit locally first, otherwise tell the user we don't have that commit
- Display actual error message
- FIXME: serverHandler remove test assert
* - Entity dies: fade out (effects/filter) + animation; Idle animation
* - Entities roaming around
* - BUG: Player hits max level and levels up again -- should stop gaining XP at max level
* - God Mode
* - FXMgr: Conditions (new sound stops previous instance of sample? limit to X number of instances of sample/bank? limit to X number of sounds on an entity? etc.)
- FIXME: renderer movable highlight: creates new canvas/ctx every time; we could easily cache multiple of these (most recently used) and simply re-use the same cached images
- BUG: Pathing error:
Path: [West 1, ...] first recalibrates; Local recalibration: [West 2, North, ...] so we recalibrate horizontally to the
Local state: {74, 69} (1187, 1104)
Path state: {74, 68} (1185, 1088)
Want recalibration: 3 west, 16 north, 1 east -> 1 west == 0
- FIXME: When zoning out I think you update an area/page which passes an event to another area/page. Its possible to first update area B, then area A where player zones from area A -> B, now B appends EVT_ADDED_ENTITY to eventsBuffer w/ current frameId, and at the end of the frame we reset global frameId to 0 but still have the old evt w/ old frameId. When clients receive this evt in the next frame they'll think it happened later than it did
- FIXME: Need to send frameId w/ NetSerialize in case the page has no other events, then we have nothing to offset from for netSerialize
- CHECK: Does it matter that our netserializes are offset from the page rather than from the area/server? Can we reorder these on the client and get bad ordering?
- Fix volume (too loud w/ snakes attacking you)
- patchserver: inc version #, on connect player confirms version w/ server version before loading
- BUG: Adding long lasting poison to enemies, after death/respawn they still have poison
- BUG: Name level/class not consistent across enemies
- BUG: Click entity as its dying
- BUG: Logged in as shit was going down (not sure what) and recieved PATH_PARTIAL_PROGRESS & PATH_CANCELLED events from entity that wasn't in any of the pages
- Add cursor icons: (eg. https://opengameart.org/content/pointers-part-5)
- Background (w/ moving clouds): (eg. https://bevouliin.com/peaceful-forest-game-background/)
- New icon sprites: (eg. https://opengameart.org/content/recolor-all-the-items , https://opengameart.org/content/496-pixel-art-icons-for-medievalfantasy-rpg , https://opengameart.org/content/painterly-spell-icons-part-1 , https://ravenmore.itch.io/ )
- Game font: https://opengameart.org/content/pixel-fonts-by-pix3m
* - Spritesheet tool: pass tilesheet through imagemagick filtering, resizing; merge tilesheets into 1 tilesheet; Go through maps (or some metadata for maps) to find if any reference this output tilesheet, and update them if necessary (eg. reordering) -- should run ps aux to check if tiled is open and disallow continuing if its open; Autodetect sprite size & rescale % to match existing sprites
- Probably better just to redo the webtool already:
- Tilesheet (autogenerated - layers)
- Folder hierarchy: sort selected images to top of filelist
- "extendedSpriteGroup" and "boundarySprite" no longer mean what they did before, rename these
- For now disable tilesize changing in generated sheets (must be 16x16)
- Perms
- sid (chmod g+s) on parent folder to force setting group of folder on files
- set mode on writeFile in node 0o777
- Scaling spriteGroups: update collisions/etc. (do this in modTilesheets so we can see updates w/out having to save/rebuild)
- Allow the same dependency to show up twice
- sprite/spriteGroup finds its dep by imageSrc (can't do this) -- add procIdx
- Allow easily adding/removing spriteGroup as opposed to dependency
- Dep {
{
// Image Based Dependency
imageSrc,
processing: [
{ "proc 1", previewSrc },
{ "proc 2", previewSrc },
{ "proc 3", previewSrc },
...
]
}
}
- spriteGroup {
// Image Based Sprite Group
imageSrc,
procIdx,
dstX, dstY, // real coordinates
width, height
}
- fs.php on build new temp image: rm previous proc (if exists) as opposed to /resources/temp/imagePrefix*
- Sprite group controls: container for like-objects, drop all similar objects here and then click sort for that group to auto place them together
- This is probably fine as a one time thing, as opposed to saving these groups for later
- Perf: Only redraw when necessary
- Perf: Blitting: Redraw virtual canvas on moving/processing spriteGroup, just erase moved spriteGroups and redraw it
- Perf: We can have 1 interactable for image dep (not necessary for each sprite)
- Scaling generated sheet's tilesize should update dst/tilesize for extracted spriteGroups/sprites (but not image spriteGroups!)
- Store hash of image dep, see if its changed (imageSrcHash), then dirty resource (look for imageSrcHash in resourceBuilder.js)
- Build output preview img to a better place than temp?
- Extraction sprites/spriteGroups in sheet.json are stored twice, once from dep and once on generated sheet. We do this so resouceBuilder can determine if there's new assets, but instead we could build up the dependencies list (as we already do), hash it, and then compare the hash to a stored dep hash on the generated res
- Can we get rid of resource.sprites in favour of resource.spriteGroups[].spriteIsland[].sprite? (possibly even store oldSprites in here)
- We can probably get rid of loadedResource
- Scaling spriteGroups up could cause collision, see if we can move the spriteGroup rather than nuke it
- FIXME: Extraction groups not working
- Fix in saving sprite group
- Fix ResourceBuilder: copy spriteGroup correctly
- Spritesheet editor
- Grid view, manipulate grid size
- Modify options
- Extract tiles from sheet to be (automatically) added into a compiled tileset (may want different tiles to go to different tilesets; may want some grouping part too: plains tileset, keep trees together, keep terrain together)
- Collision, shoot-through, floating, etc. flags
- Select area of tilesheet for imagemagick processing in specific region (probably don't want regions to overlap)
- Select region of tilesheet shows up on preview window; w/ imagemagick conversion?
- On-the-fly imagemagick processing/updating temp file & rendering in preview
- Animated sprites
- Animation editor + preview
- Spritesheet editor
- Options to manipulate sprite settings, and quickly run export-model/bakespritesheet for preview of changes (eg. camera angle, imagemagick settings, textures, etc.) -- NOTE: We're likely going 3D in the near future, so keep this in consideration for what to spend time on
- Map editor (not yet, but ready for this in the near future -- also consider the 3D overhaul + pathfinding (diagonal movement) changes soon w/ map editor)
1) Place sprites (group, eg. tree)
- Should have an icon/image list of assets
2) Paint biome: water, grass, ice, etc.
3) Blend sprites
4) Automatic art placement (foliage/decos/etc.)
- Perhaps prefabs? eg. tree A could have 10x different prefabs of leaves surrounding it; water near edge has 6x different prefabs w/ shells/etc. around it
5) Place spawns
- Terrain editor (part of map editor, but global and allows all spritesheets)
- Define which sprites are terrain
- Define groups of sprites (eg. tree, cliff, multiple sprites that act as 1 in-game sprite)
- Terrain height: going up left -> right? going down top -> bottom? etc.
- Biome properties (checkbox of various properties: water, dessert, forest)
- Density properties (higher level for leaves, etc.)
- Sprites that you're likely to see near other sprites
- The base of a tree spritegroup attracts leave sprites
- Blends
- Put sprites next to each other to describe what's allowed
- Describe sprites which are interchangable (this could include a group of sprites that are interchangeable w/ another group of sprites) eg. a long cliff could have 6 different vertical strips of sprites that are all similar, but some parts are interchangable w/ another
- Paint area properties
NOTE: There should be a default for the level, and then we simply paint offsets to that default
- Biomes/properties
- Water
- Density of "stuff" (eg. forest would be trees/plants, etc.)
- Height
- Maybe instead of height we can draw where a cliff is
- Spawns
- Level of enemies
- NOTE: If blending, heights, etc. don't work for biome then we can use what we've got (eg. ignore height/blend) and highlight red area in editor there
- Right click sprite: d3 style graph/nodes of potential prefabs for that sprite; above that a list of preset styles (eg. right clicking a tree? a bunch of different tree sprites)
- Draw areas for particular zones (like paint, but 0 or 1 / no in-between)
- town (music starts playing, "town discovered" reward)
- dynamic quests
- event trigger (boss)
- fxmgr (snow, etc.)
- Spawns automatically determined at runtime based off area properties
- Should also consider special camps (like Albion online mob camps, bosses, etc.)
- Draw walls (walls connected, randomness, etc.)
- Dungeons: draw tunnels through walls
- Harvesting areas
- Smaller tiles for next-gen movement updates
- Auto-nav creation
- Consider statically dynamic areas too (doors that will open/close)
- Convex regions, way-points
- Rules for art
- Trees are likely to have leaves around it
- Manual placement
- Select tree as a whole rather than individual tiles
- Allow automated updating map afterwards
- Baking the level
- New avatars/spawn rules for area
- New prefabs
- Rules for art changed (less leaves under tree; new trees for this biome, etc.)
- Should be easy enough + isolated so that other people can help out with this
- Updating sheets/etc. should trigger updates in map editor (if open, or starting since last time), eg. resizing/moving sprites in tilesheets
- Keep tile sizes in mind: game tiles are 4x4 (for movement) and may change again. But we don't want to needlessly specify a 16x16 tile in 4*4=16 sprites
- Infinite world; show world edges
- Updating sheets (eg. resize sprites, move sprites): update map automatically (and quickly), including if mapper is already open
- Can probably optimize maps: ground tiles (maps, etc.) and some decos can probably be determined on load for player. Map editor can simply export "grass tiles here"
- Data sheet editing
- NPC, Media, FX, Buffs, Rules, Items
- Icons/Sounds: preview + data editing
- Dialog editing: quests, interaction
- New avatars for talking to: eg. ones from BQ
- New sprites for lower forest area: bear warrior, wolf + wolf den & ruins (from tilesheets); crab + turtles near water & to the right; statues to area on the right
- Include comment metadata w/ tilesheets/spritesheets (authors, copyright license, link, etc.)
- Tilesheet layers -> tilesheet
- Different sizes, need to try to resize accordingly
- Could treat as an autogenerated tilesheet to make use of moving sprite groups around; then dependency needs to reference the layer image as opposed to a sheet, and also needs some processing for resizing
- "built" flag to indicate the tilesheet is built from a bunch of other images in some given directory; dependencies are all of the checked images within the directory
- each dependency has some option for resizing
- similar to autogenerated, allow spriteislands & translating islands
- Tilesheets/spritesheets -> preprocess tonemapping: to help w/ tilesheets from different sources not using the same colours
- Extract colourmap from image:
convert input.png -colors 64 -unique-colors colormap.png
- Remap colours from image:
convert input.png -modulate 100,120,100 +dither -remap colormap.png -set colourspace RGB input.remap.png
NOTES:
- Modulate: seems like it may be worth it to darken/saturate slightly so that we prefer certain colours for specific tilesheets
- Scale: `-filter box -scale 75% -scale 125%` before remap can help w/ simplifying colours if colours are too complex atm
- `-posterize 12` or `-colors 14` before or after could help
- Edge highlighting:
convert biggames.png -scale 500% -define convolve:scale='500,100%' -morphology Convolve 'Log:0x2' -scale 20% biggames.edge.png
NOTE: Scaling up seems to help w/ getting edges, but also speckles the images a little
- Tilesheets/spritesheets create edges: marching cubes & draw edges. Note that in some cases we may already have edges around the sprite, so need to put this into consideration. Also some tiles we may not want edges (eg. grass)
- Background FXMgr: accept events for modifying background (eg. onHit -> change bg-colour of sky and blend-mode multiply, onLevelUp -> different colour)
- Look into performance/GC/optimizations
- https://github.com/thlorenz/v8-perf
- v8 args that allow you to view optimizations, bytecode, GC, etc.
- node args
- Client error -- halt game
- BUG: Player 2 zones away from Player 1's PVS, NetSerializes some changes, zones back to Player 1's PVS (eg. health change, etc.)
- What do we send? If its minimal we could just include it all in _character; perhaps that's what we're already doing?
- BUG: Player 2 zones out of Player 1's PVS, disconnects, logs back in and zones back to Player 1's PVS: player 1 has retained player 2 from earlier, and now has 2 copies of player 2
- We could send all zone-out, d/c, death, etc. across the map
- We could send/store playerID and check if we already have that playerID, then if so remove the previous player (NOTE: This should ONLY happen if the stale copy is out of our PVS) and reload the new copy
- Use machine learning colourize tool to assist w/ spritesheet colouring
- Time sync w/ server: periodically send 1 minute time to users (we're now at 0s on the clock again), then server messages only need to send time mod 1 minute (shorten messages + synced)
- openpgp upgrade to 4.6.2:
Error starting around 4.5.0: TypeError: This readable stream reader has been released and cannot be used to monitor the stream's state
Error starting around 4.0.0: npm install has SyntaxError
- Upgrade to Babel 7 + presets
- Upgrade libs: jquery, lodash, bluebird (or replace?), replace requirejs
- Browser Debugging Snippets
var scaryTiles = [];
for (var x=13; x<=17; ++x) {
for (var y=27; y<=30; ++y) {
if (The.area.isTileOpen({x,y})) { scaryTiles.push({ x, y }); }
}
}
var times = 200;
var doTheDance = () => {
var randTile = scaryTiles[Math.floor(Math.random() * scaryTiles.length)];
The.user.clickedTile(new Tile(randTile.x, randTile.y));
if (--times > 0) setTimeout(doTheDance, 120);
- CHECK: We ALWAYS flush ALL events from everywhere in the same frame (no dynamic handlers after flush before end of frame)
- CHECK: Pathfinding fix works and fixes all cases; also look into if there's a cleaner way or if going through the other codepath will 100% work
- BUG: Players have .isPlayer === false for each other
- If there's a syntax error w/ bot2.js (probably test and server stuff too), no syntax warning is given and shit just won't work
- FIXME: Issue w/ netserializing some stuff on entity, then they zone out of our PVS (locally? remotely?), we've removed them already and then receive page event w/ netserialize on entity
- FIXME: Bot teleports w/ you -- stuck in old position or something? "Bad path -- want to go to..."
- Input to test to indicate increase/decrease error/debug level (pop into debug for minor errors)
- FIXME: Recalibration issue -- player 2 teleports to player 1 then walks; it seems like player 1 may have an incorrect position for player 2 (possibly a position that's outside of their PVS)
- FIXME: Character walks out of PVS, but we don't receive an event of them leaving -- path doesn't continue on to next page (perhaps no path progress?), no removal event from servef (--times > 0) setTimeout(doTheDance, 120);
}
- BUG? What if client / local player zones then receives a delayed packet that we had a server path to remain in the page? (We should only process zoning stuff of adding/removing pages and movables when we receive the zone event from server; also will we teleport/walk back to position?) Something to look into/test later
- On client error: repro immediate environment in node? Could auto spawn a script that has this sandbox from dump, and the code the user was about to run
const vm = require('vm');
const sandbox = { x: 2 };
vm.createContext(sandbox); // Contextify the sandbox.
const code = 'x += 40; var y = 17;';
// `x` and `y` are global variables in the sandboxed environment.
// Initially, x has the value 2 because that is the value of sandbox.x.
vm.runInContext(code, sandbox);
console.log(sandbox.x); // 42
console.log(sandbox.y); // 17
====== PATHFINDING SYSTEM
- PRIORITY
- FIXME
- Fix delayed path coming in after dying/respawning (player + npc?)
- Cleanup rework stuff (old pathfinding stuff still exists, path.ptPath, etc.)
- Short paths should be immediate (especially due to delay and recalibrate from moved position -> beginning of path, this would be far slower than just immediate for short path)
- Optimize end point recalibration (click to move somewhere: can use a range about point since we unlikely need exact point; maybe even the whole tile?) -- the larger the distance the higher the endpoint range?
- WARNING: We can only do this in some cases; eg. can't do this when we recalibrate from position to delayed path w/ stale beginning
- Re-path to delayed path: we could re-path to a point along the path that's really far (eg. first walk a one long jump in direction), would using the path as a hint help?
- Initial/End(?) tile weights (distance to edge of tile) only for initial/last tiles??
- OPTIMIZATIONS
- Dynamic collisions and constant updating: keep track of some optimizations for pathfinding (convex regions, HPA*, JPS, etc.) and update as changes come in, OR at runtime as a region becomes used more frequently: eg. user spam clicking, need to keep pathing from position to new position but we create a convex region (room? circle? nav?) and can check if two points are in the same convex area then simply straight-line path. Can also webworker convex region management / creation (mark as stale when collisions come up and they need refinement)
- Cache and re-use high level path, then only need to refine lower level path. Only need to update update nearby part of path, and can sequentially refine the remainder of the path later
- AI chasing: pathfind from previous destination to new destination, then refine in subsequent step (low prior webworker). THe farther away they are the lower the priority. Can use current path as hint for new path
- Minimize path/walk object size
- Store path as: [ startPt, (dist, nextTile/nextPt), (dist, direction/endTileFromStraightLine/endPtFromStraightLine), (dist, direction/endTileFromStraightLine/endPtFromStraightLine) ]
- A* by default, but as we pathfind over a page frequently, start to load in HPA* or JPS stuff (stuff that takes more memory and shouldn't be loaded in memory constantly); might need to update or rebuild HPA* or JPS or other augmentations because of dynamic collisions. Or even keep a list of dynamic collisions, things that are different from the static for that page, then apply those changes when you load in HPA*. This helps speed up pages that are in use
- Could store all movement operations in 1 single gigantic array that's all processed in a webworker, all at once (cache coherency/etc.)
- Includes: { position/leftover/delta, path }
- Peer-to-peer: users could send "I am here, moving here" messages to both server AND other players in nearby area
- User has full map (load pages from indexdb)
- Server feeds changes from default (eg. broken walls, open doors, etc.)
- Server could blindly trust user paths, and check at runtime for collision; or webworker for validating path
- neighbours[neighbourHash] can probably optimize by using an array of array of bitmasks? largeBlockRegions[smallBlockRegions[bitmasks]] masks whether or not neighbour exists, then we can neighbours[neighbourHash] to fetch actual neighbour; could even do a non-guaranteed first-pass check for faster results
- pathfinding.movables needs garbage collection
- multiple endpoints
- A* iteration: checking neighbours on tile, we can fetch collision mask (or convex regions) and queue multiple neighbours that we know have an open straight path
- later: HPA*/Quadtree/JPS/Convex regions
- "Hierarchical Dynamic Pathfinding for Large Voxel Worlds" GDC18
- Quadtree https://www.youtube.com/watch?v=sn6P7xCTvvc
- Can add waypoints and portals as highest level graph (for long paths) if necessary
- Can sequentially calculate path across multiple frames; pass unrefined path to clients if necessary, clients can either determine OR shouldn't have to render character yet (out of view)
- Can batch spatially nearby paths together to be calculated at the same time: fetch same collisions/etc., then calculate these paths, then move on to next path batch
- Can use JPS in pages where it makes more sense (eg. maze-like dungeons, tight corridors, etc.)
- Waypoint graph: distances to adjacent nodes; helps us first pass decide which way to go
- Allow refinement + smoothing
- Tiled path (eg. interactable with tiles as goto points)
- Nuke (or hide) unused old tile search routines (comment out?)
- More accurate diagonal cost: sqrt(2) ~ 1.4; 1.4 * 5 == 7; use cardinal direction as distance 5 and diagonal direction as distance 7
- Server replacing path for movable: client cancelPath (find path to cancel point) -> receive follow-up path. Can we predict incoming path to avoid unnecessary cancelPath handling?
- Server trust user path; clients check for collision at runtime (ran into a wall? cancelPath OR look for another route until we receive update from server). This also helps for dynamic collisions
- Server use client path as a hint for its own path? This may be necessary if we want to mimic user path (eg. avoiding traps, etc.)
- Webworker "go to random tile" -- also fix this since you could pick an open tile that's impossible to walk to or REALLY far
- Optimize finding cheapestWeightClass (frontOfObject and get rid of decimals eg. turnWeight? More clever method since constantly updating array sucks?)
- Optimize first pass recalibration attempt (without worker)
- Optimize communication w/ worker (eg. path.walks[].walked unnecessary. In fact we could send something to parse and build path on receive:
"13132_232_116"
1 success
3 walks
walk 0:
direction 1
distance 32
walk 1:
direction 2
distance 32
walk 2:
direction 1
distance 16
- Optimize target "safe" area where we don't need to update path until target moves outside safe area. That safe area may need to narrow down as we get closer to the target
PathPlanner.refinePath(path, options)
- Path can come in as any of these states:
{ startTile/Pt, endTile/Pt } -- build actual path
{ start/end, partial path } -- HPA* path that needs to be sequentially fleshed out, OR refined at beginning stages
{ start/end, tiled path } -- path finished but needs refining (down to points) or smoothing
{ start/end, stale path, new end point } -- recycle same path when we know the destination is close to the previous destination
- Options describe what sort of refinement we're looking for
- Sequentially building path (HPA*)
- Tiles -> Points
- Path smoothing
- New end point / start point (user spam clicking, AI chasing)
- Webworker
- RefinePath creates job and either has callback or frame update checks if job has finished then sets path
- Might need to set current path as stale when we pend a new one, or otherwise nuke current path
- Use 1 (or more) master workers that are constantly running, and we send messages with job requests (path refinements), and receive messages back
- On startup create master webworker and send area collision info; on collision changes send to webworker
- Returned path either needs callback OR identifier for movableID to set path to
- Incomplete (in progress) paths: full path is complete as lower res (higher level graph), but first xx% of path is higher res (lower level graph) so we can immediately begin executing path while refining remainder of path sequentially)
- Server delay paths? If we don't have the path fleshed out yet (start/end point, but not created yet) simply accumulate path delta and spend when we have the path
- Beef up smokes: Constantly clicking around tiles that we want + constantly spawning/despawning enemies/items/interactables (or teleporting) so that preferences change and bots keep moving all over the place
Need a map specifically for this type of soak
XXXX....
XXXX....
XXXX....
XXXX*...
.*......
........
........
........
- Volume on entities?
- Need to check certain points on collision vol depending on direction: moving NORTHEAST? Check NW/NE/SE points on collision vol