Coolcord / Level-Headed

Random Level Generator for Super Mario Bros. 1 on the NES
GNU General Public License v3.0
117 stars 6 forks source link

[Feature Request] Easier way to generate a premade game for races #20

Closed macobra52 closed 1 year ago

macobra52 commented 3 years ago

Currently in order to race a generated game with friends one person would either have to generate and distribute the ROM file to the other players (a legal issue in itself), or all players would need to verify that all settings match up in Level-Headed prior to generation, a daunting task in itself with all the available settings.

What I would propose is an interface allowing you to simply provide the seed number and a flag/config string or CFG file that would allow you to easily generate the same game as another player for racing purposes. This could also allow players to select their own graphics and music (provided there are no differences as far as lag goes, not sure), but the important thing is that all other settings should be the same (levels, enemies, power-ups, lives, etc.)

Coolcord commented 3 years ago

I'd actually like for Level-Headed to have this feature too! I've considered implementing this before, but it's actually a very complicated issue when it comes to Level-Headed. It's important to realize that Level-Headed isn't exactly a randomizer, as it's actually making new content and injecting pre-made content into the game. Consequently, while other randomizers can implement something like this very easily, there's a ton to consider with Level-Headed that would cause this feature to almost completely break under numerous circumstances. In many other cases, there's a lot of potential for user error. I'll explain why.

The Custom Graphics and Music Issue

In Level-Headed, users can add their own graphics and music patches. Having more or less patches available would completely throw off the game that is generating, resulting in a different generation.

As you suggest, this can be avoided by having this config string ignore graphics and music. While this would solve some potential issues, it would also raise a few new ones. For example, due to the nature of how graphics and music patches work, there's actually nothing stopping them from changing other aspects of the game. This would mean that there would be nothing to stop someone from including their own patch that ends up modifying the levels or changing enemy behavior. In the context of a professional race, this would mean that someone could "cheat" by including a graphics or music patch that actually makes the game easier in some way.

An alternative would be to only allow config strings to be used if the graphics and music patches have remained unchanged since install. While this is the case for well over 99% of Level-Headed's users, it would also mean that if any user ever makes changes to the graphics or music in any way, they will consequently be punished by not being allowed to use the config string anymore (at least, not until they uninstall and reinstall Level-Headed). This would likely further demotivate people from using the custom graphics and music feature. It would also add more work for me when updating Level-Headed, as the checksum hash for each graphics and music database will change with each future release.

The Second Quest Issue

Level-Headed allows users to distribute previously generated levels as well as pre-made levels (written via scripts). These level packs are found under ./Levels/SMB1/ in Level-Headed's application folder. Users need to be using the exact same level pack in order to get the same game. There's a lot of potential for user error here if a config string is introduced. For example, if users are using a different version or revision of a level pack, that could also result in potentially significant differences between the generated games.

The Pattern Database Issue

v0.4 will introduce a complete overhaul of how levels are generated. Level-Headed (as of v0.3.x versions and prior) currently uses a pattern-based approach to generating levels. A pattern is a recipe for a small piece of a level. Currently, patterns are defined programmatically, and there's a lot of potential for bugs in each one. However, the advantage to this approach is that a significant amount of variety is possible from a small amount of patterns. The current versions of Level-Headed are a testament to this, as there are currently (at most) only 10 patterns for each level type.

Fun Fact: v0.1 launched with so few patterns since this iteration of the project was originally started as a college capstone project for my degree in Computer Science. I was originally planning on adding many, many more patterns, but due to time constraints, I had to stop with what's currently in Level-Headed. The pattern database feature has been planned for years, and since programmatic patterns will become the legacy approach, I haven't added any new patterns since Level-Headed's initial public release of v0.1. This will change starting with v0.4.

The plan is to implement a pattern database, much like how graphics and music are currently implemented. This would mean that users can potentially add their own patterns to Level-Headed. Patterns will be created with a graphical editor, allowing for their creation to be much easier. The plan is that this editor will also check to help make sure that a pattern will not introduce a segment of level that is impossible to complete.

With all of this in mind, a config string will only result in the same game if users do not add or change any patterns in the pattern database. One small change could seemingly start out the same, but then the two games could end up desynchronizing at some point pretty significantly.

The Easiest Solution (For Now)

I realize that this solution probably isn't exactly what you're looking for, but for now, I'd just recommend creating a patch file for the game you wish to share and distribute that. Simply treat Level-Headed games as if they are each a new hack, and distribute them accordingly. There are many formats that can be used for this, including IPS, BPS, PPF, and my own HEXP (Hexagon Patch). Hexagon may actually be the best option here, as it can ensure that everyone is using the same base ROM as the original file when applying a patch.

Bear in mind that development of the pattern database and v0.4 will take priority over this feature, as I personally feel that Level-Headed's lack of patterns is the main thing holding it back right now. This config string feature could potentially end up being a significant undertaking with very little end-user benefit, considering how many edge cases there are to consider. Unfortunately, I haven't had much time to work on v0.4 lately, so not much progress has been made on that front yet.

However, I'm completely open to discussion and further suggestions of how to implement this feature, as it may lead to a potential design solution.

macobra52 commented 3 years ago

Thank you for the quick reply and well elaborated answer. I can see where the difficulty lies in doing this now due to the nature of the program. Admittedly I haven't explored all of the features myself, but a group of us would race generated games with it from time to time and every time it's been a fun experience (we all agree it is underrated as far as randomizers go). We recently decided to start a Discord for casual races and potentially a tournament down the line if there was enough interest, so I was curious as far as what options we had to make racing with it a simpler process.

The easiest solution seems to be the best way to do it for now as you said. Distribute a patch instead of the ROM itself. Would it be possible for Level-Headed to automate the patch generation? Maybe have a checkbox added to generate a patch in addition to the game itself.

Coolcord commented 3 years ago

After thinking about this, I don't think Level-Headed should be managing patch files. Hexagon already makes patch creation very simple once it has been setup. For your use case, here's what I would suggest.

Download and install Hexagon. Once installed, run it and go to the Options tab. Set the original file in slot 1 to the "(Full Support) Super Mario Bros. (JU).nes" file located under Level-Headed's ./Data/SMB1/ folder. After this, set "Ask for Save Location" to "Never" and make sure that "Skip checksum with creating patch" is not checked. After this, go back to the Patch tab.

From now on, creating patches for Level-Headed SMB1 games will be as simple as running Hexagon, selecting "Create Patch", and choosing the game you wish to distribute. The patch file will be created in the same directory as the file you selected.

macobra52 commented 3 years ago

Thanks. I gave the process a try and it seemed simple enough once set up. I'll see if the others in the discord are ok with that approach.

Coolcord commented 1 year ago

Sorry for the late response on this. v0.3.10 has support for sharing configurations. As stated before, a tool such as Hexagon is still recommended for sharing games without sharing the ROM itself. A note about this will be added to the about tab in the next release.

Thanks again for the feature request. Your feedback is appreciated!