Entries

【夢幻的規則】SuperPause與Pause


老實說這篇文章有點不太想發啊...
因為才剛發完白翼神製作日誌100則的紀念文章
這麼快就要被這篇刷下去真的滿討厭的啊...

最近看到某些文章
真的覺得台灣關於凶惡領域需要有人來認真的寫點甚麼
雖然自己很清楚自己的部落格沒甚麼人看
花了快六個鐘頭撰寫和編輯這篇文章根本只是浪費時間
但總覺得這是自己作為可能是台灣極少數研究過凶惡的製作者
應該做的一些事

由於自己也有一段不短的時間沒有寫類似的東西了,
有可能會有寫錯的地方。
如果有人經過自己的嘗試之後獲得和我不一樣的結果
可以留言在底下和我分享。
如果是文章中有訛誤或是不完善的地方
我會立即更正、
如果留言後發現是自己不小心搞錯了也沒甚麼關係,
透過閱讀我的文章能讓一些想了解的人
發現些甚麼、學到些甚麼,
或者透過這些文章讓我能遇到
能讓自己知識更上一層樓的人
未嘗是件壞事?

如果有著一些相當基本的知識
看完這篇文章除了"會寫"日文俗稱時止無視跟時止解除的東西之外
還會很清楚"知道為什麼"自己要這樣寫。

對於某些有興趣更深入了解的人
這篇文章或多或少會有所幫助。

※SuperPause與Pause是甚麼

SuperPause與Pause是MUGEN提供的兩種特殊"暫停"方式。
暫停在MUGEN中主要的用途
是用於人物使用超必殺技時整體畫面停頓,
強化技能施放時的停頓視覺效果等等。
尤其在Pause期間搭配特效、
作為強調技能施放氣勢來說是相當好用的效果。

由於被成功暫停住的單位也會暫停該單位的State程式碼執行
因此有些人對這兩種Pause動了歪腦筋,
用作凶惡用途來暫時停止對方的某些代碼執行。

因為這一篇主要要講的並非一般作為演出強化的用途
而是作為凶惡相關的一種干涉手段,
因此接下來的內容
只會針對這類特殊用途所可能遇到的情況進行說明。

如果只是作為一般用途的人
看到這邊我建議可以開始自己動手試試
或者是去看MUGEN的Sctrl文件(點我)
我的部落格右下角有連結
雖然版本是1.1的不過大多數的東西都是一樣的
那裏寫得非常非常的清楚。

對於想更進階了解的人
首先要知道MUGEN內部本身是個大黑箱、
因此想試著了解實際內部系統處理的情況
在沒有MUGEN引擎原始碼的情況下,
我們只能透過歸納結論、
來推測最有可能的執行順序和流程。

而本文對於較為深入的部分
便是以現階段所蒐集的資料和實驗結果
所得出最有可能的結論。

※SuperPause與Pause的運作

首先在MUGEN中的每個單位(意思是不管是玩家本身還是Helper都一樣)
都擁有SuperMoveTime和PauseMoveTime這兩個變數
這兩個變數的值分別代表
這個單位能在SuperPause和Pause中的效果行動多少Frame(後面以F來簡稱Frame)
一般在movetime大於零的情況下、
受到對應pause效果就會如同甚麼事都沒有發生一樣的無視。
而每在Pause效果中無視1F暫停效果,對應的movetime就會減少1。
而MoveTime為零的單位就會被凍結住。


而每個單位決定"是否被凍結"的這個狀態有個Flag、
在MUGEN中有特別分配一個記憶體位置來保存它
WinMUGENの十徳ナイフ作者在工具中把這個Flag命名為"isFrozen"
在這裡也沿用這個名字。
每個單位在執行自己的程式的前1F如果isFrozen = 1
這個單位在這1F會被凍結、並且不會執行自身的State內容
如果前1F的isFrozen為零則正常的繼續State相關的運作。
(至於為何是前1F而非當F,後面的補充會提到我下此結論的理由)

而實際上我們也可以透過改對手的這個值、
在不干涉MoveTime的前提下強制凍結對手,
不過因為這部分會使用到隔離相關的手段,
而這部分也非本文章探討的重點,在這裡先不多著墨。

這裡為了節省版面,單舉Pause為例子。(SuperPause也是相似的)

首先,我們先不管場上其他對手,
在這裡先單觀察一個單位Pause與Movetime間的互動是甚麼樣子。

比如說小逝的某個攻擊時的Pause如果寫成這樣:
[State DreamLuz, Sei, Pause]
type = Pause
trigger1 = !time
time = 531
movetime = 31

當這個Statel觸發時
PauseTime就是531、小逝的PauseMoveTime就是31

經過1F PauseTime = 530、逝的MoveTime = 30 isFrozen = 0
(可以行動)

經過2F PauseTime = 529、逝的MoveTime = 29 isFrozen = 0
(可以行動)

經過3F PauseTime = 528、逝的MoveTime = 28 isFrozen = 0
(可以行動)
...
...
經過30F PauseTime = 501、逝的MoveTime = 1 isFrozen = 0
(可以行動)

經過31F PauseTime = 500、逝的MoveTime = 0 isFrozen = 1
(此F仍然可以行動、不過因為MoveTime為零,所以檢查完會改動isFrozen,設為1)

經過32F PauseTime = 499、逝的MoveTime = 0 isFrozen = 1
(被凍結而無法行動)

Pause、MoveTime和角色是否被凍結住的關係就如同上面那樣。

而整個MUGEN系統中的PauseTime是公用的
這意味著四個Player或眾多Helper中有任何單位使用Pause時
全部的單位都會受到Pause的影響而進行類似上列行動與否的判斷
其中MoveTime為零的單位就會在下1F被凍結住。


※SuperPause與Pause效果的無視與解除

從前面的例子我們可以發現
一般情況下只要對應的movetime能大於零
這個單位便可以無視暫停效果自由的行動
因此最簡單的方法便是如此
假設我在小逝的某個State寫下了這個:
[State DreamLuz, Sei, Pause]
type = Pause
trigger1 = !time
time = 531520
movetime = 531520

很明顯的現在我們可以在暫停效果下自由行動了
不過這個狀態下
我們也把對手和所有在場上的其他單位也全部暫停住了
然而許多時候我們並不希望這樣。

於是可能有些聰明人會想說、
"這樣不就好了嗎":
[State DreamLuz, Sei, Pause]
type = Pause
trigger1 = !time
time = 0
movetime = 531520
然而很遺憾的是當這個State觸發時
我們會發現左上角出現類似Set illegal movetime的警告訊息
並且很驚訝的發現小逝執行完後仍然可以被別人的Pause給凍結。

這是因為Pause系列Sctrl在設計上不允許設定比PauseTime還大的MoveTime。
Pause系列的Sctrl在這種數值不正確的情況下
會把MoveTime以預設值0代入來執行。

而很不巧的、本體又沒辦法像Helper一樣
可以很方便的在召喚的時候就賦予SuperMoveTime和PauseMoveTime
那麼,這樣子如果我們還是想在不凍結對手的情況下
賦予本體一個超大值的MoveTime時
我們該怎麼做呢?

還記得前面提到過所有單位的PauseTime是共用的這個特性嗎?
這點其實也意味著我們可以利用較晚執行的Helper
來覆蓋掉先前單位所施放的Pause效果。

因此利用這個特性,我們可以透過這樣
巧妙的讓自己在非Pause狀態中仍然保有MoveTime :

【小逝本體】
;本體進行Pause的同時賦予自己高額的movetime
[State DreamLuz, Sei, Pause]
type = Pause
trigger1 = !time
time = 531520
movetime = 531520

;呼叫一個Helper覆蓋掉上面所賦予的PasueTime
[State DreamIllumination, Helper]
type = Helper
trigger1 = !time
stateno = 531
supermovetime = 2
pausemovetime = 2

【小逝的Helper】
[Statedef 531]

;把PauseTime覆蓋成零
[State Dream Illumination, Pause]
type = Pause
trigger1 = 1
time = 0
movetime = 0
;當下自我消滅
[State Dream Illumination, DestroySelf]
type = DestroySelf
trigger1 = 1


這樣子,小逝就在完全沒有凍結對手的情況下
成功讓自己擁有PauseMoveTime來抵抗對手施放的Pause了
而SuperPause也同樣可以透過這個手段
來進行相對應的MoveTime賦予。

不過要注意的是MoveTime會在進入movetype = H的State時自動歸零
這部分沒有甚麼特別的理由,MUGEN引擎內部運作就是這樣設計的。
所以成功獲得MoveTime以後要當心不要進入Move = H的State了。




※補充:
這部分算是自己更進一步的補充資料。
實際上一般的使用情況不需要在意以下的內容。

前面所提到的"改變isFrozen的檢查"時機點
並不是每個單位執行自身程式後分別執行
而更像是全部單位全部執行完各單位的State之後
再從P1開始一次進行isFrozen檢查並且進行賦值
比較像是 P1State內容→P2State內容 ..... 全部做完後才進行isFrozenSet這樣。

理由是進行前面使用的1F內的時止賦予+時止解除的改動時
並不會讓夾在過程中的P2或者是其他Helper出現isFrozen的變動
而之所以是State執行"之後"而不是"之前"
理由是因為當F的Pause當F就能改動isFrozen的值

至於"isFrozen影響當F的State是否執行"的具體判斷影響點
一直讓我內心抱持疑問
首先、用隔離手段進行isFrozen賦值
似乎會讓被干涉單位"使isFrozen根據movetime與pausetime關係做變動"的機制失效?
雖然當F進行isFrozen竄改的時候
對手當F仍然可以執行State內容這點
代表判斷點有可能是在State執行完了之後
因此使得isFrozen凍結State執行的影響無法在當F出現。

但總覺得......
沒有決定性的證據?

除此之外,
isFrozen在十德上被影響的時機點
和被干涉對手的程式凍結的時機點並不一致
目標的程式會先被暫停之後一小段時間十德上顯示的isFrozen才會變動
而且被干涉目標的Anim此時也還會流暢播放
(雖然對手目標State執行運作早就被凍結了)
直到isFrozen顯示的值改變才會真正連同動畫一起被凍結。
這也意味著除了isFrozen外還有可能有其他Flag也會影響Pause的機制運行。
(當然也很有可能我修改到的根本不是isFrozen而是其他會牽動到他的東西)
這部分之後其實已經開始需要一些
更精巧修改記憶體內數值才能驗證的部分了,
而這部分並不是我特別感興趣想碰的東西,

而且實際上這部分對於內部執行順序的研究
理應以記憶體分析軟體去分析該位址的真實數值
或者是對MUGEN程式片段進行反向工程
同時也不該這麼倚靠類似十德
這種他人客製化的工具產出結果來做為判斷依據
然而因為沒有這麼多興趣跟時間深入調查研究
對於isFrozen這個Flag、
根據目前所能獲得的結果
暫時下了因為執行順序關係使得效果會延遲1F生效的合理假設,
如果有人有興趣而且有空閒時間,
這部分確實是個可以研究的有趣方向。
引用此文章(FC2部落格用戶)
http://piano999.blog.fc2.com/tb.php/388-6602e706

引用

留言

[C204] 受教了

感谢,受教了

發表留言

發表留言
只對管理員顯示

Appendix

自我介紹

Dream Mirror

Author:Dream Mirror
一位喜歡設計演出、
喜愛為心愛的人物改圖、
並製作有趣MUGEN人物的台灣人。

喜歡節奏遊戲中的電子音樂、
曾經玩過和做過StepMania的譜面。
不過已經很久沒碰了。


❀夢境中的孩子們❀
---------------
希拉

追求永生的熾紅術士
(公開中)


---------------
姬法妮

殘留記憶的集合體
(W.I.P.)


---------------
朵慕●克露可

末日魔法使
(??? ~ 狂)

✡Work In Process
進度:31%


---------------
※Private Edit※
愛諾仙特

救贖
(強 ~ 凶)


---------------


(凶~神)
Work In Process


---------------
白翼神

,,Ծ‸Ծ,,
(強~凶)
處女作♡♥
-------------

Twitter

累積人次

ヤマンチュゲーム研究所