6742382d9a948

6742382d9bdcb
1 Guest is here.
 

Topic: SS2 Randomizer, Is it even possible? Read 6779 times  

6742382d9c446JossiRossi

6742382d9c4b3
Having seen some really impressive randomizer projects done with a variety of different games lately, I was taking a cursory glance at some game resources to see if it was even possible, but frankly am not remotely experienced enough to determine that.

Most other randomizers use an external program to alter files. A start could be simply change door codes. I believe you could generate new log texts with altered codes numbers included (ignoring the audio portion not being reflected), but then you'd need to change the code on the lock itself. Which would require map modifications, can that even be done on a compiled map? Honestly, guessing not? Let alone trying to fancier with randomizing key locations/routes etc. Still, wanted to ask.

6742382d9c62bZylonBane

6742382d9c6a0
Most codes are read in audio logs, so they can't be changed.

Log text also can't be dynamically changed.

6742382d9c7f9JossiRossi

6742382d9c848
It wouldn't exactly be dynamic. It'd essentially be a process for creating a.custom mod. So a program would take in the file with the audio log text. Replace the door code with a new random one. Really, the way I'd do it is have a version of the log text file, where codes like 0451 were replaced with *door_code_medsci_01*, then do the substitution and generate an altered version of the log information file. This would not be an in engine process.

The bigger hurdle isn't generating these log files, it would be also generating map information altered to reflect a generated door code. The actual recorded playback of the log could never reflect a random door code, so I'd probably edit the audio with static over where a number is said to avoid the conflict. You would need to look at the text to know the new code

6742382d9c8e1ZylonBane

6742382d9c92b
Or, players could just not open doors that they haven't found the code for yet.

6742382d9ca8bJossiRossi

6742382d9cb06
The door codes are not the end goal of the idea. Check out the Link to the Past Randomizer for an example of what people have been tinkering with in terms of randomizers. You essentially code up a lot of logic of where items can be located and what the different gatekeeping aspects there are. Door Keys, Door Codes, Etc. Then the randomizer creates a possible path that allows a player to collect all the needed gate keeping tools to accomplish everything, but it can take the player through very unconventional paths to do that.

One of the biggest things is just even if it's possible to make these kinds of alterations to the map in the first place in a way that won't require someone to jump through a ton of hoops and export maps manually etc. Ideally, any data that is exposed and modifiable in the map formats could be altered in this way. So a key for Engineering will not be located in it's normal location, and could be just about anywhere (as long as the basic logic of possible paths allows it). And if all items are exposed logically in the map data in some way then you could randomize how they are handled. So, you might need a chemical for research, but they are no longer in the chem storage but could be anywhere, and it'd add a twist to the search and scrounge style of play.

6742382d9cbe7ZylonBane

6742382d9cc33
Why didn't you ask that in the first place? Of course that's possible. It was done 15 years ago.

6742382d9cdf1voodoo47

6742382d9ce49
many SS2 quest items are set up in a very specific way that doesn't allow easy swaps, so it's very safe to say that such a randomizer would not be possible.

you could however, set up a low number (2-3) of alternate variations of those objects, and make the game pick one set randomly (so basically, you would have 3 places where a log with a code could be located, and 3 different codes, so 9 possible variations total).

6742382d9cf38JossiRossi

6742382d9cf86
Ok, I was suspecting that there might have been hardcoded or really restrictive ways for how quest items were handled. It might be fun to try and do some remixing of the items with the method you two linked, but without the ability to really control placement logic to weed out unwinnable states, it feels this is placed in the not possible camp. Thanks for the info though!

6742382d9d050voodoo47

6742382d9d099
I wouldn't call it restrictive, it's just that the quest setups can be rather complex, so if you want to change them, you need to roll up your sleeves, fire up the editor, and actually change them. if you were hoping for an auto-tool that would modify some hex values on the fly, you are out of luck.

no free lunches with Dark, remember?

6742382d9d160JossiRossi

6742382d9d1a8
With my limited skill set, I could have handled some editing, but it would have largely been about replacing references that were possible to edit and sliding things around according to a brute force logic set. If I was going to dedicate time to wacky hacking, I was hoping to keep it limited to "build map object lists/alter references" rather than "learn how an archaic editor functions" if that makes sense.

6742382d9d24cvoodoo47

6742382d9d295
as far as I can tell, that route (alter references etc) is simply not possible here.

6742382d9d855JossiRossi

6742382d9d8a2
So, after banging my head against this for a few days, I actually made some progress! It's never going to be the bigger idea I had, but there might be a use for what I'm working on at the moment. We'll see how far I can get as I explore other aspects, might get something enjoyable out of it. The thing that *might* be good with this method over Zygo's randomizer mod is this only touches dml files, so I think it should be able to be incorporated a little more easily into other projects, vs altering the level data directly?

So, right now I have a script I can run and it'll create randomized dml outputs for corpses in MedSci1. Nothing terribly advanced and it will likely result in unwinnable states, and the corpses don't always align right, and who knows what else. But for a first poke into creating a python script to generate usable game info, I'm rather surprised that it worked at all.

By using info from the hierarchy export in the editor, you can quickly get the positional data of all corpses in a level. I plugged that into a python script that mixes up all the Object IDs and the Object coordinates, and exports them in the dml format to swap all the corpses around in the level.

Here are 3 randomized versions I just exported for example if anyone wanted to give something that WILL break the game logic. The odds of getting the door code corpse as one of the two immediately available corpses is extremely low for instance. However, with some routing logic I'd be able to control for that. Want to see what else I can do before bothering with that aspect though.

To use just take this code and cram it into the bottom of the medsci1 dml file.

Random Medsci1 Corpses 1
Code: [Select]
//Randomized Corpses
+ObjProp 833 "Position"
{
"Location" 37.80, -161.26, -18.79
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1680 "Position"
{
"Location" 93.17, 79.42, -13.77
"Heading" e005
"Pitch" 0
"Bank" 0
}

+ObjProp 492 "Position"
{
"Location" 43.68, 116.57, -15.25
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 781 "Position"
{
"Location" 77.88, -100.65, -18.77
"Heading" aa6
"Pitch" 0
"Bank" 0
}

+ObjProp 880 "Position"
{
"Location" -22.58, -106.00, -9.88
"Heading" 8000
"Pitch" 0
"Bank" 0
}

+ObjProp 219 "Position"
{
"Location" -14.62, 61.68, -2.67
"Heading" 4000
"Pitch" 0
"Bank" 0
}

+ObjProp 831 "Position"
{
"Location" -78.29, -187.01, -3.96
"Heading" 8f07
"Pitch" 0
"Bank" 0
}

+ObjProp 1177 "Position"
{
"Location" 47.17, -171.49, 3.33
"Heading" e03e
"Pitch" 0
"Bank" 0
}

+ObjProp 1095 "Position"
{
"Location" -48.89, -6.37, -14.79
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 165 "Position"
{
"Location" -44.51, -78.61, -2.67
"Heading" 17cb
"Pitch" 0
"Bank" 0
}

+ObjProp 1351 "Position"
{
"Location" -48.25, 88.43, -2.79
"Heading" 92d2
"Pitch" 0
"Bank" 0
}

+ObjProp 867 "Position"
{
"Location" 43.24, 26.74, -3.89
"Heading" c000
"Pitch" 0
"Bank" 0
}

+ObjProp 1428 "Position"
{
"Location" -48.13, 128.36, -3.86
"Heading" f8e3
"Pitch" 0
"Bank" 0
}

+ObjProp 998 "Position"
{
"Location" 0.21, -19.20, -14.77
"Heading" 3ffd
"Pitch" 0
"Bank" 0
}

+ObjProp 931 "Position"
{
"Location" -31.64, 113.44, -3.96
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 702 "Position"
{
"Location" 56.64, -143.63, -18.67
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1182 "Position"
{
"Location" 2.66, -71.45, -3.25
"Heading" 8000
"Pitch" 0
"Bank" 0
}

+ObjProp 507 "Position"
{
"Location" -75.40, 22.79, -3.00,
"Heading" d3b4
"Pitch" 0
"Bank" 0
}

+ObjProp 735 "Position"
{
"Location" -77.10, -72.53, -3.96
"Heading" c000
"Pitch" 0
"Bank" 0
}

+ObjProp 490 "Position"
{
"Location" -27.69, -14.70, -3.61
"Heading" ef97
"Pitch" 0
"Bank" 0
}

+ObjProp 294 "Position"
{
"Location" 78.36, -23.84, -2.79
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1153 "Position"
{
"Location" -67.46, -147.73, 4.77
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1584 "Position"
{
"Location" 39.83, -111.82, -3.66
"Heading" e2b4
"Pitch" 0
"Bank" 0
}

+ObjProp 967 "Position"
{
"Location" 45.20, -18.21, -3.73
"Heading" 3949
"Pitch" 0
"Bank" 0
}


Random Medsci1 Corpses 2
Code: [Select]
//Randomized Corpses
+ObjProp 219 "Position"
{
"Location" -75.40, 22.79, -3.00,
"Heading" e03e
"Pitch" 0
"Bank" 0
}

+ObjProp 831 "Position"
{
"Location" -67.46, -147.73, 4.77
"Heading" 92d2
"Pitch" 0
"Bank" 0
}

+ObjProp 1680 "Position"
{
"Location" -31.64, 113.44, -3.96
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 492 "Position"
{
"Location" -48.89, -6.37, -14.79
"Heading" 8f07
"Pitch" 0
"Bank" 0
}

+ObjProp 1584 "Position"
{
"Location" 43.24, 26.74, -3.89
"Heading" 4000
"Pitch" 0
"Bank" 0
}

+ObjProp 165 "Position"
{
"Location" -78.29, -187.01, -3.96
"Heading" c000
"Pitch" 0
"Bank" 0
}

+ObjProp 294 "Position"
{
"Location" 43.68, 116.57, -15.25
"Heading" aa6
"Pitch" 0
"Bank" 0
}

+ObjProp 1351 "Position"
{
"Location" -22.58, -106.00, -9.88
"Heading" f8e3
"Pitch" 0
"Bank" 0
}

+ObjProp 1428 "Position"
{
"Location" -14.62, 61.68, -2.67
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 931 "Position"
{
"Location" -77.10, -72.53, -3.96
"Heading" e2b4
"Pitch" 0
"Bank" 0
}

+ObjProp 867 "Position"
{
"Location" -48.25, 88.43, -2.79
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 833 "Position"
{
"Location" -34.38, -54.92, -2.79
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1362 "Position"
{
"Location" 47.17, -171.49, 3.33
"Heading" c000
"Pitch" 0
"Bank" 0
}

+ObjProp 1182 "Position"
{
"Location" 37.80, -161.26, -18.79
"Heading" 3949
"Pitch" 0
"Bank" 0
}

+ObjProp 735 "Position"
{
"Location" 0.21, -19.20, -14.77
"Heading" d3b4
"Pitch" 0
"Bank" 0
}

+ObjProp 490 "Position"
{
"Location" 45.20, -18.21, -3.73
"Heading" 8000
"Pitch" 0
"Bank" 0
}

+ObjProp 781 "Position"
{
"Location" 77.88, -100.65, -18.77
"Heading" ef97
"Pitch" 0
"Bank" 0
}

+ObjProp 702 "Position"
{
"Location" 2.66, -71.45, -3.25
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 507 "Position"
{
"Location" 93.17, 79.42, -13.77
"Heading" 3ffd
"Pitch" 0
"Bank" 0
}

+ObjProp 1177 "Position"
{
"Location" -48.13, 128.36, -3.86
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1095 "Position"
{
"Location" -44.51, -78.61, -2.67
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1153 "Position"
{
"Location" 39.83, -111.82, -3.66
"Heading" 8000
"Pitch" 0
"Bank" 0
}

+ObjProp 880 "Position"
{
"Location" -27.69, -14.70, -3.61
"Heading" e005
"Pitch" 0
"Bank" 0
}

+ObjProp 998 "Position"
{
"Location" 56.64, -143.63, -18.67
"Heading" 0
"Pitch" 0
"Bank" 0
}


Random Medsci1 Corpses 3
Code: [Select]
//Randomized Corpses
+ObjProp 931 "Position"
{
"Location" 93.17, 79.42, -13.77
"Heading" f8e3
"Pitch" 0
"Bank" 0
}

+ObjProp 880 "Position"
{
"Location" 0.21, -19.20, -14.77
"Heading" aa6
"Pitch" 0
"Bank" 0
}

+ObjProp 1153 "Position"
{
"Location" -14.62, 61.68, -2.67
"Heading" 8000
"Pitch" 0
"Bank" 0
}

+ObjProp 702 "Position"
{
"Location" 43.24, 26.74, -3.89
"Heading" ef97
"Pitch" 0
"Bank" 0
}

+ObjProp 490 "Position"
{
"Location" -48.25, 88.43, -2.79
"Heading" e005
"Pitch" 0
"Bank" 0
}

+ObjProp 998 "Position"
{
"Location" -34.38, -54.92, -2.79
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 781 "Position"
{
"Location" 45.20, -18.21, -3.73
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1177 "Position"
{
"Location" 37.80, -161.26, -18.79
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 833 "Position"
{
"Location" -67.46, -147.73, 4.77
"Heading" c000
"Pitch" 0
"Bank" 0
}

+ObjProp 735 "Position"
{
"Location" 77.88, -100.65, -18.77
"Heading" e2b4
"Pitch" 0
"Bank" 0
}

+ObjProp 294 "Position"
{
"Location" -48.89, -6.37, -14.79
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 492 "Position"
{
"Location" 78.36, -23.84, -2.79
"Heading" 3949
"Pitch" 0
"Bank" 0
}

+ObjProp 967 "Position"
{
"Location" -44.51, -78.61, -2.67
"Heading" 8f07
"Pitch" 0
"Bank" 0
}

+ObjProp 219 "Position"
{
"Location" -48.13, 128.36, -3.86
"Heading" 92d2
"Pitch" 0
"Bank" 0
}

+ObjProp 1428 "Position"
{
"Location" 47.17, -171.49, 3.33
"Heading" 3ffd
"Pitch" 0
"Bank" 0
}

+ObjProp 507 "Position"
{
"Location" 56.64, -143.63, -18.67
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1182 "Position"
{
"Location" 39.83, -111.82, -3.66
"Heading" d3b4
"Pitch" 0
"Bank" 0
}

+ObjProp 1680 "Position"
{
"Location" 2.66, -71.45, -3.25
"Heading" 17cb
"Pitch" 0
"Bank" 0
}

+ObjProp 831 "Position"
{
"Location" 43.68, 116.57, -15.25
"Heading" 8000
"Pitch" 0
"Bank" 0
}

+ObjProp 165 "Position"
{
"Location" -22.58, -106.00, -9.88
"Heading" c000
"Pitch" 0
"Bank" 0
}

+ObjProp 1351 "Position"
{
"Location" -78.29, -187.01, -3.96
"Heading" 4000
"Pitch" 0
"Bank" 0
}

+ObjProp 1362 "Position"
{
"Location" -77.10, -72.53, -3.96
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1095 "Position"
{
"Location" -75.40, 22.79, -3.00,
"Heading" 0
"Pitch" 0
"Bank" 0
}

+ObjProp 1584 "Position"
{
"Location" -27.69, -14.70, -3.61
"Heading" 0
"Pitch" 0
"Bank" 0
}

6742382d9d9a2voodoo47

6742382d9d9eb
so, you are using an external tool to randomly pick a dml from an pre-configured existing set? that's.. different.

but whatever gets the job done, I suppose.

6742382d9dad6JossiRossi

6742382d9db27
It generates dml data on the fly, when I run a small Python script. Right now it has a harcoded list of all the current corpse locations, it then generates the dml data and gives every corpse a different random location sourced from the list. I can easily enough add new corpse locations too, so corpses can be in a mix of classic and brand new positions if I wanted. So it's not preconfigured really and is very easily extendable.
6742382d9dc67
IIRC NewDark has a script language available named squirrel. Might make sense to write the generator in that.

6742382d9dd0cJossiRossi

6742382d9dd5b
Squirrel seems interesting I do want to.try and learn more about how it works. For protyping I can probably keep rolling with Python short term while I get used to things. It's very much still learn as.I go.
Acknowledged by: Kolya

6742382d9df65JossiRossi

6742382d9dfb9
Did some cleanup today. So the script now pulls info from a modifiable text file, that includes all the data needed to generate the randomized locations. As part of that I also tested adding new locations, and the barest of logic.

Right now I can randomize all the corpse locations, while ensuring that the corpse with the 45100 door code log will always spawn before that door. Ensuring that a player (who somehow doesn't know that code AND is trying out a randomizer for whatever ill advised reason) won't get stuck.

Edit
https://imgur.com/gallery/ymrhhlr check out images here for what I am talking about.

2 versions of that room right before the 45100 door. Sometimes there's 2 corpses in that room, other times none and the log is in a different location in the hallway or where wrench corpse usually is.

That said, definitely kinks I am working out, like poses are supposed to be linked to location, basically copying what the existing pose was of whatever corpse originally was there. But there's issues with that were it seems different corpse models have different offsets when utilizing a pose, like Dead2. 3 models will have 3 different heights using that one pose. Not too worried about it, but it'll be a back burner concern.
« Last Edit: 22. April 2020, 00:28:54 by JossiRossi »

6742382d9e17cJossiRossi

6742382d9e1c4
I'm hoping this question gets seen, don't want to revive old threads or start a new one for this question, but I've done a lot of searching the past few days with no luck. I saw in the DML limitations thread that you can now create new items instead of only modifying old ones. I can't seem to get this to work. I have been using the Create dml command, but I haven't had any luck, are there any existing examples of placing brand new objects into a .mis?

6742382d9e285voodoo47

6742382d9e2cf
the examples in the Docs folder should be enough, but if you need an existing mod, Droid Immortality would be a good start (see gamesys.dml).

6742382d9e37dJossiRossi

6742382d9e3d0
Thank you, I'll try that out later. I saw the examples in the doc and for the life of me couldn't make any progress on it working

6742382d9e4b8JossiRossi

6742382d9e511
Thanks again voodoo. Figured out the issue eventually...

Helps to use the version of New Dark that supports the feature trying to be used  O_o

6742382d9e610voodoo47

6742382d9e65d
well yes, that indeed sounds like a good idea.

add dbmod_log 10 to your cam_ext, and explore dbmod.log when things are going south - if you see syntax errors, unexpected tokens etc, you should focus at the code bits where they are generated. helps a lot.
Acknowledged by: JossiRossi

6742382d9e77aJossiRossi

6742382d9e7ca
The dbmog.log tip has helped a lot while doing more testing/feature exploration, thank you voodoo. I spent some time getting the starting area modified some. I want to force a player to realize things have been changed. So the 45100 door lock has now replaced the cryo door with the ghost. And the log will be located anywhere before that door and after the airlock door. Also made the one way doors in those first few rooms two way, so you can go back if you missed something before you leave that area forever through the one way vent.

Also discovered the way to set door codes, so I can actually randomize door codes! I'd need to have the script alter the text log scripts so that the new codes exist somewhere, but it's an actual possibility now, which is pretty fun.
1 Guest is here.
Meanwhile, somewhere in the Pacific...
Contact SMF 2.0.19 | SMF © 2016, Simple Machines | Terms and Policies
FEEP
6742382d9f5c1