So recently I’ve been working a lot in the Playground and my module has been getting huge Making for a frustrating dev experience scrolling all over the place trying to find my place.
Naturally, it would make sense to have a Playground “project” with multiple files that’s serialized in a big metadata payload for loading and saving. Alas I came upon this post too late from @RaananWSuggested playground improvements and I’m not sure if there is already something in the works.
Nevertheless, I got to work and have a working example with VSCode like tabs with rename, duplicate, drag, etc. It works with relative imports and npm modules that are published to esm.sh. It can handle existing Playground snippets and the next time they’re saved are “upgraded” to the v2 metadata version including all the files, order, etc.
Here’s the demo, went from a few thousand lines to breaking things up into smaller modules, not complete yet but a good showcase for a large Playground split across now readable and semantic modules:
And I’m currently working in my fork on just the main branch, depends on public feedback and reception if this is fit for roadmapping into BJS Playground core.
Awesome! I’ve been spending some time polishing this to give it a lot of the QOL features of VS Code including:
Definition peeking with cmd/ctrl click
Link/symbol following with local modules
Preserving scroll state while navigating between modules
Additional TS support like decorators
If you had any bigger PGs and felt like giving it a whirl to split into smaller modules let me know what you think, or drop them here and I give it a shot. You can append the hash from the current Playground into the link at Babylon.js Playground
those are some great improvements @knervous . I think they would be really appreciated by the community. One trick to work out is how to store the multiple files in the snippet - comparing to current functionality.
i don’t know if you can draw any inspiration from some documentation pages from a library that I work on. it has multiple tabs for documents. it supports importing directly from babylon modules (that would be an issue on older playgrounds). editing directly affects the playground immediately, so that can be a plus/minus as well: https://brianzinn.github.io/react-babylonjs/examples/physics
short video of switching code tabs and inline editing:
I also have a playground here - you can save snippets. It also supports switching back and forth from Typescript/Javascript and exporting to codesandbox. Getting a bit more into maybe usability, but these playgrounds also have a dark mode! Also, full intellisense support (even in JSX).
Awesome, humbled to get feedback from the creator of react-babylonjs, great project! Very nice design with the code playground and feature for opening the project externally in codesandbox. Can tell you understand all the moving parts and know how to put them together. I will definitely peruse your source. I toyed with the idea of starting from scratch and writing another Playground. I think I’ve spent so long in the BJS one I’ve grown very fond of it and want to just plug in some new pieces (up next going to tackle piping a local dev build of an npm module into a deployed Playground site to iterate on a module being developed for BJS)
As far as getting it to work with the existing snippets server, it currently “just works” by loading any existing snippet by loading it as per usual, but there’s a new schema defined in place of the code field that instead of a string of code is now a json blob with this structure. Any PG saved from PGv2 will save this json blob so it isn’t backwards compatible.
As we’ve seen across the different types of playgrounds there are dozens of ways to approach a project format in a code runner in the web. I have my use cases so I’m going to keep chipping away making this as hardened as possible and hope people have the time to give feedback. If I feel like it’s in a very good spot I might try to put a PR just to start a conversation.
That will be great when you get ready to create a PR. Hopefully the babylon team chimes in to make sure there’s not double work going on to increase chance of accepting PR.
I really can’t take credit for the docs/playground on github - those are mostly community contributions. I have, however, spent more time on docs and playground than the actual project code. It’s very time consuming, but definitely creates much higher adoption and makes using a library more fun to experiment with and share code gists. Looking forward to seeing where your work takes the PG system. I wanted to work on the main playground, too - the team didn’t want to I think complicate it further with third-party libs/JSX.
I think we had this debate internally about improving Playground, in the sense that you mention, but I’m not sure we reached an agreement… I believe there were arguments against it, in favor of keeping the Playground simple and not turning it into a full-fledged project manager… I think we should discuss it again, this time with more information thanks to the work you’ve both done.
I do that a lot with my PG for both my modules and babylonjs. Sometimes though you might get more mileage with npm link, since you don’t need to publish. It’s out of scope with community discussion, but it might help your workflow.
I am converging on a stable branch that I’m going to publish a PR from - I’d say early next week I’ll have a PR open in main that is as concise as possible.
I created a short YT video outlining some of the features here (I am going to follow up on a more advanced use case in my other thread for the 10k+ MSDF nameplate thread with a new npm package I published)
Aha good catch, in my main PG i’ve been working on I do use it so it’s just habit writing it in
If you have some time to try it out it’d be great to get early feedback, check for bugs etc. on the deployed site at https://playgroundv2.vercel.app - you can load existing playgrounds by appending the hashes like in the existing URL. I’ve seen you posting here since quite a ways back and imagine you have some historical use cases so would be great to get some insight into existing PG snippet support.
I think I’m going to comb through the forum history or official examples to come up with a list of “modularized” snippets to have a before and after picture.
wow - that video is really compelling. what’s so cool about your approach is that the simplicity is maintained, but you have extended it for more powerful use cases. Maintaining backwards compatibility is probably the biggest thing. Looking forward to your next video - sounds like you will maybe import a shader?
also, we can do specific imports like your lodash like this - you default to that cdn looks like
import lodash from 'https://esm.sh/lodash@4.17.21'
I wonder if we could tap into that to allow more versions of babylon.js to be loaded? then for reporting issues/breaking changes we could pin to a specific version.
Yes great use case, I updated to be able to parse @version suffixes so we can pin versions of modules that we’re importing. It can be used with @babylonjs/core although importing the whole core package in dynamically in runtime gets a bit wonky, would have to work on optimizing that path.
I’ve also got a “local package development” sync option with Monaco’s code lens. You can sync a directory you’re working from locally and it will pull in that package for types and in the code and will automatically grab the latest version every time the code is run – great for when developing BJS npm modules and iterating quickly in the PG.
I’ll be posting a video updating the status of the shader-object npm package in that thread but in the meantime here is a Playground showing how pinning a version is working:
Super cool, appreciate you guys taking the time to consider this. I am going to take some time and go through all the paths to ensure compatibility and will probably have something up in the next few days.
@Evgeni_Popov@Deltakosh@sebavan Would you guys consider saving the snippet locally when it is manually executed? This would prevent code loss if the main thread enters an infinite loop and disables saving the snippet.This feature was discussed in the past many times as well.
If you agree with this, I believe @knervous would also be on board and could include the feature in this PR. The loading of the last local save could be indicated by a GET parameter (for example, #SNIPPETID#local).
Great idea, can’t remember how many times I accidentally have navigated away from the page or done a Cmd+R and reloaded by accident and lost work. This was an interesting problem because there’s a lot of chicken → egg scenarios that pop up…For example, if you retained a local version on every code change and stored locally, when do you offer the opportunity to prefer that local change over the loaded in saved version on new page load-ins per snippet? Or if they are stored per Playground run, how could we prevent or differentiate an initial PG run when the browser loads the previous saved version without the local changes?
Enter Session Revisions
The idea is to track revision changes per snippet ID (not snippet version, just the ID) and store the last 10 in localStorage per snippet. Serializing is using the already available JSZip to keep storage memory low and options to remove are present. Might need some safety mechanisms for quota exceeding but i’d say most cases this will take an insignificant amount of storage space when compressed.
Here’s a heavier use case:
Been spending time going through all the PG cases and crossing them off the list for compatibility, working hard so should have an update soon!