10. Replay
In this chapter, we will implement replay logic of Note.
Judgment and Accuracy
Replay recreates the recorded gameplay in watch mode.
In order to achieve that, we need the judgment and accuracy information:
export class Note extends Archetype {
// ...
import = this.defineImport({
// ...
judgment: { name: EngineArchetypeDataName.Judgment, type: DataType<Judgment> },
accuracy: { name: EngineArchetypeDataName.Accuracy, type: Number },
})
// ...
}
export class Note extends Archetype {
// ...
import = this.defineImport({
// ...
judgment: { name: EngineArchetypeDataName.Judgment, type: Number },
accuracy: { name: EngineArchetypeDataName.Accuracy, type: Number },
})
// ...
}
Despawn Time
We accuracy, we can adjust despawn time accordingly:
export class Note extends Archetype {
// ...
despawnTime() {
return replay.isReplay
? timeScaleChanges.at(this.targetTime + this.import.accuracy).scaledTime
: this.visualTime.max
}
// ...
}
export class Note extends Archetype {
// ...
despawnTime() {
return replay.isReplay
? timeScaleChanges.at(this.targetTime + this.import.accuracy).scaledTime
: this.visualTime.max
}
// ...
}
SFX
Similarly, we can adjust SFX based on both judgment and accuracy:
export class Note extends Archetype {
// ...
preprocess() {
// ...
if (replay.isReplay) {
const hitTime = this.targetTime + this.import.accuracy
switch (this.import.judgment) {
case Judgment.Perfect:
effect.clips.perfect.schedule(hitTime, 0.02)
break
case Judgment.Great:
effect.clips.great.schedule(hitTime, 0.02)
break
case Judgment.Good:
effect.clips.good.schedule(hitTime, 0.02)
break
}
} else {
effect.clips.perfect.schedule(this.targetTime, 0.02)
}
// ...
}
// ...
}
export class Note extends Archetype {
// ...
preprocess() {
// ...
if (replay.isReplay) {
const hitTime = this.targetTime + this.import.accuracy
switch (this.import.judgment) {
case Judgment.Perfect:
effect.clips.perfect.schedule(hitTime, 0.02)
break
case Judgment.Great:
effect.clips.great.schedule(hitTime, 0.02)
break
case Judgment.Good:
effect.clips.good.schedule(hitTime, 0.02)
break
}
} else {
effect.clips.perfect.schedule(this.targetTime, 0.02)
}
// ...
}
// ...
}
Particle Effect
Lastly, we should skip playing particle effect if player did not hit the note:
export class Note extends Archetype {
// ...
terminate() {
// ...
if (replay.isReplay && !this.import.judgment) return
// ...
}
// ...
}
export class Note extends Archetype {
// ...
terminate() {
// ...
if (replay.isReplay && !this.import.judgment) return
// ...
}
// ...
}