Hi everyone
Happy Halloween! Development and testing continues on seamless co-op for Dark Souls II. In this post I'll discuss what I've been working on this past week.
Event flags
Event flags in the other souls games are used for everything you can think of - from game progression (e.g. boss kills, bonfires, estus level, etc.) all the way to objects and their state (e.g. door open/closed, lift up/down). Getting a complete world sync by just copying the hosts' own event flags during connection is 99% of the way there.
In Dark Souls II however, it is unfortunately not that easy. There are event flags (space for around 20,000 core ones and an additional 200 map-specific ones per area) however they aren't relied on nearly as much as in the other games.
There are several additional components that need to be reverse engineered and synced up with the host when creating a fully seamless multiplayer experience.
One example is the status of bonfires in the game:
There is a list of bonfires (77 in the vanilla game)
The bonfire ID is a 2-byte value, followed by a single byte relating to specific bonfire info
The zeroth bit is whether the bonfire has been lit or not
The remaining bits represent the 'level' of the bonfire (how many bonfire ascetics you have used on it
The next byte following this is the same as the above, but relating to the multiplayer
After this, a pointer containing some more general information - for example whether you can use it to burn bonfire ascetics / the flag ID representing which boss is the 'master' of the bonfire, etc
Although I have completely mapped out the internal game structures representing bonfires, and have created networking and functions within the mod to sync up your bonfires to the host (only in the session) and ensure bonfires lit during the session carry over to your own world -- you can maybe get an idea on why this game is taking so long as all of this would be as easy as copying event flag states in the previous seamless mods.
The leads me on to my next point...
Map entities
Map entities relate to objects (intractable or not) placed in any give map. This covers all kinds of stuff such as the torches you can light, items that spawn on the ground, destructible objects, chests, etc.
I've spent most of this afternoon trying to figure out how to carry over certain object interaction results - for example opening a chest - from the host world into your game world. For example:
Guest player joins host
Guest player opens Majula chest in host world
Guest player returns to their own world
Majula chest remains open
As I described above, in other seamless mods the above was all managed by setting certain event flags which was fairly straightforward.
From what I can understand Dark Souls II handles it differently, using a combination of MapSnapDataManager and MapStateActManager to periodically take snapshots of the map entities in the area and store it in your save file directly as raw data - rather than flags.
After a while I figured out how to access and write to the world state in your own world even as a guest in a host world, however there are some complexities regarding the auto-save feature that I need to resolve first.
This is a work-in-progress feature, however in the process of working out how it all worked I managed to corrupt my save file so I'll spend some time tomorrow fixing that as well.
Enemy generation (extra)
As a side note - earlier this week I needed a break from seamless work and wanted to see if I could get my own custom enemy generator working in seamless.
It took about a day, but I managed it. It was fun to work on something other than networking features for a little while, and as a rough draft I could duplicate enemies. Adjusting it to spawn who I want where I want shouldn't be too difficult.
As always - thank you for your patience and a huge thank you to all of my supporters <3
Take care
~ Yui