Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
NonSpicyBurrito committed Oct 30, 2023
0 parents commit 4ea3478
Show file tree
Hide file tree
Showing 18 changed files with 12,300 additions and 0 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Deploy

on:
push:
branches:
- master

workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- uses: actions/setup-node@v2
with:
node-version: '16'
cache: 'npm'

- run: npm ci
- run: npm run docs:build

- uses: DevOpenWRT-Router/github-action-push-to-another-repository@main
env:
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB_WIKI_DEPLOY }}
with:
source-directory: 'docs/.vuepress/dist'
target-directory: 'dist/skin-specs'
destination-github-username: 'Sonolus'
destination-repository-name: 'wiki'
user-email: 'action@github.com'
target-branch: 'develop'
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.vscode/
node_modules/
docs/.vuepress/.cache/
docs/.vuepress/.temp/
docs/.vuepress/dist/
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 NonSpicyBurrito

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
7 changes: 7 additions & 0 deletions docs/.vuepress/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { bootstrap } from 'sonolus-wiki-theme'

export default bootstrap({
base: '/skin-specs/',

prism: ['ts', 'json'],
})
108 changes: 108 additions & 0 deletions docs/essentials/skin-sprite-name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Skin Sprite Name

While you can use any arbitrary string for skin sprite name, there are standardized skin sprite names that every skin is required to implement.

This requirement allows skins to be usable across different engines, and engines to be playable with other skins.

## Standardized Names

| Name | Resizing |
| ------------------------------------------- | ---------- |
| `#NOTE_HEAD_NEUTRAL` | |
| `#NOTE_HEAD_RED` | |
| `#NOTE_HEAD_GREEN` | |
| `#NOTE_HEAD_BLUE` | |
| `#NOTE_HEAD_YELLOW` | |
| `#NOTE_HEAD_PURPLE` | |
| `#NOTE_HEAD_CYAN` | |
| `#NOTE_TICK_NEUTRAL` | |
| `#NOTE_TICK_RED` | |
| `#NOTE_TICK_GREEN` | |
| `#NOTE_TICK_BLUE` | |
| `#NOTE_TICK_YELLOW` | |
| `#NOTE_TICK_PURPLE` | |
| `#NOTE_TICK_CYAN` | |
| `#NOTE_TAIL_NEUTRAL` | |
| `#NOTE_TAIL_RED` | |
| `#NOTE_TAIL_GREEN` | |
| `#NOTE_TAIL_BLUE` | |
| `#NOTE_TAIL_YELLOW` | |
| `#NOTE_TAIL_PURPLE` | |
| `#NOTE_TAIL_CYAN` | |
| `#NOTE_CONNECTION_NEUTRAL` | Vertical |
| `#NOTE_CONNECTION_RED` | Vertical |
| `#NOTE_CONNECTION_GREEN` | Vertical |
| `#NOTE_CONNECTION_BLUE` | Vertical |
| `#NOTE_CONNECTION_YELLOW` | Vertical |
| `#NOTE_CONNECTION_PURPLE` | Vertical |
| `#NOTE_CONNECTION_CYAN` | Vertical |
| `#NOTE_CONNECTION_NEUTRAL_SEAMLESS` | Vertical |
| `#NOTE_CONNECTION_RED_SEAMLESS` | Vertical |
| `#NOTE_CONNECTION_GREEN_SEAMLESS` | Vertical |
| `#NOTE_CONNECTION_BLUE_SEAMLESS` | Vertical |
| `#NOTE_CONNECTION_YELLOW_SEAMLESS` | Vertical |
| `#NOTE_CONNECTION_PURPLE_SEAMLESS` | Vertical |
| `#NOTE_CONNECTION_CYAN_SEAMLESS` | Vertical |
| `#SIMULTANEOUS_CONNECTION_NEUTRAL` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_RED` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_GREEN` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_BLUE` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_YELLOW` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_PURPLE` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_CYAN` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_NEUTRAL_SEAMLESS` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_RED_SEAMLESS` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_GREEN_SEAMLESS` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_BLUE_SEAMLESS` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_YELLOW_SEAMLESS` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_PURPLE_SEAMLESS` | Horizontal |
| `#SIMULTANEOUS_CONNECTION_CYAN_SEAMLESS` | Horizontal |
| `#DIRECTIONAL_MARKER_NEUTRAL` | |
| `#DIRECTIONAL_MARKER_RED` | |
| `#DIRECTIONAL_MARKER_GREEN` | |
| `#DIRECTIONAL_MARKER_BLUE` | |
| `#DIRECTIONAL_MARKER_YELLOW` | |
| `#DIRECTIONAL_MARKER_PURPLE` | |
| `#DIRECTIONAL_MARKER_CYAN` | |
| `#SIMULTANEOUS_MARKER_NEUTRAL` | |
| `#SIMULTANEOUS_MARKER_RED` | |
| `#SIMULTANEOUS_MARKER_GREEN` | |
| `#SIMULTANEOUS_MARKER_BLUE` | |
| `#SIMULTANEOUS_MARKER_YELLOW` | |
| `#SIMULTANEOUS_MARKER_PURPLE` | |
| `#SIMULTANEOUS_MARKER_CYAN` | |
| `#STAGE_MIDDLE` | Both |
| `#STAGE_LEFT_BORDER` | Vertical |
| `#STAGE_RIGHT_BORDER` | Vertical |
| `#STAGE_TOP_BORDER` | Horizontal |
| `#STAGE_BOTTOM_BORDER` | Horizontal |
| `#STAGE_LEFT_BORDER_SEAMLESS` | Vertical |
| `#STAGE_RIGHT_BORDER_SEAMLESS` | Vertical |
| `#STAGE_TOP_BORDER_SEAMLESS` | Horizontal |
| `#STAGE_BOTTOM_BORDER_SEAMLESS` | Horizontal |
| `#STAGE_TOP_LEFT_CORNER` | |
| `#STAGE_TOP_RIGHT_CORNER` | |
| `#STAGE_BOTTOM_LEFT_CORNER` | |
| `#STAGE_BOTTOM_RIGHT_CORNER` | |
| `#LANE` | Vertical |
| `#LANE_SEAMLESS` | Vertical |
| `#LANE_ALTERNATIVE` | Vertical |
| `#LANE_ALTERNATIVE_SEAMLESS` | Vertical |
| `#JUDGMENT_LINE` | Horizontal |
| `#NOTE_SLOT` | |
| `#STAGE_COVER` | Both |
| `#GRID_NEUTRAL` | Both |
| `#GRID_RED` | Both |
| `#GRID_GREEN` | Both |
| `#GRID_BLUE` | Both |
| `#GRID_YELLOW` | Both |
| `#GRID_PURPLE` | Both |
| `#GRID_CYAN` | Both |

## Resizing

For skin sprites with specified resizing, they are expected to remain presentable when stretch to arbitrary size in resizing directions.

## Seamless

Engines may use the seamless variants of skin sprites to create more complex graphics by joining multiple segments together, thus seamless variants are expected to remain presentable when used in such a manner.
56 changes: 56 additions & 0 deletions docs/essentials/skin-sprite-transform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Skin Sprite Transform

Skin sprite transform provides simple yet powerful way for skin sprite to manipulate its own transform while rendering.

## Transform Expression

Each property output is computed based on its transform expression, which is the sum of all property inputs multiplied by corresponding coefficient.

Take the following example:

```json
{
"x1": {
"x1": 0.1,
"y2": 0.2,
"x3": 0.3,
"y4": 0.4
}
}
```

It will be transformed with the following logic:

```ts
output.x1 = input.x1 * 0.1 + input.y2 * 0.2 + input.x3 * 0.3 + input.y4 * 0.4
```

## Inputs

| Name | Description |
| ---- | ------------------------- |
| `x1` | `x1` received from engine |
| `y1` | `y1` received from engine |
| `x2` | `x2` received from engine |
| `y2` | `y2` received from engine |
| `x3` | `x3` received from engine |
| `y3` | `y3` received from engine |
| `x4` | `x4` received from engine |
| `y4` | `y4` received from engine |

## Identity Transform

The identity transform produces an output equals to the input, and can be used when transforming is not needed:

```json
{
"x1": { "x1": 1 },
"y1": { "y1": 1 },
"x2": { "x2": 1 },
"y2": { "y2": 1 },
"x3": { "x3": 1 },
"y3": { "y3": 1 },
"x4": { "x4": 1 },
"y4": { "y4": 1 }
}
```
8 changes: 8 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Introduction

Specification for Sonolus skins.

The specification includes:

- Overview of a skin and how it works.
- Resources of a skin.
6 changes: 6 additions & 0 deletions docs/locale.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "English (English)",
"lang": "en",
"title": "Skin Specs",
"description": "Specifications for Sonolus skins"
}
13 changes: 13 additions & 0 deletions docs/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Overview

An overview of Sonolus skins.

## Sprites and Texture

A Sonolus skin contains named sprites, which are combined into a texture resource.

Skin data contains information about each sprite and where to locate it in the texture resource, as well as its transform when rendered.

## Engine Import

Engines can import sprites from a skin using their names.
60 changes: 60 additions & 0 deletions docs/resources/skin-data-sprite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Skin Data Sprite

Skin data sprite is used by Sonolus app to drive a skin sprite's rendering.

## Syntax

```ts
type SkinDataSprite = {
name: SkinSpriteName | (string & {})
x: number
y: number
w: number
h: number
transform: SkinDataTransform
}

type SkinDataTransform = Record<`${'x' | 'y'}${1 | 2 | 3 | 4}`, SkinDataExpression>

type SkinDataExpression = Partial<Record<`${'x' | 'y'}${1 | 2 | 3 | 4}`, number>>
```
### `name`
See [Skin Sprite Name](../essentials/skin-sprite-name.md).
### `x`
Sprite's x coordinate within skin texture.
### `y`
Sprite's y coordinate within skin texture.
### `w`
Sprite's width.
### `h`
Sprite's height.
### `transform`
See [Skin Sprite Transform](../essentials/skin-sprite-transform.md).
## Examples
```json
{
"name": "#NOTE_HEAD_RED",
"x": 0,
"y": 0,
"w": 64,
"h": 64,
"transform": {
"x1": { "x1": 1 }
// ...
}
}
```
45 changes: 45 additions & 0 deletions docs/resources/skin-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Skin Data

Skin data is used by Sonolus app to drive a skin's rendering.

## Resource Type

JSON resource.

`.json` is the only supported format, and must also be GZip compressed.

## Syntax

```ts
type SkinData = {
width: number
height: number
interpolation: boolean
sprites: SkinDataSprite[]
}
```
### `width`
Width of skin texture.
### `height`
Height of skin texture.
### `interpolation`
It is recommended to use `false` for pixel art styled skins to preserve crisp edges, and `true` otherwise.
## Examples
```json
{
"width": 2048,
"height": 2048,
"interpolation": true,
"sprites": [
// ...
]
}
```
13 changes: 13 additions & 0 deletions docs/resources/skin-texture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Skin Texture

Skin texture is used by Sonolus app as the texture of the skin.

## Resource Type

Image resource.

`.png` is the recommended format.

## Remarks

It is recommended to have power of two in image dimensions and smaller than 2048x2048.
Loading

0 comments on commit 4ea3478

Please sign in to comment.