Author Topic: Things collapsing and falling  (Read 382 times)

Offline tarsolyger

  • Squaddie
  • *
  • Posts: 42
    • View Profile
Things collapsing and falling
« on: October 30, 2018, 09:48:15 am »
Hi!

I have always been amazed how determined street lights are to stand there, you shoot the lamp post, and the whole structure just keeps standing. Same with buildings after shooting out all the walls, they still stand strong.

I wonder if it would be somehow possible to give at least a few structures a more realistic effect by having some tiles rely on the tiles below or next to, and if a certain amount of  support is gone, collapsing?

This of course would bring other implications that can or can not taken into consideration at this point, like what happens to someone if the floor or the chair from upstairs falls on them?

What I have been thinking about is more along the lines of a simple collapse model, i.e. the lamp post case, every tile of the post relies on the tile below 100%, while the lamp itself is to the side, so it relies on the one next to it (depending on direction), so if there's a tile destroyed, the tiles over and next to it are checked for consistency, so by one shot, you can destroy the whole post.

For walls, i.e. on the 2nd floor, I'd say, 40% is supported by the wall below, 30-30% by the walls next to it, so if you just shoot out the bottom wall, it stays there, but if you shoot also the wall next to it, it's gone. Some floors, that hinge overhead, can have their full weight supported by the floor tiles next to, so if you clear let's say the walls on 3 sides of the building, than the tiles supported mostly by the walls can start to fall and cause a cascade of falling ceiling elements.

Offline Stoddard

  • Captain
  • ***
  • Posts: 378
  • in a fey mood
    • View Profile
    • Linux builds & stuff
Re: Things collapsing and falling
« Reply #1 on: October 31, 2018, 03:27:40 pm »
I wonder if it would be somehow possible to give at least a few structures a more realistic effect by having some tiles rely on the tiles below or next to, and if a certain amount of  support is gone, collapsing?

For that to work one has to define somewhere what is a wall/support and what is not.

This is not easy because:

  • while the original MCD format has 5 more-or-less unused bytes, no one can be sure of values there in the existing tilesets, so using them is out of question
  • storing the property in the rulesets is cumbersome and requires much work for the tools to support that
  • all the tooling (mapview, mcdedit, whatever) has to be modified to support that. for some there is no source code

you can see why this wasn't done yet


Offline tarsolyger

  • Squaddie
  • *
  • Posts: 42
    • View Profile
Re: Things collapsing and falling
« Reply #2 on: November 01, 2018, 04:49:04 am »
you can see why this wasn't done yet

Yeah, I kinda suspected something like this. Maybe an additional file, that only contains the additional physics information for each tile could be a solution? If there is no corresponding file like that, everything defaults to 'hovering' or something.

The other end of the problem, namely the editing tools being rigid seems to me the biggest ordeal :(

Anyways thanks for the reply, I just really like this game and enjoy throwing ideas back and forth.

Offline Solarius Scorch

  • Global Moderator
  • Commander
  • *****
  • Posts: 7976
  • WE MUST DISSENT
    • View Profile
    • Nocturmal Productions modding studio website
Re: Things collapsing and falling
« Reply #3 on: November 01, 2018, 01:54:48 pm »
Well, if someone crazy enough shows up, designs a good mechanics for this (probably meaning: copy it from Apoc) and adds support for a new file (we already have 3 after all), then as a modder, I have absolutely no problem with doing all the tiles by hand. After all this file would have to be optional, so this could be done gradually.

Offline Stoddard

  • Captain
  • ***
  • Posts: 378
  • in a fey mood
    • View Profile
    • Linux builds & stuff
Re: Things collapsing and falling
« Reply #4 on: November 01, 2018, 09:43:54 pm »
designs a good mechanics for this (probably meaning: copy it from Apoc)

It's either Apoc (only vertical support propagation IIRC) or Dwarf Fortress (vertical or horisontal propagation, but a soap column can hold the world).

In theory it is possible to do a more complete model, where a whole red barn wouldn't hang on a single wall.
In practice I don't know of either a fast enough algorithm to recalculate the full what-is-supported-by-what graph
or a good algorithm to update an existing such graph. A brute-force approach appears to be too slow, but it might turn out to be acceptable.

So for apoc-style crashes only one field has to be added, for a full-blown simulation - three or four.

As for the file formats.. it all depends much more on the tools than on the engine.

This field-adding is possible right now by extending the MCDPatches and dropping small rulesets into the terrains directory,
but I feel that is too ugly and that moving terrain and map definitions completely into yaml would be a better way.



Offline tarsolyger

  • Squaddie
  • *
  • Posts: 42
    • View Profile
Re: Things collapsing and falling
« Reply #5 on: November 02, 2018, 09:20:46 am »
I would do it like this (I haven't coded in C or Java for more than 5 years, and I'm not a programmer by profession, so excuse my syntax):

Code: [Select]
struct WeightDistrib {
byte weight; // the weight of the tile
byte below, above, ground, ceiling; // the supports from the tiles from below and from above
byte north, south, east, west; // supports from the tiles on the sides
}

WeightDistrib tileWeights[xMax][yMax][zMax]
WeightDistrib floorWeights[xMax][yMax][zMax]

and then when a tile is destroyed, I'd check all neighboring tiles if they are supported by the following function:

Code: [Select]
bool IsSupported(WeightDistrib currentTile, int x, int y, int z) {
int supportedWeight;

supportedWeight = 0;
if (IsThereObject(x-1, y, z)) supportedWeight = supportedWeight + currentTile.west;
if (IsThereObject(x+1, y, z)) supportedWeight = supportedWeight + currentTile.east;
if (IsThereObject(x, y-1, z)) supportedWeight = supportedWeight + currentTile.south;
if (IsThereObject(x, y+1, z)) supportedWeight = supportedWeight + currentTile.north;
if (IsThereObject(x, y, z-1)) supportedWeight = supportedWeight + currentTile.below;
if (IsThereObject(x, y, z+1)) supportedWeight = supportedWeight + currentTile.above;
if (IsThereFloor(x, y, z)) supportedWeight = supportedWeight + currentTile.ground;
if (IsThereFloor(x, y, z+1)) supportedWeight = supportedWeight + currentTile.ceiling;

return supportedWeight > currentTile.weight
}

int DestroyObject(int x, int y, int z,) {
ObjectTile(x, y, z).Exists = False;

if ( !IsSupported(tileWeights[x-1][y][z], x-1, y, z) ) DestroyObject(x-1,y,z)
if ( !IsSupported(tileWeights[x+1][y][z], x+1, y, z) ) DestroyObject(x+1,y,z)
if ( !IsSupported(tileWeights[x][y-1][z], x, y-1, z) ) DestroyObject(x,y-1,z)
if ( !IsSupported(tileWeights[x][y+1][z], x, y+1, z) ) DestroyObject(x,y+1,z)
if ( !IsSupported(tileWeights[x][y][z-1], x, y, z-1) ) DestroyObject(x,y,z-1)
if ( !IsSupported(tileWeights[x][y][z+1], x, y, z+1) ) DestroyObject(x,y,z+1)
if ( !IsSupported(floorWeights[x][y][z], x, y, z) ) DestroyFloor(x,y,z)
if ( !IsSupported(floorWeights[x][y][z+1], x, y, z+1) ) DestroyFloor(x,y,z+1)
Return 0
}

int DestroyFloor(int x, int y, int z) {
FloorTile(x, y, z).Exists = False;

if ( !IsSupported(floorWeights[x-1][y][z], x-1, y, z) ) DestroyFloor(x-1,y,z)
if ( !IsSupported(floorWeights[x+1][y][z], x+1, y, z) ) DestroyFloor(x+1,y,z)
if ( !IsSupported(floorWeights[x][y-1][z], x, y-1, z) ) DestroyFloor(x,y-1,z)
if ( !IsSupported(floorWeights[x][y+1][z], x, y+1, z) ) DestroyFloor(x,y+1,z)
if ( !IsSupported(tileWeights[x][y][z-1], x, y, z-1) ) DestroyObject(x,y,z-1)
if ( !IsSupported(tileWeights[x][y][z+1], x, y, z) ) DestroyObject(x,y,z)
Return 0
}

In this case what I'd do is in case of a destroyed floor tile, I'd check neighboring floor tiles, the object "on" the floor and "below" the floor. In case of a destroyed object tile, I'd check the neighboring tiles, the tiles above and below, and the floor tile on "below" it, and the floor tile "above" it.

In this I am having some assumptions about the data structure, most importantly, that floor and object tiles are in separate 3 dimensional arrays, with the floor below the certain object go by the same z coordinate.

Edit: I was thinking about only the weight of neighboring tiles as an approximation, so if you set it up that one pillar can hold a floor tile, and one floor tile can be held by one remaining neighboring floor tile, than this pillar will be able to hold an infinitely big floor by itself. But I think by tuning the weight and how it is supported on the sides, you could achieve an effect that the whole ceiling crumbles if one tile is missing, and you can also also you have one where you have to shoot all neighboring tiles to get the middle one destroyed.

This is how much I have thought about it now.
« Last Edit: November 02, 2018, 09:39:29 am by tarsolyger »