WAITは指定したフレーム(1/60秒)待つ関数。
VSYNCは前回実行したVSYNCから指定したフレーム(1/60秒)過ぎるまで待つ関数。
と、微妙な動きの違いがあります。
VSYNCが1回も実行されていない場合はどうなるか動作不明(おそらく実行開始時にVSYNCが実行されたように動作する)なので、 VSYNCを使うループ開始の直前で1回 VSYNCを入れておくときれいに動作します。
WAIT, VSYNCを使わずにカウンタ変数を使って実現する場合、メインのループから呼ばれて1フレーム(1/60秒)ごとに1回よばれるようなつくりにすることができ、
音を出して1文字ずつメッセージを表示しながら、他の処理ができるようになります(たとえばメッセージ表示中にNPCが動いたりとか、メッセージに関係ない他の処理とか)
この場合、メインループから1フレームに1回だけ呼ばれて処理するため、そのように動作するようなつくりが必要になります。
メッセージ表示にたとえば2秒(120フレーム)かかるなら、メッセージ表示処理が 120回呼ばれるようになります。
表示開始から何フレーム目か、何文字目まで表示完了しているか、呼び元でもうこの処理を呼び出す必要があるかどうか(全部表示したかどうか)などの変数を元に、処理が1回呼ばれたら何もしないのか、文字表示など何か処理するのかを判断するようになります。
アクションゲームなどで敵が勝手に動くようなしくみも、これと同じような作りになっています。