Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MomTV Run Submission #1085

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open

MomTV Run Submission #1085

wants to merge 22 commits into from

Conversation

tsa96
Copy link
Member

@tsa96 tsa96 commented Dec 15, 2024

Reworks run submission to use new replay format including significantly refactoring validation logic. I've tested fairly extensively in-game, all working well.

Keen that this is reviewed by game devs, especially @jason-e. Most important thing is run-processor.class.ts which handles validation, and stuff in libs/formats/replay.

Checks

  • !! DONT IGNORE ME !! I have ran nx run db:create-migration <name> and committed the migration if I've made DB schema changes
  • I have included/updated tests where applicable (see Testing)
  • I have followed semantic commit messages e.g. feat: Add foo, chore: Update bar, etc...
  • My branch has a clear history of changes that can be easy to follow when being reviewed commit-by-commit
  • My branch is functionally complete; the only changes to be done will be those potentially requested in code review
  • All changes requested in review have been fixuped into my original commits

@tsa96 tsa96 force-pushed the feat/0.10-run-submission branch from c96e3ed to 6909af4 Compare December 15, 2024 05:04
Copy link
Member

@GordiNoki GordiNoki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I'm not completly sure about the run validation logic so I'll leave it to rio

@tsa96 tsa96 force-pushed the feat/0.10-run-submission branch from 6909af4 to aabd95d Compare December 15, 2024 05:55
Copy link
Member

@jason-e jason-e left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only reviewed run-processor.class.ts based on your suggestion. Let me know if there's anything else I should review.

if (header.gamemode !== session.gamemode)
throw new RunValidationError(ErrorType.BAD_META);

if (!approxEq(header.tickInterval, Tickrates.get(session.gamemode)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tick interval should be exactly the official value I would think

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a matter of float32 vs JavaScript's native doubles, Tickrates should be defined as float32.

On a side note I just realized it's called Tickrates but stores tick intervals (the inverse of tickrate). I think we have a bad habit of using the terms interchangeably in game code too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know there was a nice way to do this with native JS until now, but turns out Math.fround is a thing and does what we're after.

My bad wrt the tickrate/intervals thing, definitely something we should be using precisely, have updated the naming.

const headerRunTime = header.runTime * 1000;

// When the run was started according to replay file
const runStart = header.timestamp - headerRunTime;
Copy link
Member

@jason-e jason-e Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not an issue yet but I wanted to note something interesting to keep in mind: some of our movement code improvements involve stopping a movement tick short of completing the full tick, and in the future (probably coinciding with sub-tick timing in general), the timer will reflect these shortened ticks by ticking less than a full tick of time. This means that the end of run true timestamp minus the start of run true timestamp will likely be slightly more than the run duration. For most runs this will likely never matter, though it could amount to maybe even a few minutes difference for a 10 hour run. If needed, maybe we will add timestamps to RunSplits corresponding to the run start and each checkpoint.

throw new RunValidationError(ErrorType.BAD_TIMESTAMPS);
}

if (checkpointsOrdered) {
for (let i = 1; i < timestamps.length; i++) {
if (timestamps[i].checkpoint <= timestamps[i - 1].checkpoint) {
if (timestamps[i].minorNum <= timestamps[i - 1].minorNum) {
Copy link
Member

@jason-e jason-e Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there also needs to be a check for no duplicate minorNum when checkpointsOrdered === false and checkpointsRequired === false

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate minorNums should never be possible, so I check for them validateSessionTimestamps already. Added a test for the case you give to make sure, which already passes.

throw new RunValidationError(ErrorType.BAD_TIMESTAMPS);
}
// First minorNum is always 1 (a segment start), regardless of track type
if (timestamps[0].minorNum !== 1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is timestamps guaranteed to be ordered at this point, or could it still be out of order depending on network conditions? There's a few places where timestamp elements are accessed according to an assumed order.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will refactor as discussed on Discord, but need to do when more awake (next couple days)

export interface RunSegment {
subsegments: RunSubsegment[];

// Contains an entry for every subsegment the player has reached so far
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should be in front of subsegments (the original C++ has the same error lol)

velocityWhenReached: vec3;
}

export interface RunStats {
Copy link
Member

@jason-e jason-e Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) I can see you've just taken the original C++ class names and prepended "Run" to namespace them better, but it makes this one a little misleading since these stats can apply to not just a whole run but sometimes a segment of a run or a single subsegment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, can use a RunSplits namespace here.


const header = readHeader(buffer);
expect(header).toEqual(expectedHeader);
expect(header.tickInterval).toBeCloseTo(0.01, 5);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tick interval should be exact (making sure to compare float32 to float32 so no wiggle room is needed, not sure how easy/hard this is in JavaScript).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out, way easier than I initially though! Using Math.fround(0.01) instead of 0.01 passes exact equality.

@tsa96
Copy link
Member Author

tsa96 commented Dec 19, 2024

Addressed a couple of rio's things but haven't organised commits yet or addressed other stuff, will do tomorrow

@tsa96 tsa96 force-pushed the feat/0.10-run-submission branch from aabd95d to b529ce2 Compare December 20, 2024 05:47
@tsa96
Copy link
Member Author

tsa96 commented Dec 20, 2024

Addressed everything besides the timestamp ordering stuff which I'll do soon

@tsa96 tsa96 force-pushed the feat/0.10-run-submission branch 3 times, most recently from d42eff3 to 9204e11 Compare December 21, 2024 20:00
Not branding these, too annoying, just doing this for clarity when
parsing replay headers
Writer is just for E2E tests
@tsa96 tsa96 force-pushed the feat/0.10-run-submission branch from 9204e11 to bc89ee4 Compare December 21, 2024 20:38
@tsa96 tsa96 force-pushed the feat/0.10-run-submission branch from bc89ee4 to 77f145d Compare January 5, 2025 00:17
@tsa96 tsa96 force-pushed the feat/0.10-run-submission branch 2 times, most recently from 808b839 to d4a93b5 Compare January 5, 2025 04:27
@tsa96 tsa96 force-pushed the feat/0.10-run-submission branch from d4a93b5 to 03fc68a Compare January 5, 2025 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants