OpenGothic icon indicating copy to clipboard operation
OpenGothic copied to clipboard

[gothic1] No magical barrier

Open sirsteve1 opened this issue 3 years ago • 16 comments

Dear @Try

When playing Gothic 1, there is no magical barrier. It is missing both at the skies and as a barrier that will stop us from when crossing the game boundaries (no effects, no death). I can simply walk out of the world.

Bildschirmfoto vom 2022-11-16 09-30-19

sirsteve1 avatar Nov 16 '22 08:11 sirsteve1

Hi, @sirsteve1 !

Barrier is not implemented: we do not support G1 officially

Try avatar Nov 16 '22 18:11 Try

@Try How would one start implementing this? Is this a difficult task for a new contributor?

CReimer avatar Jan 29 '23 17:01 CReimer

@CReimer , probably there is more investigation work than a actual coding.

I'm not 100% sure how barrier works in vanilla: is it MOBSI or sphere baked into the engine or something else.

NOTE: someone told me that there is a special mesh magicfrontier.3ds in game asset, but I'm haven't check it

Try avatar Jan 29 '23 18:01 Try

OK, I figured out how to extract all VDFs. There is a MAGICFRONTIER_OUT.MSH file in MESHES.VDF

I would have expected some kind of error in OpenGothic's output regarding this file. But nothing.

I looked for information on how to extract all of this further. But everything I found so far is pretty old. What do I have to do to get something human-readable out of all these VDF files?

CReimer avatar Jan 29 '23 21:01 CReimer

What do I have to do to get something human-readable out of all these VDF files?

AFAIK there is https://github.com/lmichaelis/phoenix-studio and some union bases solutions(don't have link atm)

I would have expected some kind of error in OpenGothic's output regarding this file

Why? Apparently file is simply is not in use. No use - no errors :)

Try avatar Jan 30 '23 21:01 Try

Does this mean that the barrier is not controlled by a Daedalus script? I figured the whole game is controlled by Daedalus scripts and that some Command in there is not implemented, which would add the barrier to the game.

CReimer avatar Feb 01 '23 17:02 CReimer

Does this mean that the barrier is not controlled by a Daedalus script?

Probably not. At least I'm not aware of any api that can be uses here.

Meanwhile there more possible options: vob/trigger/hardcode

Try avatar Feb 01 '23 20:02 Try

At least parts of it seems to be hard coded. I found this old forum thread here: http://forenarchiv.worldofplayers.de/thread.php?id=251841 (German, sry ^^) They claim that the physical barrier with getting close to the border of the map == ouch only exists if the zen file loaded is called world.zen. The barrier itself is loaded all the time according to them, but made black/transparent of not wanted.

EDIT: And another one: http://forenarchiv.worldofplayers.de/thread.php?id=133273 They say it's hard coded in the outdoor engine.

Does not really fit together, but both at least comply with it's hard coded.

dreimer1986 avatar Feb 02 '23 13:02 dreimer1986

I decided to dig into this a little, here's what I have found:

The frontier geometry is indeed stored as a MSH, initially they seemed to want to build the frontier from multiple parts, with an inner and outer layer.

This is the inner layer which seems to be unused and is made of a top and bottom part (Magicfrontier_Up.3ds, Magicfrontier_Down.3ds):

image

This is the outer layer, which is actually used in-game:

image

Only Magicfrontier_Out.3ds seems to be used (as MAGICFRONTIER_OUT.MSH) I suspect that using more than one layer ate too much fill rate and they went for one layer only.

MAGICFRONTIER_OUT.MSH only seems to contain vertices, at least zmodel writes no faces to the wavefront object file, thinking about it I lean towards a bug in phoenix studio / zmodel:

image

There are some strings in the executables which strongly suggest that this is all hard-coded:

  • D:\dev\gothic\current_work\Gothic\_Carsten\oMagFrontier.cpp
  • D:\dev\gothic\current_work\Gothic\_Ulf\oBarrier.cpp

Other interesting strings are:

  • myThunder
  • MFX_Barriere_Ambient
  • BARRIERE.TGA
  • CSkyControler_Barrier
  • RenderPreSky

There's some good info about the barrier and associated lightning here.

I'm willing to give this a shot, I'll try to come up a with a plan to implement basic rendering by getting into the OpenGothic code base.

astillich avatar May 08 '23 17:05 astillich

I tried to set up rendering, first using the resource system to load the .MSH, discovering it is not supported. Knowing that the world mesh is stored in .MSH format, I then had a look at how world is implemented and found that in order to parse a mesh I need to know which polygons to include as in world context all non-leaf polygons are discarded. I need to modify phoenix to allow keeping all the polygons in the mesh. Please stop me if I'm on the wrong path.

The barrier animation is done by warping BARRIERE.TGA which I'll do in the shader, the texture animations in MAGBA_A0-A1.TEX and MAGICFRONTIER_A0-A7.TEX seem to be unused.

astillich avatar May 08 '23 20:05 astillich

.MSH format

Afair .MSH is not a geometry format, but a mesh-hierarchy rather. @lmichaelis may know more, when it comes to file format.

warping BARRIERE.TGA which I'll do in the shader

At start please keep it simple. Most likely we will not use original texture in final shader, rather build a procedural texture.

Try avatar May 08 '23 20:05 Try

According to what info I can find, the .MSH format is the "old" mesh format and looking at the phoenix code, geometry is read from there.

Warping is just offsetting the UV coordinates with some sin(time) added together, I'll not reproduce the original behavior exactly which would require lots of observation and tweaking. Completely rendering it procedurally would be cool, but I consider it more work than warping the texture. It should be left to future improvements, as you implied.

astillich avatar May 08 '23 20:05 astillich

Here's what I'm trying to do:

image

I'm not sure if that's the best way to get it to render. I can step through the code and see that meshlets are generated from the mesh, but nothing shows up yet. Maybe I need to do something to make it visible? It could also be out of scale, culled or depth-covered, still need to figure that out.

Anyway, is this approach viable at all?

astillich avatar May 08 '23 22:05 astillich

I tried to set up rendering, first using the resource system to load the .MSH, discovering it is not supported. Knowing that the world mesh is stored in .MSH format, I then had a look at how world is implemented and found that in order to parse a mesh I need to know which polygons to include as in world context all non-leaf polygons are discarded. I need to modify phoenix to allow keeping all the polygons in the mesh. Please stop me if I'm on the wrong path.

The barrier animation is done by warping BARRIERE.TGA which I'll do in the shader, the texture animations in MAGBA_A0-A1.TEX and MAGICFRONTIER_A0-A7.TEX seem to be unused.

phoenix does support the .MSH-format. You can load those files using phoenix::mesh::parse.

I need to know which polygons to include as in world context all non-leaf polygons are discarded.

Those leaf polygons are only relevant when loading worlds. They are obtained from a BSP-tree ("binary space partitioning") which was used to improve performance in the original engine. They are not relevant for stand-alone meshes.

I need to modify phoenix to allow keeping all the polygons in the mesh.

That is actually a bug in phoenix. You're supposed to be able to load a mesh without specifying polygons to include. A fix has been rolled out in phoenix/5230465.

lmichaelis avatar May 09 '23 15:05 lmichaelis

Hi @lmichaelis, thanks for chiming in. I know that I can parse a mesh, I'm already using it in the snipped I posted. It's really only about how to set up rendering in OG now.

The change you posted is what I need, as an intermediary solution I added a third boolean parameter to the parse method, just to get the mesh parsed, your solution with optional is nicer and I'll use that.

I'm not sure what you are trying to say about the BSP, I know what a BSP is and what leaf nodes / polygons are. Just wanted to say that the parser skips any polygon indices not specified upfront, and I just verified that. And it does apply to parsing stand-alone meshes. Anyway, with your patch it's not a problem anymore.

@Try Is adding the barrier mesh to the WorldView as static view the right approach here?

EDIT: it seems that all ProtoMeshes are rendered using the same shader, at least Material does not allow specifying another shader. I'm not sure how adding a shader member to Material would affect the meshlet stuff, and I don't want to interfere with it for this special case. So I'll look into setting up custom rendering like Sky does, but with vertex / index buffers created from the parsed mesh.

EDIT: the barrier seems to render, when I fly over the map I can sometimes see black garbage lines with the barrier mesh added as a static view. I'm probably running into the bug I discovered earlier when trying to convert MAGICFRONTIER_OUT.MSH to a wavefront .obj where it had no faces. Something is wrong with parsing that mesh, it seems.

I adapted the wavefront code from zmodel and dumped the mesh I read withing OG, importing it into blender results in this:

image image

which looks corrupted. I'll investigate the mesh geometry later.

astillich avatar May 09 '23 15:05 astillich

Okay, I'll drop the shader part for now, it makes the barrier too much of a special case. It's just a semi-transparent object after all. I have a basic version running which draws the thing with solid red color using a custom shader, but that interacts badly with the sky and fog, I'll stop at that.

I'm still trying to figure out how to queue stuff for rendering on a high level, it seems that adding a view for a mesh is the way to go? Still have to get something to render this way, the garbage lines I see are probably something else.

EDIT: I was too focused on the rendering part and I think that I need to create a Vob with the mesh, probably a trigger to apply damage, figuring out how to do that programmatically.

astillich avatar May 09 '23 18:05 astillich