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 install
to locally install the packages - run
yarn dev
to start the local dev server - Visit
localhost:3000/type/IdeaName
to 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 YourIdeaName
to create all the files. It will automatically organize itself under thechaos
folder, 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.json
file and anindex.tsx
file. You can copy the contents ofscripts/TEMPLATE_IDEA.txt
for theidea.json
andTEMPLATE_INDEX.txt
form 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.json
syntax 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.json
andindex.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.