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

Add Music Timeline (Global Timeline) to Open Hexagon to enhance rhythm aspects #346

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

Morxemplum
Copy link
Collaborator

Closes #335.

I've managed to implement the music timeline. Turns out that the timeline class that the pattern, event, and custom timelines use are based on timeline2, which is built to function as a relative timeline. So I had to actually create a brand new class that represents a global timeline. This was the trickiest part because there are things that the global timeline class does differently from timeline2. The global timeline:

  • Uses integers for timepoints instead of Chrono timepoints for simplicity.
  • Doesn't have any waiting functions, because waiting functions don't serve a purpose in a global timeline.
  • Uses a map to keep track of actions instead of a vector. The map contains vector values to allow for multiple events at the same time.
  • Can account for any abrupt changes in the time by clearing the previous timepoint
  • Doesn't remove events after executing them, allowing for repeated execution.

The global timeline is used to create the music timeline, and it functions almost like your typical timeline. The main difference comes in when you have to time your events. Instead of a wait function, you have to specify a specific time when the event will happen. If you want to use relative transformations, you can use simple math to recreate a waiting function.

There is now a "music pointer", which relays the current time that the song is playing. The music pointer will follow along with the music pitch and music changes. The music pointer works off milliseconds, rather than frame time (to account for precision in music). Due to an OpenAL limitation, the music pointer updates every 20ms. If precision is really important, I will go back and try to redo this pointer to work off the game logic instead of the SFML logic.

Speaking of Lua functions, here are all the new Lua functions that this pull request adds:

  • a_getMusicSeconds: Grabs the value of the music pointer in seconds
  • a_getMusicMilliseconds: Grabs the value of the music pointer in milliseconds. Unlike the previous function, this returns an integer in case you're worried about floating-point error.
  • a_evalTo: Puts a Lua block of code onto the music timeline at a specific timestamp in seconds.
  • a_evalToMs: Puts a Lua block of code onto the music timeline at a specific timestamp in milliseconds.
  • a_clearTimepoint: Removes all events from that specific time point in the music timeline.
  • a_clearTimepointMs: Millisecond variant.
  • a_clear: Removes all events from the music timeline.

There were a few more that I added than originally intended. I wanted to add clearing specifically for a timepoint for quality of life, and I added millisecond variants to ensure precision.

@vittorioromeo
Copy link
Owner

If I am understanding correctly, the music timeline might change behavior depending on the random music segment that's being played, for levels with multiple music segments. Is that right?

If so, we need to devise a strategy for replay synchronization first, as replays do not currently store the music segment as it hasn't been significant to gameplay until now.

@Morxemplum
Copy link
Collaborator Author

You do have a fair point. We probably should make replays hold music segment information. This is also something that has been heavily requested by players as well.

@Morxemplum
Copy link
Collaborator Author

I have no idea what is causing that weird segfault and is causing the GitHub Actions to fail. This happened since the first push onto the branch and I have no reason to believe that a simple music pointer and music timeline can lead to a segfault with a replay test case. The two seem completely unrelated and I wish the Actions were more verbose with the error information so I can understand what is causing it.

@fentras
Copy link

fentras commented Feb 5, 2022

Merging with latest master (as of writing this comment) fixes the problem.

2022-02-05.20-51-24.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make a Timeline that is controlled specifically by a level's music
3 participants