Skip to content

Setup

Environment

  • Cargo 1.51+
  • Rust 1.51+
  • Node.js 14+
  • Pnpm 8+

Install

Misakura has many package name, so you can choose one you like:

bash
pnpm install misakura
pnpm install avgjs

Structure

  • my-visual-novel
    • public Static files and misakura scripts files
      • audio
        • music Music files
        • sound Sound effect files
        • voice Characters voice files
      • fonts Font files
      • images
        • background Background images
        • figure Character images
      • scripts Misakura scripts files
      • videos Video files
      • misakura.svg Logo file
    • src TypeScript source code
      • styles
      • index.tsx Loading file of the dom
      • main.ts Entry file of the game
    • src-tauri Rust source code
      • icons Icon files
      • src Rust source code
      • tauri.conf.json Configuration file of the Rust code
      • Cargo.toml Package information
    • package.json Package information
    • index.html HTML template file
    • README.md Readme file
    • .gitignore Git ignore file
    • tsconfig.json TypeScript configuration file

Visual Studio Code Extension

Search for Misakura Script in the Extensions tab of Visual Studio Code.That will get syntax highlighting for Misakura scripts.

extension

Coding

src/main.ts:

typescript
import Misakura from 'misakura'
import * as styles from './styles'

function main() {
  const ctx = new Misakura({ entry: 'complex', styles })

  ctx.start()
  return ctx
}

export default main

src/index.tsx:

tsx
/* @refresh reload */
import { render } from 'solid-js/web'
import './styles/index.css'
import main from './main'

function App() {
  return <>{main()}</>
}

const root = document.getElementById('root')
render(() => <App />, root as HTMLElement)

src-tauri/src/main.rs:

rust
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust and love of Misakura!", name)
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Write Scripts

public/scripts/main.mrs:

mrs
# Main.mrs - Misakura 脚本默认入口文件

# 加载 i18n 国际化文件
# using /locales/ --global

# 加载背景
background /images/background/1.png

# 加载角色
character neri --name '角色名字' --figure /images/figure/neri.png
# Options:
  # -N, --name 设置角色显示名字
  # -F, --figure 设置角色当前使用立绘
  # -V, --voice 设置角色语音文件

# 对话
# 无说话者消息(角色独白),阻塞指令(将暂停程序直至用户点击屏幕)
say '这是一串非常非常非常非常非常非常非常非常非常非常非常非常非常非常非常非常非常非常非常非常非常长的文本'
# 有说话者消息
say 'hi' -S neri
# Options:
  # -S, --speaker 设置该消息的说话者

play /audio/music/1.flac
# 播放背景音乐(循环播放)

# 显示角色立绘
show neri

neri: 这是一个对话测试
# say 指令语法糖, 等同于 say '这是一个对话测试' -S neri
neri: 这也是一个对话测试
: 又是一个段落
# 当上文有设置 speaker 时,下文可无需再次设置 speaker
# 此处的speaker为上面的neri,适当的使用这种语法糖对于脚本的简化是非常重要的

think: 自带的 character ID:⌈think⌋,代表角色独白
think: 适当的在游戏使用独白内容可展示当前角色的心理活动
think: 至于角色独白到底是哪个角色的心理活动,并不需要明确在脚本中指代,这取决于剧情上下文(也就是编写脚本的你决定)
think: 同时,一句话不应太过长。
unknown: 自带的 character ID:⌈unknown⌋,代表未知角色
: "这里有一些需使用转义 \\ 符号才可表示的英文符号:\" \', 因为这些符号已经用在了 Misakura 脚本中,如若不转义将会导致脚本语法错误"


# 切换背景
background /images/background/2.png
show neri
# 切换背景后会清除之前所有显示的角色,因此如果要展示角色的话需再次使用 show 指令
neri: 又出现了!
character neri --figure /images/figure/neri_smile.png
# 再次使用 character 附上相应参数会更新相关角色信息
# 此处更新了角色立绘图片 使其为一个笑脸表情
neri: bye~~

# 隐藏角色立绘
show neri --hide

: 'ending...'