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:
TypeScript
export class Note extends Archetype {
// ...
import = this.defineImport({
// ...
judgment: { name: EngineArchetypeDataName.Judgment, type: DataType<Judgment> },
accuracy: { name: EngineArchetypeDataName.Accuracy, type: Number },
})
// ...
}
JavaScript
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:
TypeScript
export class Note extends Archetype {
// ...
despawnTime() {
return replay.isReplay
? timeScaleChanges.at(this.targetTime + this.import.accuracy).scaledTime
: this.visualTime.max
}
// ...
}
JavaScript
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:
TypeScript
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)
}
// ...
}
// ...
}
JavaScript
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:
TypeScript
export class Note extends Archetype {
// ...
terminate() {
// ...
if (replay.isReplay && !this.import.judgment) return
// ...
}
// ...
}
JavaScript
export class Note extends Archetype {
// ...
terminate() {
// ...
if (replay.isReplay && !this.import.judgment) return
// ...
}
// ...
}