Skip to content

Datapack export improvements #84

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

Merged
merged 16 commits into from
Sep 10, 2019
Merged

Datapack export improvements #84

merged 16 commits into from
Sep 10, 2019

Conversation

Bentroen
Copy link
Member

@Bentroen Bentroen commented Sep 7, 2019

The changes proposed in this PR bring many new possibilities to the data pack export feature, optimizing the playback to run only a few commands at a time, allowing songs that were previously incompatible to be played in Minecraft, allowing more flexibility in regard to how the folders are arranged in the pack, adding the option to export to ZIP and much more!

PR

  • Optimized song playback using binary encoding

    • Uses binary search (splits the range in half every iteration) to find which tick to play at a given moment

    • i.e. to play tick 3 in a 64-tick song, will look for players in range 1-32, then 1-16, then 1-8, 1-4, 3-4 and finally reach 3.

    • For a song with 4000 ticks, this reduces the amount of commands running every tick from 4000 to a mere 24 (log2(4000) ≈ 12), which is to say two commands are added for each power of 2 less than the song length

    • Makes performance impact negligible. Below is a ms/tick comparison for a song with 2500 ticks (top is a data pack generated with the latest version of Note Block Studio; bottom is the new version):
      image

    • On the other hand, the number of generated functions can easily reach the thousands (which shouldn't be too big a of a deal).

  • Now allows any tempo

    • That's right! You can play in any tempo supported by the program (even higher than 20 t/s).
    • Achieved by clipping each tick to the nearest Minecraft tick
    • The tempo is controlled in-game by the score of player speed in the song's objective. This value is added to the total count every tick and, every time it accumulates to 80, the next tick is played
    • Every t/s value in the program corresponds to a speed value in-game, which is obtained by multiplying it by 4 (this way 0.25 t/s becomes 1, 20 t/s becomes 80 and so on)
    • You can change the speed of the song on the fly by changing the speed score, but it will get reset on reload
    • Divisors of 80 work more smoothly, since it always takes the same time to reach the next tick (meaning no stutter). With that in mind, the Compatibility window allows you to optimize the tempo for data packs. Although, even if not optimized, results are pretty satisfactory.
    • Uses two objectives per song. The second one is to keep track of the last tick that was played, in order to prevent duplicate ticks (for example, playing each tick twice when you play at half speed). These were labeled nbs_<songname> and nbs_<songname>_t
  • Added option to export out of range notes

    • Extends the supported range to 6 octaves (2 lower and 2 higher than the ordinary range) by making the key go from 0-24 and appending _-1 or _1 to the sound event
    • Requires a resource pack which is included with the program
    • If enabled, unlocks a button for you to save the resource pack containing the extra notes
  • Added option to export as ZIP

    • Uses a shell command and a 7-Zip executable bundled with the program
    • Can still be exported as a folder
  • Added enable loop option

    • You can set where the song will loop to after the playback to have "intros" in the songs
    • Loop start can only be increased up to the last tick of the song, preventing it from jumping to a point after the song end
    • If disabled, song will stop at the end of playback, as normal
  • Redesigned compatibility indicator and window

    • Changed indicator to "Fully compatible", "Data pack only" and "Resource pack only" image
    • Compatibility window is now split into two tabs (schematic and data pack)
    • Schematic tab was reverted to how it was before data packs (only fixes tempo to 10, 5 or 2.5)
    • Data pack tab has extra features to optimize the playback, and points out that you can use custom instruments and out of range notes if you're willing to use a resource pack image
  • Added fields to set custom namespace and path to function folder

    • Makes it easier to merge songs into one data pack, if composing for a map
    • Both are optional, but the path is only used if you provide a namespace
    • Gray out to indicate when they do not apply
      image
    • Path can only contain up to 5 subfolders (to avoid making infinitely long folder chains)
    • dat_makefolders() is responsible for recursively creating the necessary folders
  • Added command preview

    • Updates on the fly as you type the name, namespace and path
    • Name and namespace is processed by string_path(), while path is processed by dat_getpath()
  • Tags and objectives are now nbs_<songname> instead of a random number

    • Before, importing a few songs could quickly make the objective list get out of hand. Also, it was hard to know which objectives/tags belonged to each song
    • Makes it easier to delete stray tags and objectives in case the data pack is removed
    • May cause conflicts, so watch out when picking a name for the data pack!
    • Uses only the first 10 characters from "song name" (as to not exceed the 16 character limit for objective names)
  • Pitch values are now 1000x more accurate, making song less out of tune

    • Uses string_format() rather than string() when converting the pitch value to string, which rounds to five decimal places instead of two
  • Attempts to grab name from the 'Song name' field in the song properties; if none, tries to grab from the file name

    • Slightly more convenient for the user, as they don't have to fill the name manually
  • Moved file writing to a separate script (dat_writefile()) to avoid repetition

  • Added box surrounding the window's content to make layout consistent with schematic export

  • Changed spelling to "data pack" instead of "datapack", as in the game

  • The commands used to control the song are shown in the popup at the end of export
    image

  • Sound source hover descriptions now show the slider which the source is controlled by
    image

  • Default sound source was changed to record (corresponds to 'Jukebox/Note Blocks')

  • Includes song name in the pack description

HielkeMaps and others added 16 commits August 8, 2019 21:46
Loader was treating nbt format v3 like v2
- Added option to export out of range notes
- Added enable loop option
- Optimized song playback using binary encoding
- Allows any tempo under 20 t/s
- Pitch values are more accurate
- Implement custom namespace and path
- Update datapack window to accommodate fields
- Use same random number in tag and objective
- Remove bad tempo popup for tempo <= 20
- Move string manipulation functions to their own scripts to make code more tidy
- Remove dat_inittempo
- Add ZipWriter extension
- Implement option to export as ZIP instead of a folder
- Move file writing to its own script
- Move folder structure creation to its own script
- Truncate command preview when it's too long
- Minor grammar fixes in the datapack window
- Change input box IDs (were conflicting with the ones in song info)
- Attempts to grab name from the song_name property; if none, tries to grab from filename
- Selectively exports function files by ensuring the columns in each branch contain notes (reduces function count if the song has "gaps")
- Fix extra slash at the end of function directory when exporting as ZIP
- Add button to save resouce pack containing out of range notes
- Only unlocks when that option is checked on the datapack window
- Fix playspeed not being set correctly
- Added support to any tempo up to 30.00 t/s
- Optimized code of the binary tree
- Fixed a bug with the 'play' command
- Unified tag and objective names (both start with 'song')
- Split compatibility indicator into "schematic" and "data pack" to make it clearer when you can export to each one
- Moved some stuff around in the datapack window
- Made namespace and path gray out to tell when they're not used
- Made default source "record" instead of "block"
- Changed spelling to "data pack" as in the game
Moved from ZipWriter extension to a 7-Zip executable (couldn't get function tags to work for some reason)
- Include song name in pack description
- Show commands to play the song in the "saved successfully" popup
- Tag and objective now uses first 10 characters of song name (easier to remove stray data after removing a datapack)
@HielkeMinecraft HielkeMinecraft changed the base branch from master to development September 10, 2019 11:21
@HielkeMinecraft HielkeMinecraft merged commit 968370e into OpenNBS:development Sep 10, 2019
@Marcono1234
Copy link

Re #91: datafiles/7za.exe is the 7za.exe file within https://www.7-zip.org/a/7z1900-extra.7z
Size and sha256 checksums match:
SHA256: EA308C76A2F927B160A143D94072B0DCE232E04B751F0C6432A94E05164E716D
Size: 739840 Bytes

It might also be necessary to include 7-Zip's license, see section "Can I use the EXE or DLL files from 7-Zip in a Commercial Application?" on https://www.7-zip.org/faq.html

Yes, but you are required to specify in your documentation (1) that you used parts of the 7-Zip program, (2) that 7-Zip is licensed under the GNU LGPL license and (3) you must give a link to www.7-zip.org, where the source code can be found.

Even though this is not a commercial application, this probably still applies. And giving credit is also good manners.

@Bentroen
Copy link
Member Author

I planned to add credits from the very beginning of this update, but since this isn't a commercial application (as you mentioned), I didn't make it a priority. I'll make sure to add it to the 'About' section before the next release.


// Add command to result
if(o.dat_enableradius) str += "execute at @s run playsound "+ soundname +" "+source+" @a ~ ~ ~ " + string(o.dat_radiusvalue) + " " + string(pitch) + br
else str += "playsound "+ soundname +" "+source+" @s ^" + string(blockposition*2) + " ^ ^ "+string(blockvolume)+ " " + string(pitch) + " 1" + br
Copy link

@Marcono1234 Marcono1234 Oct 26, 2019

Choose a reason for hiding this comment

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

It appears Minecraft determines the volume based on the camera position, compare:

  1. /execute anchored eyes run playsound minecraft:block.note_block.banjo ambient @s ^ ^ ^ 0.25
  2. /playsound minecraft:block.note_block.banjo ambient @s ~ ~ ~ 0.25

Though the difference might be negligible (if there is actually a difference).

Edit: Nevermind, when the sound is played at eyelevel, it is not stereo: MC-164575

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.

4 participants