Marechal-L / Dark-Souls-III-Archipelago-client

This is the Dark Souls III client made for the multiworld randomizer Archipelago
MIT License
1 stars 9 forks source link

Concept for fully randomized overworld items #17

Open nex3 opened 8 months ago

nex3 commented 8 months ago

I mentioned this in the Discord, but I want to jot it down here as well so it doesn't get lost to the sands of time.

As I understand it, the reason progressive items have their own special "pick from a list"-style randomization is that the mod doesn't see item locations, it only sees item IDs. Since most overworld item locations contain things like Titanite Shards that aren't at all unique, the mod isn't able to distinguish whether the player picked up a Titanite Shard in High Wall of Lothric or bought one in Firelink Shrine.

But I think this issue could be solved without needing to access additional data in the mod itself. The parameter file and map formats are well-understood, so—before booting the game—you could edit the params to add a few hundred additional fake items that exist only to have unique IDs, and then edit the maps to point all the overworld progressive pickups at those fake items. Then you could have an option on the randomizer server to track whether progressive items have been faked out and add them to the item pool if so.

Edit: Actually, you wouldn't even need to generate the params files as part of the mod. All you'd have to do is generate them once (maybe using the C# libraries that other software uses) and provide them as a zip file for people to use along with ModEngine.

nex3 commented 8 months ago

I might be interested in working on implementing this if there's an appetite for it. I don't think the map and param formats are so complicated that it would be prohibitively difficult to port them to Python, which opens up all kinds of possibilities: showing the names of items in other games, putting items in the shrine maiden shop, randomizing starting equipment, and so on.

Marechal-L commented 8 months ago

Hi, yes that's exactly why I ended up using a progressive location system for this first implementation. I didn't try to modify the game files yet but it would be very interesting to create a new set of itemIDs to identify each location.

I still see some problems with it, but some could be fixed by changing the mod :

There's definitly appetite to support a maximum amount of features and would love to invest more time on this project to support this kind of idea :)

nex3 commented 8 months ago

Unfortunately my skills end at the ASM boundary, so I can't help fix those issues directly, but I may be able to suggest workarounds.

The mod doesn't handle properly a stack of the same item, which will prevent picking up a stack of titanite even if 'fakeItems' is set to false.

As in, the mod can't push multiple items of the same type into inventory? This may be less of an issue if all the items are randomized at the map level. As you don't have any cross-game items that are stacks, you should be fine.

The mod doesn't hook the right method called after a buy from a merchant, which means even if the merchant inventory is shuffled the mod couldn't send the check to the server.

This is tricky. The easiest workaround is to say "cross-game items never go in shops", which is fine but kind of unsatisfying (especially because it makes the "get an ash -> get some souls -> get a progression item" flow much harder). The other possibility would be to check items in inventory rather than items as you pick them up, since you'd be able to treat each progression item as a unique key item. That would definitely be harder to implement, but it might fix #14 as well as a side effect.

Having a single .dll file is a convenient installation process, if another file is involved I would probably need to create an installer to check the modengine setup first and then setup AP properly. Otherwise the amount of support requests would increase to much.

I think the way the offline randomizer handles this is to distribute a .zip of files and just say "unzip these into the DS3 directory". ModEngine supports chained mods, so this could just look like:

Another option would be to collaborate with @gracenotes (author of the offline randomizer) to teach that to connect to an Archipelago server and handle all the local generation. This might be the best option in general, since it also gives you enemy randomization effectively for free. I've done some work on that codebase already.

nex3 commented 8 months ago

it's still early and a bit hacky, but I have a functional prototype of connecting @gracenotes' offline DS3 randomizer to the Archipelago server and randomizing items offline:

image

20231020054320_1

This isn't particularly useful yet, but it'll eventually allow Archipelago to put any item in any location the offline randomizer knows about, which is pretty much everywhere. It'll also allow it to randomize cool stuff like the Path of the Dragon gesture, display other games' item names within DS3, and share enemy randomizer settings and seeds for competitive runs.

Major work still to be done includes:

nex3 commented 8 months ago

Making more headway here! If anyone's interested in following along, I'm pushing pretty regularly to github.com/nex3/Dark-Souls-III-Archipelago-client/ and github.com/nex3/SoulsRandomizers, and I'm going to start a branch on github.com/nex3/Archipelago soon as well.

I've got the offline randomizer generating custom items to represent items in other worlds:

20231021211810_1

...and I've also found another hook to use to detect items purchased from shops. This is actually less work than I thought it might be!

eudaimonistic commented 8 months ago

This is all really exciting stuff! Just so I have a better understanding of the intended results here:

-Offline Generator connects to multiworld server to fetch items/locations based on the player yaml options. -Generator patches and randomizes the game world to abide by those locations/items, shuffling anything else not included with presumably filler items, if necessary.

All of this accomplished by using invisible event flags on the correct locations? Essentially, allowing for both to be arbitrary and highly customizable?

Does this account for player saves, and resuming sessions? From what I can gather, the Generator itself becomes the Client, and patching the game once should be sufficient for the duration of the multiworld, even if across multiple sessions. How would a user handle multiple player slots? Just repatch the game? Would that nuke player progress? Obviously the server remembers what you've done, but I felt like asking because this sounds like a great step forward.

Got me all jazzed up thinking about the possibilities! Thank you for your effort.

nex3 commented 8 months ago

This is all really exciting stuff! Just so I have a better understanding of the intended results here:

-Offline Generator connects to multiworld server to fetch items/locations based on the player yaml options. -Generator patches and randomizes the game world to abide by those locations/items, shuffling anything else not included with presumably filler items, if necessary.

That's basically it, yeah. My plan is to make the Archipelago server do all the heavy lifting for figuring out the locations for almost everything, but the offline randomizer will probably still handle a few details like shop prices, non-unique enemy drops, and starting character loadouts (seeded by the server so it's consistent for races, of course). It'll also handle all the enemy randomization itself, with options sent down from the server.

All of this accomplished by using invisible event flags on the correct locations? Essentially, allowing for both to be arbitrary and highly customizable?

Mostly we don't even need to use the event system (although they may be necessary for edge cases like Path of the Dragon). The offline randomizer is able to modify the map files, drop tables, and so on. It's already very sophisticated—that's one of the big advantages of using it. (The other is that it knows how to read data from the DS3 files on disk so we don't need to store a whole copy of DS3 on the server.)

Does this account for player saves, and resuming sessions? From what I can gather, the Generator itself becomes the Client, and patching the game once should be sufficient for the duration of the multiworld, even if across multiple sessions. How would a user handle multiple player slots? Just repatch the game? Would that nuke player progress? Obviously the server remembers what you've done, but I felt like asking because this sounds like a great step forward.

It's possible to have multiple concurrent saves if you keep the mod directories separate and don't load into the wrong save at the wrong time. I think the UX will be something like this:

If a user wants multiple different saves, they just need to keep a different archipelago/ directory for each one, and make sure whichever one they want to use is the one with the correct name.

nex3 commented 8 months ago

All right, I've got both parts of this fully functional. I've run an end-to-end test with the current server implementation and I've verified that it works to get items locally, send items to other worlds, and receive items from other worlds (it would be weird if that broke but stranger things have happened). You can test it out yourself by downloading DS3-Archi-Stack.zip and following the instructions above.

Anything further here is going to require updating the server as well. Would it make sense to start landing the work I already have in this repo? Or would you prefer I wait until I have a parallel server PR as well and land a whole lot of changes at once?

Edit: Oh actually buffed weapon drops are currently broken. This is fixable with the current server implementation for sure, but if I'm going to be doing a server overhaul before landing I might as well just do that.

eudaimonistic commented 8 months ago

At best I fill a Community Manager sort of role in the Archipelago world, as I've never actually developed any code myself outside of plain text documentation. I'll offer my opinion based on observing development, and hopefully that's useful for your purposes. You'll likely get more specific implementation instruction in #archipelago-dev, as you've done so far.

Obviously @Marechal-L is the relevant Code Owner to consider for merging this progress into their currently existing implementation. They (or possibly @Br00ty) will end up being tagged in any DS3-related server PRs for the main Archipelago repository, and will therefore need to approve changes. It would then need to pass the usual unit-tests and Core Dev review prior to inclusion, which is definitely the slowest part of the process by far. However, this is usually mitigated by successful Beta Tests and code review from other non-core-dev interested parties. Judging by how previous PRs in the DS3 space have been reviewed, there are quite a few parties interested in pushing this along.

I would recommend compiling an Archipelago build that supports your changes, scheduling a Beta Test (or hopefully, more than one) in the #planning section of the AP Discord server, and distributing your build during that session. This allows for some stress testing, and the session can be referenced in your actual PR against Archipelago. Alternatively, you could schedule a Beta Test Async in the #community-run-asyncs channel to do something a little more long-form. Many of the longer games go this route as it gives you an entire forum post to collect information and bug reports. The main victory there is Archipelago has a lot of edge-cases and cross-game interactions that are not easy to design for without actually throwing it against the wall.

I made a guide for hosting both sync and async sessions in the #get-started section of the community Discord server, for the purpose of using the AginahBot commands to schedule them. You're always welcome to schedule testing privately as well, though public sessions have the advantage of more players (aka more data points) and a better public record of testing. The big takeaway is that PR approval is frequently slow in this project due to the small number of core developers, and whatever we can do to test functionality against the rest of the project in advance is a boon to speeding up that process.

Sorry for longposting, I don't think I forgot anything relevant? That comment won't age well, I'm sure. I'll try to give all of these changes a try tonight for my own personal testing. I get the impression that the proposed changes will do a LOT for ease of use and engage players who found the existing setup frustrating.

eudaimonistic commented 8 months ago

Oh I'm pretty bad at reading. If you're pretty confident that the PR against the Client repo is compatible with the Archipleago server behavior as-is, then yeah it'd probably make a lot of sense to just PR against this repo now as a prelude to server changes. Sorry, I'm a bit blind sometimes and completely missed the actual question while ranting.

nex3 commented 8 months ago

The main asterisk on sending a PR as-is is that this also changes the way users need to set up the randomizer. I'm happy to update the documentation for this as well, but it's a bit more complex than just doing an in-place replacement of this client.

eudaimonistic commented 8 months ago

If so, then it might make a lot of sense to open a Draft PR with a comment explaining the new setup, and then commit doc changes alongside it once it's converted to a normal PR. That way people will see the intended changes sooner and consider testing them, while not holding things back over the docs being prepared immediately.

Marechal-L commented 8 months ago

This looks amazing, I'll take a look later this day

Br00ty commented 8 months ago

I've always wanted to use Matts version of the rando for AP, so seeing it come to light has no qualms with me. There was talks of adding a button to the offline rando for Enemizer, but never needed to as it just works with base rando as it is. When it comes to changes, I usually always hit up Marech and ask "Hey mind if blahblahblah?" just to be transparent and make sure they know whats going on with their implementation, as they are the original person that made DS3 even happen in AP. All that being said, I will be excited to stress test this and report anything to help progress this version more.

nex3 commented 8 months ago

Latest update: this is now fully working, end-to-end, including:

There are a few quality-of-life changes I want to make, and I want to update the documentation and do a full multiworld runthrough with some friends, but once I'm pretty confident it's in a solid place I'll package up the current offline randomizer and send all of this out for review.

saqlain1020 commented 4 months ago

Email you got about github hiring is fake Visit: https://github.com/Marechal-L/Dark-Souls-III-Archipelago-client/issues/17 to find the content which you received in the mail. Just a friendly developer letting you know of the scam.

xinming365, @diulama, @lempere, @ianidi, @khadgachy07, @teebui, @mutahhirkhan, @littleboycoding, @qzz0518, @JustAPotato0916, @damonliu1991, @huemy221338, @helnwein, @gtaschuk, @sumitpatel93, @kapdap, @sheikhimtiaz, @LIYANG-UST, @fruitcow, @mdastronaut

Hello,

We have an exciting opportunity for you! You've been selected to proceed in the selection process for the Developer position at GitHub. Congratulations on your achievement!

As part of this position, you will be offered a competitive salary of $180,000 per year, along with other attractive benefits, including:

  • Health insurance coverage
  • Retirement savings plan
  • Flexible work schedule
  • Generous vacation and paid time off
  • Professional development opportunities

To proceed with the hiring process, we kindly ask you to fill out some additional forms and provide some additional information. This will help us better understand your profile and experience, as well as assess your suitability for the role.

Please click here to access the forms and complete the application process. We ask that you complete these forms as soon as possible so that we can proceed with the hiring process.

Important: You have 24 hours to complete the application process.

If you have any questions or need further information, please don't hesitate to contact us.

Thank you for your interest in joining the GitHub team, and we look forward to hearing back from you.

Best regards, GitHub Recruitment Team xinming365, @diulama, @lempere, @ianidi, @khadgachy07, @teebui, @mutahhirkhan, @littleboycoding, @qzz0518, @JustAPotato0916, @damonliu1991, @huemy221338, @helnwein, @gtaschuk, @sumitpatel93, @kapdap, @sheikhimtiaz, @LIYANG-UST, @fruitcow, @mdastronaut