A community repository to work on Ideas for the Muse Universe.
Ideas are the fundamental building blocks for your Muse World. Everything you can add or remove to your world is an Idea. They are different than React Components since a single Idea can be constructed from multiple React Components. They are also designed with Muse's builder tools and compilation infrastructure in mind. In the end, your World is simply the set of Ideas you use to tell your Story.
If you want to create your own idea to add to the muse ecosystem for personal use or for one-off projects, you can simply submit a Pull Request with the source for your plugin. If you are looking for a commercial integration or want to keep your idea closed-source, reach out to us on discord and we can get set up on a call.
Join our discord to get in touch https://discord.gg/ADJSj9xtDJ
- Run
yarn installto locally install the packages - run
yarn devto start the local dev server - Visit
localhost:3000/type/IdeaNameto access your idea. For example, to develop the Proximity Picture idea located atsrc/ideas/decorations/ProximityPicture, go tolocalhost:3000/decorations/ProximityPicture
- If you're on mac or linux, you can run
yarn generate YourIdeaNameto create all the files. It will automatically organize itself under thechaosfolder, but feel free to re-organize.
- Find the folder by which to organize your idea inside of
src/ideas. Feel free to make a new folder if none of the types seem to fit what you want to make. Make sure to copy the casing. - Inside that folder, create an
idea.jsonfile and anindex.tsxfile. You can copy the contents ofscripts/TEMPLATE_IDEA.txtfor theidea.jsonandTEMPLATE_INDEX.txtform theindex.tsx
This file should default export the actual react component that will make up your idea. As you can see in every provided example, there is only one export that accepts props matching the defined schema in the idea.json file. From here, the possibilities are endless.
I strongly suggest looking through other idea files to get a sense of how your code should be structured or to copy commonly used setups. Copying in encouraged in this repo!
This file stores the metadata as JSON for the idea you want to upload. We can help you fill this out if need be. The fields are as follows:
predecessor: Autogenerated on publish, not necessary for the PRid: Autogenerated on publish, not necessary for the PRname: Human-readable name for your ideapurpose: Text describing why this idea was created, or what it was set out to accomplish.schema: An array of objects that describe each property for your idea and the type. The name is both what is seen in the builder tools and what the variable name is in your component. The type is an enum, where each corresponds to a different input mechanism. Full list of types listed below.npm_dependencies: Following thepackage.jsonsyntax for dependencies, list out which external npm libraries are to be included in your component. The list of default provided libraries is below.
- position
- rotation
- scale
- image (resource url)
- video (resource url)
- number, float, integer (as of right now no difference in builder tools)
- radius
- audio (resource url)
- gltf (resource url)
- font (resource url)
- string
- color
- boolean
- react
- three.js
- @react-three/fiber
- @react-three/drei
- @react-three/flex
- @react-three/cannon
- spacesvr
- @react-spring/three
There's a lot of weird gotchas when using this system as it is woefully underdeveloped. that's life i guess.
- You can only use files that are at the same level or below the
idea.jsonandindex.tsx. You can't import from sibling directories. - The topmost element you return from the main react component should be a
group, with the appropriate name, and the rest of the props passed onto it. The Muse builder will store some metadata on there, so this part is crucial for your idea to work. - It is very important that you wrap any elements that use async requests in a React
<Suspense />component. - Our builder tools use raycasting to detect when you are selecting, moving, rotating, or scaling your idea. Some elements, such as SkinnedMeshes, don't support raycasting. It's best to add an invisible box mesh surrounding these elements to support raycasting.
- At least for right now, when you specify an idea by id to add it to your muse world, the values will all defualt to
undefined. Make sure you put in some reasonable fallback values for your props or account for it in the UX.