Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
Quasar

Undefined behavior in Strife

Recommended Posts

I found out last night that Strife doesn't clear the mobj_t tracer fields when you load a save game. Try this:

  • Give yourself sigil 4 (the one that fires a single vertical homing lightning bolt).
  • Find a relatively open place such as near the river on Tarnhill and fire it at an Acolyte - be sure it'll home.
  • Save while the missile is in flight.
  • Quit and restart the game.
  • Load your save - the missile will probably appear to still hit the target, but it may instead veer off in a random direction. Repeated loading of the save will see the missile start to go in a different direction - often missing toward the right if it would have hit before.
So far I've not been able to coax the game into crashing because of this. One reason is because DosBox always loads the program at the same base address, so the addresses it accesses are always within range of the application's address space - not that DOS4GW was ever very good at enforcing that anyway.

I am at a loss for how to emulate this in Choco Strife :P

Share this post


Link to post
Quasar said:

I am at a loss for how to emulate this in Choco Strife :P

It catches an access violation if tried to be emulated?

Share this post


Link to post

I don't see how this affects gameplay. If it can't be emulated then oh well, all those people who save games while firing homing projectiles in Strife will be let down. If mobj_t tracer is called from a monster's attack, that might be kinda cheap to save/reload and then magically avoid incoming ememy fire. However if MORE undefined behaviors pop up...

Share this post


Link to post
printz said:

It catches an access violation if tried to be emulated?

No. It'll cause an access violation if you allow the code to function as it functioned in vanilla. If you clear the tracer by setting it to NULL, the missiles simply won't home any more.

In order to actually emulate the vanilla exe, you would need to make the missile behave in a semi-random manner >_> Exact emulation is impossible in any case.

Share this post


Link to post

Create a function that returns a pointer to a random mobj? Or even create a new mobj type that does nothing (no function calls in its states), but that is initialized with random coordinates. Create one of them for each loaded mobj type that is known to use tracers, and point to them.

Share this post


Link to post

Doom clears tracer target's just like normal targets, right? IMHO that's a descent approach to vanilla. Of course, later, the BOOM target restoring behavior makes sense.

It's not like a Strife demo would be loading save games, is it? What does this do to hubs?

Share this post


Link to post

What would be the point to 'emulate' this? It's broken in a way that can't be preserved. Just make it so that nothing bad happens but I think that deliberately introducing an instability just for the sake of it is not helping.

Share this post


Link to post
kb1 said:

Doom clears tracer target's just like normal targets, right? IMHO that's a descent approach to vanilla. Of course, later, the BOOM target restoring behavior makes sense.

It's not like a Strife demo would be loading save games, is it? What does this do to hubs?

DOOM 1.9, at least, clears both mobj_t::target and mobj_t::tracer. It may very well be the case that DOOM II 1.666 did not include clearing of mobj_t::tracer, as homing missiles were a relatively new feature to that version - would probably be nice if somebody could verify this using Revenants as the test case ;)

Strife clears allies' and normal things' targets, but for enemy monsters, it attempts to set their target to players[0].mo - of course this too has a glitch in that if the player has not been respawned from the save game yet (the things are saved in an arbitrary order, and that includes the player's body...) then the monsters up til that point actually get their target set to the mobj that was created for the player in P_SetupLevel but was then removed by P_UnArchiveThinkers.

Due to a fluke in the DOOM engine whereby all map things that are removed in P_UnArchiveThinkers are leaked on the zone heap until the next call to P_SetupLevel occurs, this code is safe. *IF* P_UnArchiveThinkers did *not* accidentally leak these objects by calling P_InitThinkers, which clears out the thinker list, then all the objects, including the old player body, would get sent to Z_Free on the first gametic, and it's likely very bad things would happen.

This is a classic case of layered bugs - two problem spots, one of which depends on the other to function. If someone working on a new port were to naively fix one but not the other, they'd get a very nasty surprise :>

Share this post


Link to post
Graf Zahl said:

What would be the point to 'emulate' this? It's broken in a way that can't be preserved. Just make it so that nothing bad happens but I think that deliberately introducing an instability just for the sake of it is not helping.

Did you get the memo about what the Chocolate Strife project, and indeed what any Chocolate port is about? Because when I read this post I have to seriously wonder if you did or not. I'd hate to have to bust out my missing the point inofgraphic again.

Share this post


Link to post

I did get it - but Quasar himself said that it's impossible to do it like the original - because it would crash under a more protected system than DOS. So there's 2 options: Add some wild hacks to make the impression of supporting it or make it safe. Since both would *NOT* be what Chocolate's 'mission' would be I'd go for 'safe'.

Share this post


Link to post

While I happen to agree with you (literally, on IRC, the night before this, I told quasar to simply say fuck it and set that shit to null) I'm still amazed at how completely your original post in the thread is not only predictable enough that I would very much like to start making bets on your responses to certain topics, but just overall how you seemed to simultaneously miss the point and be dismissive at the same time, even if you did state your reasoning much better just now. I'll grant you the consistency is impressive.

Share this post


Link to post

Double posting here to let people know that xttl tried this out in Doom II 1.666 and it's the same thing there - Revenant rockets in flight at the time of a savegame, *if* they remain homing when the game is reloaded (which depends on the gametic), will behave in the same random fashion. He even managed to get one to home in on a stimpack, which it orbited forever since stimpacks cannot be hit by missiles :)

Share this post


Link to post

So, a subtle gameplay difference between 1.666 and 1.9? Nice find! I always assumed that gameplay was identical between the two. Typically 1.666 demos play well when emulating 1.9. (Of course, to see THIS difference you'd have to be loading a game during a demo, which is impossible, isn't it?)

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×