openapi: 3.1.0 info: title: OuterScout description: |- A toolbox for creating cinematic shots in Outer Wilds With this API you can put multiple cameras on your scene, create keyframes to animate their parameters and transformation, and then record color and depth information to your disk license: name: MIT url: https://github.com/Picalines/outer-scout/blob/master/LICENSE version: 0.1.0 tags: - name: api description: Operations related to API information - name: environment description: Operations related to the general state of Outer Wilds app - name: scene description: Operations related to the scene - name: object description: Operations related to Unity GameObjects - name: camera description: Operations related to cameras - name: animation description: Operations used for animation - name: recording description: Operations related to recorders - name: player description: Operations related to the player paths: /api/version: get: operationId: getApiVersion tags: [api] summary: Gets the API version description: |- Use this operation to check API compatability responses: '200': description: API version returned content: application/json: schema: type: object properties: major: type: integer minor: type: integer patch: type: integer example: major: 0 minor: 1 patch: 0 /api/spec: get: operationId: getApiSpec tags: [api] summary: Gets the API specification description: |- Returns the API specification in the specified type parameters: - name: type in: query required: false schema: type: string enum: [openapi] responses: '200': description: Successful operation content: application/yaml: {} /api/swagger: get: operationId: getApiSwagger tags: [api] summary: Returns the Swagger HTML responses: '200': description: Successful operation content: text/html: {} /environment: get: operationId: getEnvironment tags: [environment] summary: Gets information about general Outer Wilds app state responses: '200': description: Information about general Outer Wilds app state content: application/json: schema: type: object required: [outerWildsScene] additionalProperties: false properties: outerWildsScene: type: string example: SolarSystem /scene: post: operationId: postScene tags: [scene] summary: Creates an OuterScout scene description: |- Scene contains cameras, custom GameObjects and other resources. Use this route to clear previous scene Scene resources are permanently erased when you change the Unity scene (when you go to the main menu) requestBody: description: |- In the request body you define the origin point, that is parented to some Unity GameObject. That's required because Outer Wilds regularly "recenters the universe" to avoid floating point errors, so Unity global coordinates are not practical The scene origin is a GameObject named "scene.origin" content: application/json: schema: type: object additionalProperties: false required: [origin, hidePlayerModel] properties: origin: $ref: '#/components/schemas/Transform' hidePlayerModel: type: boolean examples: villageCampfire: description: The request body creating a scene next to the campfire in the starting village on Timber Hearth value: hidePlayerModel: true origin: parent: "TimberHearth_Body" position: [15.2269516, -43.7520866, 187.071] rotation: [0.5456432, 0.59208554, 0.523036, 0.279538333] scale: [1, 1, 1] responses: '201': $ref: '#/components/responses/plainSuccess' '400': $ref: '#/components/responses/invalidBody' '404': $ref: '#/components/responses/gameObjectNotFound' '503': $ref: '#/components/responses/unavailable' delete: operationId: deleteScene tags: [scene] summary: Deletes the OuterScout scene description: |- Scene resources are permanently erased when you change the Unity scene (when you go to the main menu) responses: '200': $ref: '#/components/responses/plainSuccess' '503': $ref: '#/components/responses/unavailable' /scene/recording: post: operationId: startRecording tags: [recording] summary: Starts recording the scene requestBody: content: application/json: schema: required: [frameRate, startFrame, endFrame] additionalProperties: false properties: frameRate: type: integer minimum: 1 startFrame: type: integer endFrame: type: integer examples: - frameRate: 60 startFrame: 1 endFrame: 180 responses: '201': description: Recording has been started '400': $ref: '#/components/responses/invalidBody' '503': $ref: '#/components/responses/unavailable' /scene/redording/status: get: operationId: getRecordingStatus tags: [recording] summary: Gets current information about the recording responses: '200': description: Returned recording status content: application/json: schema: type: object properties: inProgress: type: boolean description: A flag indicating that the recording of the scene is still in progress startFrame: type: integer endFrame: type: integer currentFrame: type: integer framesRecorded: type: integer minimum: 0 example: inProgress: true startFrame: 1 endFrame: 180 currentFrame: 30 framesRecorded: 29 '503': description: Recording haven't been started /scene/active-camera: get: operationId: getActiveCamera tags: [camera] summary: Gets the current Unity camera responses: '200': description: Returned active camera content: application/json: schema: type: object additionalProperties: false required: [name, camera] properties: name: type: string description: Name of the GameObject containing current Unity camera camera: type: object additionalProperties: false required: [type] properties: type: type: string enum: [unity] perspective: $ref: '#/components/schemas/CameraPerspective' examples: freecam: value: name: FREECAM camera: type: unity perspective: focalLength: 20 sensorSize: [36, 24] lensShift: [0, 0] nearClipPlane: 0.1 farClipPlane: 5000 '503': $ref: '#/components/responses/unavailable' /scene/keyframes: put: operationId: putSceneKeyframes tags: [animation] summary: Sets the keyframes related to the scene description: |- Properties available for animation: time.scale requestBody: content: application/json: schema: $ref: '#/components/schemas/SceneKeyframes' examples: time.scale: description: Animates the Unity Time.timeScale property value: properties: time.scale: keyframes: 1: {value: 1} 10: {value: 2} 170: {value: 2} 180: {value: 1} responses: '200': $ref: '#/components/responses/plainSuccess' '400': $ref: '#/components/responses/invalidBody' '503': $ref: '#/components/responses/unavailable' /objects: post: operationId: postGameObject tags: [object] summary: Creates a custom Unity GameObject description: |- Creates a custom Unity GameObject. The GameObject is owned by the scene and will be destroyed when creating a new OuterScout scene requestBody: description: |- The GameObject will be attached to the origin of the scene if the parent is not declared content: application/json: schema: type: object additionalProperties: false required: [name] properties: name: type: string description: Must be non-empty, cannot contain '/' and cannot start with the "scene." transform: $ref: '#/components/schemas/Transform' example: name: timber_hearth_orbit transform: parent: TimberHearth_Body position: [0, 400, 0] responses: '201': $ref: '#/components/responses/plainSuccess' '400': $ref: '#/components/responses/invalidBody' '404': $ref: '#/components/responses/gameObjectNotFound' '503': $ref: '#/components/responses/unavailable' /objects/{name}: get: operationId: getObject tags: [object] summary: Gets information related to the GameObject description: |- Gets current Transform of the GameObject in the coordinates of the scene Another GameObject will be used as the coordinate center if specified in the query parameters: - $ref: '#/components/parameters/objectName' - name: origin in: query required: false description: |- A GameObject whose transform will be used as the origin schema: type: string default: scene.origin example: TimberHearth_Body responses: '200': description: Returned gameObject information content: application/json: schema: type: object additionalProperties: false required: [name, transform] properties: name: type: string transform: $ref: '#/components/schemas/Transform' examples: playerInitial: description: Player initial transformation (origin=TimberHearth_Body) value: name: Player_Body transform: position: [20.83783, -45.4903259, 185.232925] rotation: [-0.208906114, 0.573324442, 0.7582229, -0.229685858] scale: [1.00000024, 1.00000083, 1.00000048] '404': $ref: '#/components/responses/gameObjectNotFound' '503': $ref: '#/components/responses/unavailable' put: operationId: putObject tags: [object] summary: Sets the specified GameObject fields description: |- Use this to update the desired GameObjects before recording begins parameters: - $ref: '#/components/parameters/objectName' - name: origin in: query required: false description: |- A GameObject whose transform will be used as the origin schema: type: string default: scene.origin example: TimberHearth_Body requestBody: content: application/json: schema: type: object additionalProperties: false properties: transform: $ref: '#/components/schemas/Transform' description: |- New GameObject transformation. Chaning the parent of an object is prohibited Only those components that are in the request body will be changed responses: '200': $ref: '#/components/responses/plainSuccess' '400': $ref: '#/components/responses/invalidBody' '404': $ref: '#/components/responses/gameObjectNotFound' '503': $ref: '#/components/responses/unavailable' /objects/{name}/camera: post: operationId: postCamera tags: [camera] summary: Creates a camera that's used to record a video description: |- You can add only one camera to each object parameters: - $ref: '#/components/parameters/objectName' requestBody: content: application/json: schema: type: object anyOf: - $ref: '#/components/schemas/PerspectiveCamera' - $ref: '#/components/schemas/EquirectangularCamera' examples: mainPerspective: description: Main perspective camera value: type: perspective resolution: width: 1920 height: 1080 gateFit: vertical perspective: focalLength: 40 sensorSize: [36, 24] lensShift: [0, 0] nearClipPlane: 0.1 farClipPlane: 5000 hdri: description: Equirectangular camera used to record HDRI value: type: equirectangular faceResolution: 1024 responses: '201': $ref: '#/components/responses/plainSuccess' '400': $ref: '#/components/responses/invalidBody' '404': $ref: '#/components/responses/gameObjectNotFound' '503': $ref: '#/components/responses/unavailable' get: operationId: getCamera tags: [camera] summary: Gets the camera information description: |- Can be used to get information about Unity cameras parameters: - $ref: '#/components/parameters/objectName' responses: '200': description: Returned camera information content: application/json: schema: type: object additionalProperties: false required: [type] properties: type: type: string enum: [perspective, equirectangular, unity] perspective: $ref: '#/components/schemas/CameraPerspective' '400': $ref: '#/components/responses/invalidBody' '404': $ref: '#/components/responses/cameraNotFound' put: operationId: putCamera tags: [camera] summary: Sets the specified camera fields parameters: - $ref: '#/components/parameters/objectName' requestBody: content: application/json: schema: type: object additionalProperties: false properties: perspective: $ref: '#/components/schemas/CameraPerspective' responses: '200': $ref: '#/components/responses/plainSuccess' '400': $ref: '#/components/responses/invalidBody' '404': $ref: '#/components/responses/cameraNotFound' '503': $ref: '#/components/responses/unavailable' /objects/{name}/keyframes: put: operationId: setObjectKeyframes tags: [animation] summary: Sets the keyframes related to the GameObject parameters: - $ref: '#/components/parameters/objectName' requestBody: content: application/json: schema: type: object additionalProperties: false required: [properties] properties: properties: type: object anyOf: - $ref: '#/components/schemas/TransformKeyframes' - $ref: '#/components/schemas/PerspectiveKeyframes' examples: transform: description: Animates GameObject transformation value: properties: transform.position.x: keyframes: 1: {value: -5} 60: {value: 5} transform.rotation.w: keyframes: 1: {value: 0} 60: {value: 1} transform.scale.y: keyframes: 1: {value: 0.5} 60: {value: 1.5} dollyZoom: description: Creates a dolly zoom effect value: properties: transform.position.z: keyframes: 1: {value: -2} 60: {value: 2} perspective.focalLength: keyframes: 1: {value: 40} 60: {value: 10} responses: '200': $ref: '#/components/responses/plainSuccess' '400': $ref: '#/components/responses/invalidBody' '404': $ref: '#/components/responses/gameObjectNotFound' '503': $ref: '#/components/responses/unavailable' /objects/{name}/recorders: post: operationId: postObjectRecorder tags: [recording] parameters: - $ref: '#/components/parameters/objectName' summary: Creates a GameObject recorder description: |- You can create a GameObject transform recorder to build something based on this data in the 3D editor Recorder types are available for GameObjects: transform requestBody: content: application/json: schema: type: object anyOf: - $ref: '#/components/schemas/ColorTextureRecorder' - $ref: '#/components/schemas/DepthTextureRecorder' - $ref: '#/components/schemas/TransformRecorder' examples: mainCameraColor: description: Recording a video from the camera value: property: camera.renderTexture.color outputPath: "D:\\assets\\color.mp4" format: mp4 timberHearthOrbit: description: Recording Timber Hearth's position relative to the sun value: property: transform outputPath: "D:\\TimberHearth_Body.json" format: json responses: '201': $ref: '#/components/responses/plainSuccess' '400': $ref: '#/components/responses/invalidBody' '404': $ref: '#/components/responses/gameObjectNotFound' '503': $ref: '#/components/responses/unavailable' /objects/{name}/mesh: get: operationId: getObjectMesh tags: [object] summary: Gets a list of mesh assets nested in the GameObject description: |- Gets a list of mesh assets nested in the GameObject. Use this to import planet models into a 3D editor This operation exists because the usual asset tools do not get streamed assets together with the main model parameters: - $ref: '#/components/parameters/objectName' - name: ignorePaths in: query required: false description: |- The list is separated by commas. If the path to the asset contains at least one substring from the list, the asset is skipped schema: type: string default: ":" example: "normals,:" - name: ignoreLayers in: query required: false description: |- The list is separated by commas. If the asset is located on one of the Unity layers from the list, it is skipped schema: type: string default: "" example: "DreamSimulation" - name: caseSensitive in: query required: false schema: type: boolean default: false responses: '200': description: Returned gameObject mesh content: application/json: schema: $ref: '#/components/schemas/GameObjectMesh' '404': $ref: '#/components/responses/gameObjectNotFound' /player/ground-body: get: operationId: getPlayerGroundBody tags: [player] summary: Gets information about the current planet description: |- Gets the name and transformation of the GameObject of the planet on which the player is currently located responses: '200': description: Returned player ground body content: application/json: schema: type: object properties: name: type: string transform: $ref: '#/components/schemas/Transform' examples: timberHearth: description: Information about the Timber Hearth at the beginning of the loop value: name: TimberHearth_Body transform: position: [-20.07576, 46.9629173, 185.391724] rotation: [0.0, 0.9937048, 0.0, 0.112030841] scale: [1, 1, 1] '503': $ref: '#/components/responses/unavailable' /player/sectors: get: operationId: getPlayerSectors tags: [player] summary: Gets a list of sectors where the player is currently located description: |- Planets and other locations are logically divided into sectors in order to efficiently load and unload detailed assets and turn off some logic Some sectors are located inside others (for example, the zero gravity cave in the village). When a player enters a sector, the latter is added to the player's list of sectors, and when it exits, it is deleted. Use this operation to select only the desired part of the planet model in the 3D editor responses: '200': description: Returned player sector list content: application/json: schema: type: object additionalProperties: false required: [sectors] properties: lastEntered: type: string description: The path in the hierarchy of GameObjects to the last entered sector sectors: type: array description: List of sectors player has entered. Last item is the last sector that the player entered items: type: object additionalProperties: false required: [name] properties: name: type: string path: type: string description: A path to sector GameObject in scene hierarchy id: type: string description: Some sectors contain a unique id examples: startingCamp: description: Sector list in the starting camp value: lastEntered: TimberHearth_Body/Sector_TH/Sector_Village/Sector_StartingCamp sectors: - name: Sector_TH - name: Sector_Village - name: Sector_LowerVillage - name: Sector_StartingCamp '503': $ref: '#/components/responses/unavailable' /player/warp: post: operationId: warpPlayer tags: [player] summary: Мoves the player to the desired position on the planet description: |- It is impossible to transfer to some planets by simply changing the player's transformation Use this operation to quickly transfer to the desired planet requestBody: content: application/json: schema: type: object additionalProperties: false required: [groundBody, transform] properties: groundBody: type: string description: Name of ground body to warp to examples: - TimberHearth_Body transform: $ref: '#/components/schemas/Transform' description: Transform local to ground body. Must include only position and rotation responses: '200': $ref: '#/components/responses/plainSuccess' '400': description: Invalid ground body or transform '503': $ref: '#/components/responses/unavailable' components: schemas: Problem: type: object description: Generic object containing the error details required: [type] properties: type: type: string title: type: string detail: type: string Vector2: description: Two numbers defining a vector in 2D space type: array items: type: number minItems: 2 maxItems: 2 examples: - [0, 0] Vector3: description: Three numbers defining a vector in 3D space type: array items: type: number minItems: 3 maxItems: 3 examples: - [0, 0, 0] Quaternion: description: Four numbers defining a rotation in 3D space type: array items: type: number minItems: 4 maxItems: 4 examples: - [0, 0, 0, 1] Transform: description: Object transformation in 3D space type: object additionalProperties: false properties: parent: type: string position: $ref: '#/components/schemas/Vector3' rotation: $ref: '#/components/schemas/Quaternion' scale: $ref: '#/components/schemas/Vector3' examples: - position: [0, 0, 0] rotation: [0, 0, 0, 1] scale: [1, 1, 1] CameraPerspective: description: Properties of PerspectiveCamera type: object additionalProperties: false required: [focalLength, sensorSize, lensShift, nearClipPlane, farClipPlane] properties: focalLength: type: number minimum: 0.00001 sensorSize: $ref: '#/components/schemas/Vector2' lensShift: $ref: '#/components/schemas/Vector2' nearClipPlane: type: number minimum: 0.00001 farClipPlane: type: number minimum: 0.00001 examples: - focalLength: 40 sensorSize: [36, 24] lensShift: [0, 0] nearClipPlane: 0.1 farClipPlane: 5000 PerspectiveCamera: description: Regular camera type: object additionalProperties: false required: [type, resolution, gateFit] properties: type: type: string enum: [perspective] resolution: type: object additionalProperties: false required: [width, height] properties: width: type: integer minimum: 1 height: type: integer minimum: 1 gateFit: type: string enum: [horizontal, vertical] EquirectangularCamera: description: Equirectangular camera used to record 360 color output (can be used for HDRI) type: object additionalProperties: false required: [type, faceResolution] properties: type: type: string enum: [equirectangular] faceResolution: type: integer minimum: 1 GameObjectMesh: type: object additionalProperties: false required: [body, sectors] properties: body: type: object additionalProperties: false required: [name, path, transform] properties: name: type: string path: type: string transform: $ref: '#/components/schemas/Transform' sectors: type: array items: type: object additionalProperties: false required: [path, plainMeshes, streamedMeshes] properties: path: type: string plainMeshes: type: array items: $ref: '#/components/schemas/MeshAsset' streamedMeshes: type: array items: $ref: '#/components/schemas/MeshAsset' MeshAsset: type: object description: |- Object used to describe Mesh asset placed in the Unity scene. There are two types of assets: static and streamed additionalProperties: false required: [path, transform] properties: path: type: string description: |- Means differend thing based on the mesh type If the mesh is static, it's a path to GameObject in a hierarchy If the mesh is streamed, it's a filesystem path to said mesh asset transform: $ref: '#/components/schemas/Transform' Keyframe: description: Property keyframe type: object additionalProperties: false required: [value] properties: value: type: number PropertyKeyframes: type: object additionalProperties: false required: [keyframes] description: Set of keyframes of the property properties: keyframes: patternProperties: "^\\d+$": $ref: '#/components/schemas/Keyframe' SceneKeyframes: type: object additionalProperties: items: $ref: '#/components/schemas/PropertyKeyframes' propertyNames: enum: - time.scale TransformKeyframes: type: object additionalProperties: items: $ref: '#/components/schemas/PropertyKeyframes' propertyNames: enum: - transform.position.x - transform.position.y - transform.position.z - transform.rotation.x - transform.rotation.y - transform.rotation.z - transform.rotation.w - transform.scale.x - transform.scale.y - transform.scale.z PerspectiveKeyframes: type: object additionalProperties: items: $ref: '#/components/schemas/PropertyKeyframes' propertyNames: enum: - camera.perspective.focalLength - camera.perspective.sensorSize.x - camera.perspective.sensorSize.y - camera.perspective.lensShift.x - camera.perspective.lensShift.y - camera.perspective.nearClipPlane - camera.perspective.farClipPlane RenderTextureRecorder: type: object additionalProperties: false required: [outputPath, format] properties: outputPath: type: string description: The path to the file where the video will be recorded format: type: string enum: [mp4] description: Output video format constantRateFactor: type: integer default: 18 minimum: 0 maximum: 63 description: FFmpeg setting that controls the level of video compression externalDocs: url: https://trac.ffmpeg.org/wiki/Encode/H.264#crf ColorTextureRecorder: type: object description: A recorder that records the color output of the camera allOf: - type: object additionalProperties: false required: [property] properties: property: type: string enum: [camera.renderTexture.color] - $ref: '#/components/schemas/RenderTextureRecorder' DepthTextureRecorder: type: object description: A recorder that records the depth output of the camera allOf: - type: object additionalProperties: false required: [property] properties: property: type: string enum: [camera.renderTexture.depth] - $ref: '#/components/schemas/RenderTextureRecorder' TransformRecorder: type: object description: A recorder that records the transformation of an object relative to the origin of the scene additionalProperties: false required: [property, outputPath, format] properties: property: type: string enum: [transform] outputPath: type: string description: The path to the file where the transform will be recorded format: type: string enum: [json] origin: type: string default: scene.origin description: A GameObject whose transform will be used as the origin parameters: objectName: name: name in: path required: true description: Name of a Unity GameObject schema: type: string examples: timberHearth: description: Name of the Timber Hearth planet GameObject value: TimberHearth_Body playerBody: description: Name fo the player body GameObject value: Player_Body responses: plainSuccess: description: Successful operation invalidBody: description: Invalid request body content: application/problem+json: schema: allOf: - $ref: '#/components/schemas/Problem' - type: object properties: lineNumber: type: integer linePosition: type: integer path: type: string unavailable: description: Operation unavailable at the moment content: application/problem+json: schema: $ref: '#/components/schemas/Problem' cameraNotFound: description: Camera was not found content: application/problem+json: schema: $ref: '#/components/schemas/Problem' gameObjectNotFound: description: GameObject was not found content: application/problem+json: schema: $ref: '#/components/schemas/Problem'