aya5 - manual - template ghost


文 version 5 ゴーストテンプレート


ゴーストテンプレートは、 文 version 5を使用して作られたデスクトップマスコットソフトウェア「伺か」用の キャラクタデータ(ゴースト)のテンプレートです。


機能概要
aya_shiori3.dic
version 4 テンプレートからの移行
  -基本
  -細部を移植する
UTF-8辞書を使用する
使い方
  -イベントハンドラ
  -SAORI
  -システム変数
  -インストール済ゴースト名リストのカスタマイズ
  -コミュニケート
  -ランダムトークのチェイン





機能概要

ゴーストテンプレートは以下の機能を提供します。

  • AIトーク(ランダムトーク、チェイントーク)
  • 時報トーク
  • ダブルクリックメニュー、しゃべり頻度調整
  • 頭撫で、胸さわり、顔たたき反応
  • 見切れ・重なり反応
  • 起動/終了などでのトーク(トーク内容が時間帯により変化)
  • ユーザーの名前を覚えさせる
  • コミュニケート
  • きのこ/猫どりふ反応
  • その他各種イベント反応
  • 30分毎に変数情報を自動保存





    aya_shiori3.dic

    テンプレートに含まれる辞書ファイルaya_shiori3.dicは、文をSHIORI/3.0コアとして動作させるための 制御辞書です。

    基本的にこの制御辞書は書き換えないで下さい。 SHIORI/3.0および文に関する知識がある方は、内容を理解の上独自の機能拡張を施すことができると思います。 しかし通常のゴースト開発では、そこまでする必要はまったくありません。





    version 4 テンプレートからの移行


    version 5への移行は強制ではありません。
    version 4のサポートは今後も継続されますので、version 4をそのままお使いいただくこともできます。移行はあなたの必要に応じて行ってください。


    基本

    以下に基本的な移行方法を説明します。
    1. aya.dllをaya5.dllと入れ替えます。

    2. aya_shiori3.dicも入れ替えます。

    3. 基礎設定ファイルaya.txtの名前をaya5.txtに変えます。

    4. descript.txtのshioriエントリをaya5.dllに書き換えます。

    5. aya_string.txtを開き、以下の関数を新しいものに入れ替えます。
      • On_otherghostname
      • On_version

    6. version 5のマニュアルを読んで変更点を把握し、修正を行ないます。
    上の方法では移行前の変数値を引き継ぐことができません。
    引継ぎたい場合は以下のように作業します。
    1. aya.dllをaya5.dllと入れ替えます。

    2. aya5.dllのファイル名をaya.dllに変更します。

    3. aya_shiori3.dicを入れ替えます。

    4. aya_string.txtを開き、以下の関数を新しいものに入れ替えます。
      • On_otherghostname
      • On_version

    5. version 5のマニュアルを読んで変更点を把握し、修正を行ないます。

    細部を移植する

    一概には言えませんが、「version 5のマニュアルを読んで変更点を把握し、修正を行なう」作業はかなり大変です。
    「ゴーストが立ってくれない」といった基本的で大きなミスは比較的簡単にクリアできますが、細部の動作まで以前と完全に同一にするのは難しいかもしれません。

    FAQ

    移植に際してこれまでに実際に発生した問題、発生しやすいと思われる問題を示し、その修正手法を説明しています。
    • 文字列操作関数は注意
      以下の関数を利用している場合はその部分をチェックしてください。
      STRLEN STRSTR SUBSTR REPLACE ERASE INSERT
      これらは以前はバイト単位で動作していました。つまり、半角文字を1、全角文字を2と数えます。
      しかしversion 5ではこの動作は変更されました。
      半角でも全角でも、ひとつの文字は1と数えます。
      例を2つ示します。
      len = STRLEN("ABCディーイー")
      
      lenはversion 4では13ですが、version 5では8です。
      str = SUBSTR("彼女のPCはMacintoshです。", 6, 9)
      
      strはversion 4では "PCはMacin" ですが、version 5では "Macintosh" です。

    • STRLEN、STRSTR、NAMETOVALUE、ARRAYSIZEの「結果を引数として指定した変数へ格納する版」を廃止
      引数2つのSTRLEN、引数4つのSTRSTR、引数2つのNAMETOVALUE、引数2つのARRAYSIZEは廃止されました。 結果を戻値で取得するように書き換えてください。以下は例です。
      // 変更前
      STRLEN("ABC", _i)
      STRSTR("This is a pen.", "is", 0, _str0)
      NAMETOVALUE(result, "var")
      ARRAYSIZE("A,B,C", len)
      
      // 変更後
      _i = STRLEN("ABC")
      _str0 = STRSTR("This is a pen.", "is", 0)
      result = NAMETOVALUE("var")
      len = ARRAYSIZE("A,B,C")
      
    • 関数が返す値に注意
      関数が空の文字列 "" を返した場合、version 4ではこれを「返り値が無かった」と解釈していました。version 5では「空の文字列が返された」と解釈します。

      RandomTalk
      {
          "いい天気ですね。"
          "おなかが空きました。"
          TeaTalk
      }
      
      TeaTalk
      {
          "緑茶は抹茶入りが好きです。"
          "鉄観音は烏龍茶の一種ですけど、飲んだ感じはかなり違いますね。"
          ""
      }
      
      RandomTalkは5種類の文字列を返す可能性があり、その中には空の文字列 "" が含まれています。

      version 4ではこの空文字列は「空だから無し」と解釈して捨ててしまいます。したがって、RandomTalkは空の文字列をのぞいた4種類の文字列のうちいずれかを返します。
      version 5では空の文字列を捨てません。RandomTalkは、空文字列を含む5種類の文字列から返り値を選択します。

      対処方法は場合によって変わってきます。たとえば以下の通りです。

      • 空の文字列を削除する
        最も簡単な解決方法です。
      • 空の文字列でなかったときだけ出力する
        以下はRandomTalkを修正した例です。TeaTalkの出力をいったん変数に入れて、それが空の文字列かどうかをチェックし、空でなければそのまま出力しています。
        RandomTalk
        {
            "いい天気ですね。"
            "おなかが空きました。"
            if (_t = TeaTalk) != ""; _t
        }
        
    • REQUESTLIBを使う場合は注意
      さおりを使用する際にFUNCTIONEX(もしくはSAORI)を使用せず、直接REQUESTLIBで実行している場合は注意が必要です。

      version 4のREQUESTLIBには返り値が存在せず、結果はLIB.HEADERやLIB.VALUE等の関数を利用して取得する仕組みでした。
      これに対し、version 5のREQUESTLIBは結果をそのまま返します。
      LIB.HEADERやLIB.VALUE等は使えません。 version 5において、LIB.*系のシステム関数が使用できるのはFUNCTIONEX/SAORIを使ったときだけです。

    移行に関する情報

  • 基本機能の主な変更点
  • 文屋 - 文Ver4からVer5への移行メモ
  • 文屋 - 文version5のTips

    文屋には文開発者の方々が寄せられたTipsが集積されています。

    *        *        *

    一旦移行できてしまえば、ほとんど以前と変わらない感覚で使用できるはずです。
    version 5で削除されたシステム関数についてもテンプレートがほとんど再現していますので、以前と変わりなく使えます。





    UTF-8辞書を使用する

    デフォルトでは、ゴーストテンプレート辞書の文字コードはShift_JISです。

    実行される環境に関わらず正しい表示にしたい場合や、多国語混在のトークを記述したい場合は、辞書をUTF-8で作成し、以下のように設定の変更を行ってください。
    • 基礎設定ファイルaya5.txtに以下を追記します。
      charset,UTF-8
      




    使い方

    概要を説明しています。
    詳細はテンプレートの構成ファイルを直接参照してください。むしろ、 マジメにここの解説読むよりは辞書を読んでしまったほうが理解が早いと思われます。


    イベントハンドラ

    イベントは「〜が起きた」「〜された」など、ゴーストやその周囲に起きたさまざまな事象や環境変化のことです。イベントが発生した際に 実行を開始する関数をイベントハンドラと呼びます。端的に言えば、ゴースト開発とはイベントハンドラを記述することにほかなりません。

    イベントには多くの種類があります。ここでそれらを逐一解説することはしません。
    以下にリンクを示しますので、どのようなイベントがあるのかを確認してみてください。

  • 本体通知イベント

    本体から通知される基礎的なイベント。最重要。

  • 外部アプリケーション汎用イベント

    外部のアプリケーションから通知されるイベント。

  • きのこイベント

    MATERIA のアクセサリアプリケーション「きのこ」から通知されるイベント。

  • 猫どりふイベント

    MATERIA のアクセサリアプリケーション「猫どりふ」から通知されるイベント。

  • 文内部イベント
    文が独自に通知するイベント。OnAiTalk、On_ID の 2 種類があります。

    OnAiTalk
    いわゆるAIトーク(ランダムトーク)のイベントです。定期的に通知されます。

    On_ID
    SHIORI/3.0 リソース参照系、および本体情報系 ID のリクエストを受信した際に発生するイベントです。
    ID: hwnd ハンドラの記述例を以下に示します。本体側 hwnd を変数 SakuraHwnd に保持しています。

    On_hwnd
    {
        SakuraHwnd = reference0[0]
    }
    

    新しいイベントへの対応方法
    将来 MATERIA 本体や外部アプリケーションが新たなイベントを定義した場合でも、AYAにおいては単にそのイベントの ハンドラを追記するだけで対応できます。
    たとえばあの夢の機能が実装されたなら、以下のように書けばよろしい。

    OnHitThunder
    {
        "\0\_s実体化開始。\e"
    }
    



    SAORI

    SAORI プラグインは、FUNCTIONEX、SAORI 関数で実行することができます。

    第一引数に DLL ファイル名を指定します。文 DLLからの相対パス指定が可能です。第二引数以降が Argument[n] となります。

    使用例を示します。Argument0 に指定した文字列を Windows クリップボードへコピーする SAORI モジュール「textcopy.dll」です。
    (→textcopy.dll 配布先 ClearBrainSystems

    FUNCTIONEX("textcopy.dll", "これをクリップボードへコピー。", 0)
    
    Result は関数の戻り値として取得します。

    _result = FUNCTIONEX("textcopy.dll", "これをクリップボードへコピー。", 1)
    
    Value[n] は SAORI 実行後に変数 valueex? で取得できます(例は省略)。

    FUNCTIONEX と SAORI は機能的にまったく同等です。どちらでも好きなほうを使ってください。

  • 寿命について
    初回の実行直前に load と GET Version 送出が行われます。unload は文のunload直前に行われます。

  • ネットワーク更新開始時の動作について
    ネットワーク更新により SAORI 構成ファイルそのものがアップデートされる可能性が ありますので、すべての load 済 SAORI は OnUpdateReady イベント受信直後に unload されます。 ネットワーク更新中は SAORI は利用できません。




    システム変数

    テンプレートは独自に以下の変数を提供します。

  • year、month、day、weekday
    現在の西暦年、月、日、曜日。
    曜日は0〜6で、0が日曜です。

  • hour、hour12、ampm、minute、second
    現在時(24時間表記)、現在時(12時間表記)、分、秒。

  • systemuptickcount、systemuptime
    OSが起動してからの時間。単位はsystemuptickcountがms、systemuptimeが秒。

  • systemuphour、systemupminute、systemupsecond
    systemuptickcountを時分秒式に読み替えたもの。

  • memoryload
    物理メモリの使用率。単位%。

  • memorytotalphys、memoryavailphys、memorytotalvirtual、memoryavailvirtual
    物理メモリ量、空き物理メモリ量、仮想+物理メモリ量、仮想+物理空きメモリ量。単位キロバイト。

  • username
    ユーザーの名前。初回起動時は "ユーザーさん" 。

  • basewarename
    「伺か」本体の種別名。MATERIA では "embryo" 、SSP では "SSP" 、CROW では "crow" です。
    OnLoad では使用できません(意味のある種別名を取得できません)。

  • aitalkinterval
    AIトーク(OnAiTalkイベント)の発生間隔です。単位秒。デフォルトは 180 (=3 分)。0を与えるとOnAiTalkイベントが発生しなくなります。

  • communicateratio
    コミュニケート開始率。AIトークに占めるコミュニケート開始の割合です。単位 % 。デフォルトは 10 (つまりランダムトーク 10 回のうち 1 回はほかのゴーストへ話しかける)。

  • ghostexlist / ghostexcount
    現在同時に起動しているゴーストの名前を半角カンマ区切りで列挙したリスト、およびそのゴーストの数。
    コミュニケート開始時には、このリストの中から話しかける相手を決めてください。

  • installedghostlist / installedsakuralist / installedkerolist
    インストール済のゴースト名、本体側の名前、kero 側の名前のリスト。半角カンマ区切り。
    ゴースト名とは descript.txt の name エントリ、本体側名前は sakura.name エントリ、kero 側名前は kero.name エントリのことです。
    installedghostlist、installedsakuralist、installedkerolist の要素数は常に同じで、並びも完全に一致しています。 例えば installedghostlist[32] が "陽子&飯綱&千早" であれば、installedsakuraname[32] が "陽子" 、 installedkeroname は "飯綱" になります。

  • uniqueid
    ユニーク ID 。Owned SSTP の認証で使用。

  • sakurahwnd / kerohwnd / sakurablnhwnd / keroblnhwnd
    それぞれの hwnd 。hwnd を要求する SAORI を使う際などに利用します。

  • reference*
    イベントリファレンス(受信側)。*は0〜。
    数値が入る場合も文字列が入る場合もあります。値が半角数値のみで構成されている場合は数値、それ以外では文字列となります。
    例えば OnCommunicate の reference0 は話しかけてきたゴーストの名前ですので通常は文字列となりますが、54 dでは数値になります。

    文字列中のバイト値 1 は半角カンマへ自動的に置換されます。

  • res_reference*
    イベントリファレンス(応答側)。*は0〜。
    このシステム変数に値を代入すると、リクエスト応答に Reference*: ヘッダを返すことが出来ます。
    リクエスト毎に内容がクリアされます ので注意してください。
    主にコミュニケート時において、相手ゴーストの名前を指定するために使用します(res_reference0)。

  • valueex?
    SAORI 実行結果の Value[?]ヘッダの値。

    なお SAORI の Result は FUNCTIONEX / SAORI システム関数の戻り値として得られますので、専用の変数は用意されていません。




    インストール済ゴースト名リストのカスタマイズ

    installedghostlist / installedsakuralist / installedkerolist は、ゴーストが load される際に自動的に構築されます。 構築には時間がかかり、インストールしているゴーストの数が多いほど処理時間は長くなります。
    従って、非常に多くのゴーストをインストールしている場合、パフォーマンスが低いマシンではゴーストの起動が非常に遅くなります。

    この問題を解決するため、リストの最大サイズを指定することができます。

    aya_shiori3.dic の25行目

        #define IGLIST_MAX -1
    
    この数値を取得したい数に変更してください。もしくは以下の数値を指定します。
  • 0でリストを構築しなくなります。
  • -1ですべてのゴーストを取得します。

    たとえば 5 に設定すると、インストールされているすべてのゴーストから5体だけが選ばれ、 installedghostlist、installedsakuralist、installedkerolistが作成されます。
    全ゴーストを巡回する仕組みになっており、次回起動時には前回とは別の 5 体が抽出されます。

    インストール済ゴーストの総数が指定値より少なかった場合はすべてが抽出されます。

    当然ながら起動時間は 0 で最速になります。
    作成するゴーストにおいてこれらのリストを利用しないのであれば、0 にしておくべきです。




    コミュニケート

  • 他のゴーストに話しかける
    各種イベントに応答する際、システム変数res_reference0に話しかける相手ゴーストの名前を代入しておくと、 そのゴーストに話しかけることが出来ます。
    ランダムトークの際だけでなく、どんな状況からでもコミュニケートは開始することができます。

    現在デスクトップ上に存在するゴーストの名前は、On_otherghostnameハンドラで取得することができます。

    具体的な実装例はテンプレートを参照してください。
    テンプレートではOnAiTalkからコミュニケートを開始しています。(通常はランダムトークを開始するが、低率でコミュニケート を開始するようになっています)


  • 話しかけに応答する
    他のゴーストもしくはユーザーから話しかけられると、OnCommunicateイベントが発行されます。
    システム変数 reference0 に話しかけてきたゴーストの名前、reference1に話しかけてきた内容が格納されていますから、これらの内容を参照して 返事を返してください。返事を返すゴーストの名前をres_reference0システム変数に代入します。

    下の例では、奈留からの話しかけであれば、内容を見て返事をしています。 それ以外のゴーストからは話しかけられても「はァ。」と言うだけです。

    OnCommunicate
    {
        if reference0 == "なる" {
            res_reference0 = "なる"
            if "こんにちは" _in_ reference1 {
                "\0はい、こんにちは。\e"
            }
            elseif "天気" _in_ reference1 {
                "\0天気?さあ‥‥。\e"
            }
            else {
                res_reference0=""
                "\0??\e"
            }
        }
        else {
            "\0はァ。\e"
        }
    }
    
    奈留が話しかけてきた内容を解釈できなかった場合は、「??」とだけ発言し、返事を返さないようにしています。

    res_reference0 にゴースト名を代入しない、あるいは明示的に空の文字列を代入した場合は、自分の発言を最後に会話は打ち切りとなります。

    ユーザーからの話しかけでは、reference0にゴースト名でなく"user"が入ります。
    ゴーストへの応答と同様にプログラムしてください。




    ランダムトークのチェイン

    ランダムトークにおいて、ひとつのトークを一度で終わらせず、複数回に分けてトークさせることが出来ます。 これをトークのチェインと呼びます。


  • 開始
    チェインのはじめのトークに「チェインID」を書きます。
    チェインID は、以下のようにトークの後ろに「:chain=チェインID」の書式で付加します。

    RandomTalk
    RandomTalk
    {
        "\0チェインしないふつうのトーク、その1。\e"
        "\0チェインしないふつうのトーク、その2.\e"
        "\0ホワ伊藤の馬鹿。\e:chain=ケンカ"
    }
    
    上の例では、三番目のトークがチェインの開始トークであり、チェインIDは「ケンカ」です。
    これで、「ホワ伊藤の馬鹿。」というトークを皮切りに、「ケンカ」トークのチェイン再生が開始されます。

    チェインはランダムトークからだけでなく、どこからでも開始できます。例えばOnBootトークにチェインIDを付加すれば、ゴーストの起動直後から チェイントークを開始できます。


  • 本体
    チェイントーク「ケンカ」の本体は、以下のように記述します。

    ケンカ
    {{CHAIN
        "\1馬鹿とはなんだ!このうすっぺらのマセ餓鬼がっ!\e"
        "\0何よ8ビットマイコンで動いてるポンコツのくせに!\e"
        "\18ビットで悪いのかよ!\e"
    }}CHAIN
    
    チェインは「チェイン関数」という特殊な書式・動作の関数で書きます。
    チェイン関数の動作はsequentialオプションのついた関数と似ています。ランダムトークのタイミングで、要素を上から順番に出力していきます。

    チェイン関数では、その要素を単純な{ }ではなく、{{CHAIN }}CHAINで囲んでください。


  • チェインの入れ子やフロー制御
    チェイン関数内でも普通の関数と同様に変数やifなどが使えます。チェイン内から別のチェインの再生を開始することも可能ですので、 複雑なチェイントークをプログラムすることができます。

    チェインIDとして「end」を指定すると、チェイン再生はそこで打ち切りとなり、通常のランダムトークモードへ戻ります。

    以下に簡単な例を示しています。

    chain1
    {{CHAIN
        "1"
        "2"
        {
            "3"
            "4:chain=end"
            "5:chain=chain2"
        }
        "6"
    }}CHAIN
    
    このチェイン関数 chain1 は、以下の 3 通りのチェイントークパターンをランダムに再生できます。
    1. "1" → "2" → "3" → "6" → 終了
    2. "1" → "2" → "4" → 終了
    3. "1" → "2" → "5" → 別のチェイントーク chain2 再生開始