Omoospace Rules
The rules are simple:
-
Set 5 main directories:
SourceFiles
stores source files of the software.Contents
stores digital content in a common format.ExternalData
stores data from external sources.References
stores reference resources (optional).StagedData
stores temporary data (optional).
-
Set
SourceFiles
andContents
subdirectories (optional):- Set subdirectories by process or object in the
SourceFiles
. - Set subdirectories by content type in the
Contents
.
- Set subdirectories by process or object in the
-
Name anything using UpperCamelCase style with most unique name not object type name.
- Name source files with their creation objects as same as their outputs, those creation objects are the Subspaces of entire workspace.
- Write workspace profiles into Omoospace.yml, such as creator profiles, software versions, etc.
A diagram illustrating the structure of omoospace
Omoospace Structure
Subspace
Subspace is a sub-workspace based on a creation object. It can be a directory or a single source file. Subspaces can be nested. For example, an anime series project, each episode is a creation object. Under that object, multiple secondary objects can be set based on the episode’s sequences, and you can continue to split each of those secondary objects. Each object is a sub-workspace of the main workspace. We call those sub-workspaces Subspace, and name them after their objects.
The nested subspaces can generate a tree-like graph that presents the structure of the entire project, as shown in the figure below.
Name source files and directories with their creation objects as subspaces.
Use _
to separate multi-level subspaces in the filename.
The filename ModelA.blend
hints that it is for creating Model A
. The filename FilmA_SQ020_ModelB.blend
hints that it is for creating Model B
of Sequence 010
of Film A
.
You can also create a Subspace Directory to avoid lengthy filename prefixes. To distinguish it from an ordinary directory, a subspace directory must contain a marker file named Subspace.yml
.
|-- SourceFiles
| |-- ModelA.blend
| `-- FilmA
| |-- Subspace.yml # marker
| `-- SQ020
| |-- Subspace.yml # marker
| `-- ModelB.blend
We call those source files and subspace directories Entities of their subspace. As you can imagine, one subspace may have multiple entities to present them.
|-- SourceFiles
| |-- ModelA.blend
| |-- ModelA.zpr
| `-- FilmA
| |-- Subspace.yml # marker
| |-- FilmA.prproj
| |-- SQ020.prproj
| `-- SQ020.blend
SQ020.prproj
and SQ020.blend
are Sequence 010 (SQ020)
entities. Similarly, the directory FilmA
and file FilmA.prproj
are Film A (FilmA)
entities. According to subspace entities, we classify subspaces into two kinds:
- File Subspace has only files to present itself, no directory.
- Directory Subspace has at least one directory to present itself.
Note
The file FilmA_SQ020_ModelB.blend
only contains the Model B
object. FilmA
and SQ020
are just pure concepts. They are Phantom Subspaces.
A subspace route is formed by combining the subspace names from root to leaf.
The multi-level subspaces in FilmA_SQ020_ModelB.blend
form a route from root to leaf: FilmA > SQ020 > ModelB
. We call it Subspace Route.
Suppose the entity subspace nodes contain its parent subspace nodes. They should overlap each other as much as possible, for example:
# No overlap
|-- SourceFiles
| |-- FilmA # FilmA
| | |-- Subspace.yml
| | `-- SQ020_ModelB.blend # SQ020 > ModelB
# `FilmA` is overlapped
|-- SourceFiles
| |-- FilmA # FilmA
| | |-- Subspace.yml
| | `-- FilmA_SQ020_ModelB.blend # FilmA > SQ020 > ModelB
# `FilmA`, `SQ020` are overlapped
|-- SourceFiles
| |-- FilmA_SQ020 # FilmA > SQ020
| | |-- Subspace.yml
| | `-- FilmA_SQ020_ModelB.blend # FilmA > SQ020 > ModelB
All examples' routes are all FilmA > SQ020 > ModelB
.
Note
There are no strict rules of when to use overlapping forms of directory structure. It is all up to the user's decision. Creators should design the directory structure to fit the project needs.
A subspace name should not be pure numbers or versions or autosave.
Numbers, versions, and autosave semantics are not for new objects, so they should not be subspace names. For example, v001
in FilmA_SQ020_ModelB_v001.blend
, is not a new creation object. The file is still for creating ModelB
. The subspace definition defines a subspace as a particular creation object. So v001
is not a subspace.
Write the subspace profile into Subspace.yml.
Besides a marker file, Subspace.yml
is also a subspace profile.
You can create the profile file to any subspace with the route as its filename, not the entire route but the subroute to the parent subspace.
|-- SourceFiles
| |-- FilmA
| | |-- Subspace.yml
| | |-- SQ020.Subspace.yml
| | |-- SQ020_ModelB.Subspace.yml
| | `-- SQ020_ModelB.blend
# SQ020.Subspace.yml
name: Sequence 020
description: The beginning scene of the story.
# SQ020_ModelB.Subspace.yml
name: Model B
description: A 3d model.
SourceFiles
It stores the source files of the software or executable scripts, pipelines, etc.
SourceFiles
stores processes, and Contents
stores results. The former must be opened with specific software, executed by the program, and pre-computed. The latter generally allows cross-software reading without any pre-computation.
For example, I am using Blender's geometry node for procedural modeling. I should place the source file of Blender in SourceFiles
. However, to load the procedural model in Unity, it is necessary to export it as a general format, such as .fbx, and I should place the exported file in Contents
.
Subdirectories by process name (optional)
When a project grows, you may need to separate many source files into directories. Besides the subspace directory, we recommend setting subdirectories by process name.
Some optional process names:
# Film production processes
|-- SourceFiles
| |-- PreProduction
| |-- Production
| `-- PostProduction
# Post-production subprocesses
|-- SourceFiles
| |-- Compositing
| |-- SoundEditing
| `-- VideoEditing
You can add sequence numbers in front.
# 3D modeling processes
|-- SourceFiles
| |-- 001-Modeling
| |-- 002-Texturing
| |-- 003-Rendering
| `-- 004-Shading
You can mix use process directories and subspace directories.
<SeriesTitle> # (Root)
|-- SourceFiles
| |-- PreProduction
| | `-- <ModelName> # (Root) > <ModelName>
| `-- <Episode> # (Root) > <Episode>
| |-- Subspace.yml
| |-- Production
| `-- PostProduction
Process subdirectories should fit your workflow. But be aware of the following rules:
- Pay attention to the naming style. It should be a gerund for the process. For example, not "Models" but "Modeling", not "Scenes" but "SceneAssembling". This way, the Process is emphasized, not the result.
- You can adjust the process subdirectories freely as the project expands.
Put source files without creation object under Void (optional)
Most source files have their object, such as rendering images or exporting a 3D model. However, some source files are not used as the primary process and have no particular object but have storage needs. We put such source files in a unique subspace called Void, which doesn’t need Subspace.yml
.
Note
Any subspaces in Void are also Void Subspace. So if any "Void" apperaed in subspace route, it will be only one "Void" in front of all subspaces.
e.g. Void/RnD_Void_HowToBeat.hip
subspace route should be Void_RnD_HowToBeat
Void subspace can be in a filename prefix or as a directory.
|-- SourceFiles
| |-- BeatingHeart
| | `-- Void_HowToBeat.hip
| |-- Void_RnD_MetaBall.blend
| |-- Void
| | `-- MaNan.hip
Note
Although the source files under void subspace have no creation objects, they still allow outputting. However, their outputs could be more rigorous and necessary but experimental and temporary. For example, Void/HeartBeating.blend
can still render Void_HeartBeating.0001.png
. The prefix Void
indicates the results are experimental.
SourceFiles structure is always dynamic when a project is in progress.
No one knows precisely what to do and how to do their creation work before starting. Plans never keep up with flashing of inspiration. Creation objects constantly change in progress. Although we make a rule for SourceFiles
subdirectories, it's for semantic structure and does not mean subdirectories should be static.
Feel free to organize files in SourceFiles
and follow the inspiration during creation!
Contents
It stores digital content in a common format, whether internal or external, whether a work result or a resource. You should organize all content files here and stick to the rules.
Subdirectories by content type (optional)
Some optional content types:
# For short video production propose
|-- Contents
| |-- Audios
| |-- Dynamics
| |-- Images
| |-- Materials
| |-- Models
| |-- Renders
| `-- Videos
# For film production propose
|-- Contents
| |-- Audios
| |-- Dynamics
| |-- Fonts
| |-- HDAs # Houdini Digital Assets
| |-- Images
| |-- Materials
| |-- Models
| | |-- Characters
| | |-- Nature
| | |-- Props
| | `-- ...
| |-- Presets
| |-- Renders
| |-- Scenes
| |-- ScientificData
| |-- Scripts
| |-- Settings
| |-- Shaders
| `-- Videos
Type subdirectories should fit your workflow. But be aware of the following rules:
- Pay attention to the naming style. It should be the plural of the content type noun.
- To avoid confusion and misplacement, merge similar content types into one.
- It is not recommended to set multi-level subdirectories or add more subdirectories by content type as the project expands.
The output of the source file is named after its source file subspace route.
There is no subspace directory setting in Contents
. But use subspace route as filename prefix to hint the relationship to its source file.
|-- Contents
| `-- Models
| |-- SQ010_BloodCells_RBC.fbx
| `-- SQ010_BloodCells_WBC.fbx
|-- SourceFiles
| `-- SQ010
| |-- Subspace.yml
| `-- BloodCells_RBC.fbx # Subspace route: SQ010 > BloodCells
You can easily guess that SQ010_BloodCells_RBC.fbx
and SQ010_BloodCells_WBC.fbx
come from SQ010/BloodCells.blend
.
In some cases, one content is a collection of multiple files. e.g., a 3d model with textures or an image sequence of render output. Those sub-file names do not necessarily contain route names, as they are always with their root directory, which already hints at its source.
|-- Contents
| `-- Models
| `-- Organs_Heart
| |-- Organs_Heart.fbx
| `-- Textures
| |-- Heart_Roughness.png
| `-- Heart_BaseColor.png
|-- SourceFiles
| `-- Organs.blend
As the example above, the texture filename does not need to have Organs
, because you wouldn't use those textures without the mesh.
However, it does not mean using the entire route name is forbidden for sub-files, or you can name them randomly. Their name must be semantic.
Keep the Contents structure flat and static as much as possible.
In most software, it will lose the link when the imported file changes its name, or someone moves it. The content files, always as IO paths for source files, must be stable. So, Contents
should be centralized, and its structure should be flat and static, which means you should not move content files frequently or make super complex multi-level subdirectories changes often.
Plan the structure at the beginning.
ExternalData
It stores all data files from external sources. The “external” here means that it is created by the creator outside omoospace or not produced within this omoospace. The most common usage of ExternalData
is to store resources from the network.
No need to follow the naming rules; do not set any subdirectories by content type
Just keep its original file structure and naming style. For example:
|-- ExternalData
| |-- www.models.com_CT_Scanner
| | |-- CT_Scanner.fbx
| | `-- tex
| |-- textures_pack-4k
| | |-- wood
| | `-- metal
| |-- MyResources
| | |-- Textures
| | |-- Materials
| | `-- Models
Note
Do not put files in the root directory of ExternalData
; always under the subdirectory.
It is not the only repository for all external data
Contents
and SourceFiles
also store external data. However, compared with ExternalData
, they are stricter. All files need to be categorized and renamed correctly. Meanwhile, ExternalData
is a storage place that allows users to ship data freely.
If you have stored external source data in Contents
| SourceFiles
, it is unnecessary to hold it in ExternalData
again. For example, an HDRI downloaded from PolyHaven could be directly put under Contents
if you rename it to PascalCase style.
Note
Categorizing and renaming are not fun, so storing external source data directly into ExternalData
is recommended unless you can ensure files under Contents
| SourceFiles
are strict to the rules.
Access to own resource library contents by creating soft links in it.
You may have your resource library of 3D assets in a local or network directory (NAS). You usually don't know which asset suits the 3D scene most until you try, like HDRI. Repeating to move resource files from the library to the current working directory for trial isn't enjoyable.
So we prefer to create a soft link to the library in ExternalData
, then you can easily access the assets from the library.
D:
|-- Resouces # My super 3D resource library for everything
| |-- Models
| | |-- Cars
| | |-- Animals
| | |-- Plants
...
It stores omoospace packages
The omoospace package is designed for sharing omoospace data. You store them in ExternalData
.
|-- ExternalData
| |-- BloodCells # Package
| | |-- Package.yml # Package info
| | |-- Contents
| | | `-- Models
| | | `-- RedBooldCells_RBC.fbx
| | `-- SourceFiles
| | `-- RedBooldCells.blend
References
It stores PureRef, Figma, Paper PDF, and Storyboard. Although you are not using them directly, you need to save them. Put them here.
Tip
If it is Figma online, put the link as a file.
StagedData
It stores any software-generated data that the source file can rebuild after deletion, such as temporary files, caches, software bridging files, etc. There is no need to browse StagedData
unless necessary.
There are no rules for its subdirectory structure.
Omoospace.yml
It stores workspace profiles such as creator profiles, software versions, etc.
name: Omoospace's name
description: A brief of this Omoospace (Optional)
creators: # Creator list of this Omoospace
- name: Creator's name
email: Creator's email
role: Creator's role in this Omoospace (Optional)
website: Creator's website (Optional)
softwares: # Software list of this Omoospace
- name: Software's name
version: Software's version
plugins: # Plugins list of this Omoospace (Optional)
- name: Plugin's name
version: Plugin's version
works: # Work list of this Omoospace
- name: Work's name
itmes:
- Work's path under Contents
For example:
name: my project
description: An omoospace for creation works
creators:
- name: MaNan
email: icrdr@abc.com
website:
role: Owner
softwares:
- name: Blender
version: 3.6.4
plugins:
- name: Zbrush
version: 2023.2
plugins:
- name: Substance 3D Painter
version: 9.0.0
plugins:
works:
- name: MyModel
itmes:
- MyModel
Omoospace Package
Inspired by the Unity Package, the omoospace package is designed for sharing omoospace data.
ExternalData acts like a Packages directory of the Unity project that stores data from other omoospaces.
Unity - Manual: Reusing Assets between Projects
The internal structure of the package is part of its source omoospace
<PackageName>
|-- Contents # (Optional)
|-- ExternalData # (Optional)
|-- References # (Optional)
|-- SourceFiles # (Optional)
|-- StagedData # (Optional)
|-- README.md
`-- Package.yml # Package info
# Package.yml
name: Package's name
version: Package's version
description: A brief of this Package (Optional)
creators: # Creator list of this package
- name: Creator's name
email: Creator's email (Optional)
role: Creator's role in this Omoospace (Optional)
website: Creator's website (Optional)
Note
Once you export a package, it has nothing to do with its source omoospace
Comparison with other software project structures
There are some common concepts to help understand.
Omoospace | Unity | Unreal Engine |
---|---|---|
Contents | Assets | Content |
ExternalData | Packages | |
References | ||
SourceFiles | Assets | Source, Content |
StagedData | Temp | Intermediate, Saved, DerivedDataCache |
Omoospace.yml | PorjectSetting | Config |
Q&A
-
Q: Most directory structure solutions of CG work have no distinction between
Contents
andSourceFiles
. Why does omoospace emphasize their differences ?A: This is due to their different purposes of them. The content files, always as an IO path, need stability. So,
Contents
should be centralized, and its structure should be as flat as possible. Meanwhile, the source files, as entries of human operations, need to be accessible. People split their works by processes and objects, which are the best subdirectory rule ofSourceFiles
. Therefore, isolating the source files that store "processes" and the content files that hold "results" is better. -
Q: Why does
Contents
have no subspace directories?The previous answer has explained the different purposes of
Contents
andSourceFiles
. However, theContents
structure should be as flat as possible. But to avoid duplicate names, Subspace Prefixes are used.SourceFiles
, on the other hand, sets up Subspace Directories for ease of finding.