Skip to content

Instantly share code, notes, and snippets.

@menduz
Created January 4, 2023 22:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save menduz/c4319d5e6cf14a1dcc0bf3ff2e95aacd to your computer and use it in GitHub Desktop.
Save menduz/c4319d5e6cf14a1dcc0bf3ff2e95aacd to your computer and use it in GitHub Desktop.
Use cases:
- Edition mode, needs component schemas and IDs
```
entity0: {
position: { x y z }
}
```
- If the devs define the component number, libraries may have conflicting numbers
```
CPP TypeID
Mammal
Human
Dog
LAST_Mammal
fun x: Mammal = x.typeId bwteen Mammal and LAST_Mammal
y: Dog
x is Mammal == true
y is Mammal == true
x is Dog == true
```
Invariants:
1. Components have stable string identifiers `packageName::ComponentName`
1. Component numbers are well known and permanent for the same component
1. The resolution of all components from the current scene and from the libraries is stable via convention over configuration
1. It is possible to know a specific component definition and name from its component number, based on the resolution of point 2
1. The list of components **MUST** be resolved at runtime and statically (for edition tools, analyzers, linters).
- +convention over configuration
- -imperative configuration
1. Component numbers **MUST NOT** be stored in "edition mode files"
1. Component numbers **MUST** be hidden to the users in regular conditions
1. Component numbers are resolved by applying a `(CRC32(identifier)+2048)&0xFFFFFFFF` algorithm over that string. This is similar to how the EVM resolves the selectors https://ethereum.stackexchange.com/questions/135205/what-is-a-function-signature-and-function-selector-in-solidity-and-evm-language this 2048 is added to account for the "core" components.
1. Colliding CRC or component names will throw a compilation and runtime errors
## Prior art
1. Compilers assign the class numbers at compile-time. The most common semantic is that it happens at linker level, symbols are defined for each object and the LLVM binds the symbols to the sources to prevent collisions. (TypeID)
1. Unity has a mixture of statically defined class ids and "dynamic-ish" class names for user defined behaviours https://docs.unity3d.com/Manual/ClassIDReference.html
## Component conventions
1. All components are stored in the `./components` folder.
1. One file per component, using an `export default defineComponent({...})` ???????????????
1. The final component name will be `<packageName>::<fileNameWithoutExtension>`.
Yielding a `my-physics::Gravity` for the file `components/Gravity.ts`
1. Component definitions can be used in any engine
1. Users utilize the components via importing a synthetic file
```ts
import Gravity from '~/components'
```
## Component conventions
1. All components are present in the `./components.ts`
1. Only component delcarations are exported in that file, one const per component
1. The final component name will be `<packageName>::<nameOfExportedVar>`.
Yielding a `my-physics::Gravity` for the `export const Gravity = {...}`
```
sdk-commands check-components
> checker.ts `import * as components from './components'`
check(components)
> ts-node checker.ts
```
```
sdk-commands components-schemas
> checker.ts `import * as components from './components'`
check(components)
> ts-node checker.ts
{ ... }
```
## Using components from libraries
```ts
// components.ts
export * from '@sdk/components' // Gravity
export * from '@menduz/physics/components' // Gravity
export const IsEnemy = declareComponent("scene::IsEnemy", { ... })
```
## Using components from libraries
```ts
const components =
libraries.map(_ => ({ [_]: require(`${_}/components`) }))
// mapa de componentes
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment