PSA: Each "dot" is 24 meters, not 30

  • We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.
Absolutely no idea. I'll ask Andy on Monday if it's something he wants to get into or not. I think it's not exaggeration to say we spent the first 9 months of this project just iterating the movement system, and we re-examined it every few months after that until we were happy with it. So there's a lot of design decision water under that particular bridge.

Please forward, while you are at it, that the people designing the UI for the movement is absolutely Brilliant. It was one of the the biggest worries for me as a lot of studios mess this up (im looking at you torment <.< ) as conveying info in such a relatively free-form and complex to boot manner (Torso Rotation and co) and it ended up Perfectly.

I have not yet played the game but watching the in-game footage everything i perfectly clear to me and it looks incredibly intuitive. So please, kudos to the designers on that front.
 
I'd recommend that if you want to understand this better, look in the log files.

I don't have time at the moment, but I'll try to point out the bits that look the most useful next time I check in.
So... in the log ([BattleTech Folder]/DumpBox/[Date-and-Time]/[Date-and-Time]_CombatLog.txt), you'll get lines like this:
Code:
CombatLog.ActorActivation [LOG] Actor Jenner BRK (d50f1e9d-0a0b-4dc8-9a06-a33233aaa8a1.0) - sprinting
CombatLog.ActorMovementSequence [LOG] MovementSequence completeMove: Current Position pre-Snap:  x: -420.1172, y: 105.2407, z: -187.1625, Current Heading:  x: 0.7577239, y: 0, z: 0.6525753, Current Rotation: 49.26395
CombatLog.ActorMovementSequence [LOG] MovementSequence completeMove will snap to: Final Position:  x: -420, y: 105.2877, z: -187.0615, Final Heading:  x: 0.755929, y: 0, z: 0.6546536, Final Rotation: 49.10661
I haven't found anything that tells you where the mechs started, but since they don't magically change position in between turns that's only an issue on the first turn. Doing the math for a hexagonal grid reveals that you should get spacing equal to the size of the grid on one axis, offset by half the spacing on every other row. This turns out to be the case for the X axis. Another axis should have spacing equal to half the size of the grid multiplied by the square root of 3... which for the default of 24 is 12√3 or √432 or ≈20.7846. This turns out to be the case for the Z axis.

Which means the Y axis is the height and is unconstrained (well, except by the map itself). This is where you might be able to find some height effects, although you can't tell from this what the slope was like along the entire path traversed... just what the final change in height ended up being. (I do want to tackle the map format eventually, but there's so much low-hanging fruit to try for first.)

You can almost certainly get more accurate numbers from here regarding what's going into the real behind-the-scenes computations. No idea why any kind of "pre-Snap" numbers would ever turn up since I would expect the interface to take care of that... but with them there, it wouldn't surprise me if that distance is the one that really got used. The main disadvantage of using the logs like this is that you can only find out about moves that were made and can't see the raw numbers for a move that was out of range. To some degree you could work around that by moving to that grid location later, of course, but who knows how different those "pre-Snap" numbers could be.
 
Last edited:
So, things are about to get weird.

I edited out the penalty for movement through water in the designMasks folder. This gives me a very flat platform to test movement numbers and is as close to a blank map as I can get. I found there is a kind of "natural grain" of each map where moving along only 1 axis is somehow cheaper than the other 2. I first started with a movement of 24, the confirmed size of the movement grid, nothing. Moving to 25 lets me move up or down the native grain of the map, but nowhere else. Note, this movement was available even if I was facing perpendicular to the native grain. Once I hit 27, things get interesting. But first, the 25 and 27 numbers confirm movements need to be one greater than whatever numbers the game is using, in this case, strait grid distance of 24m and that magical 26.25 that keeps coming up, but I can't find why it's so important or where it's declared.

Here is a VTR with 27m walk movement and its facing options, this screen shows the directions I will be using below. The composite shots show the maximum facing angles to the left and right after entering each hex. The 1 direction is "with the grain" of the hexes and the direction the VTR is facing. However, it's not with the "native grain" of the map that runs along the 2-5 axis and that means we see some strange results below.

Tjtvznf.jpg

Here is my turning raduis for 1. Note that my path along 1 is crooked to the left, and my final facing options favor the inside of my curved path.
77sAEp5.jpg


For 2, this runs along the native grain and my facing options are greatest, with over 240 degrees (if my math is right) of freedom. The pathing is in a strait line, suggesting this route is somehow shorter than hex 1 and leaves more facing angles.
OtTal8n.jpg


We see 3 works like hex 1, in that the pathway is curved and my facings favor one side, to the right this time.
aD4nycO.jpg


Hex 4 is also curved like 1 and 3, but note this is behind the VTR. This kind of action is probably why reverse isn't needed. We don't really pay much cost to turn around at the start of our movement, it's costly to turn at the end but it seems stepping off in any direction is free.
BARmAtD.jpg


Now back to the native grain on hex 5. Again, this is somehow cheaper (strait line shorter than curved used to calc mp spent?) and I get a wide range of facing options.
i0kktbr.jpg


Now we get to hex 6. The pathing is strait, but I don't get the same +240degree range of the 2-5 axis. I only get around 230degrees or so. This "strait but not with the native grain" movement and limited facing can be replicated on many points of the map. Some hexes have two or maybe 3 off native grain movements that look strait but don't get the native grain bonus.
dPExhSW.jpg

I think the game's pathing line is the raw distance of the move displayed. That's why the curved moves cost more MP and leave me with less facing angles at the end. As to why some 1 hex moves don't travel in the strait line and soak up MP, or why some seemingly strait moves have more or less facing after, I got no clue.
That looks indeed weird. As if there is some underlying grid for pathfinding that is not identical to the standard grid. I wish I still had the beta fioles to do some testing myself, but what happens if you set the experimental_grid_size way off. Like 100 meters or 3 meters? That could reveal some interesting things about the grid.
 
This thread is really great! I promise I will write something meaningful here soon... right now I'm fixing a nefarious soft-lock in the new cinematic camera when running a Locust max distance :\ this soft lock has been lurking for a while, and our great QA just got me reliable repro steps. Love when that happens :D

Spoiler alert though... there is indeed an underlying square grid (used by terrain, pathfinding, LOS/LOF checks) that throws numbers and angles off a bit when it comes to snapping moves onto the hex grid.
 
This thread is really great! I promise I will write something meaningful here soon... right now I'm fixing a nefarious soft-lock in the new cinematic camera when running a Locust max distance :\ this soft lock has been lurking for a while, and our great QA just got me reliable repro steps. Love when that happens :D

Spoiler alert though... there is indeed an underlying square grid (used by terrain, pathfinding, LOS/LOF checks) that throws numbers and angles off a bit when it comes to snapping moves onto the hex grid.
Thanks! Don't delay getting the game out the door for our threads sake. I'm already taking heat (jokingly) for this delaying the game. I had a suspicion the X/Y/Z square grid format not meshing with hexes would be an issue. I await your post, but am far more eager to get my hands on the game.
 
This thread is really great! I promise I will write something meaningful here soon... right now I'm fixing a nefarious soft-lock in the new cinematic camera when running a Locust max distance :\ this soft lock has been lurking for a while, and our great QA just got me reliable repro steps. Love when that happens :D

Spoiler alert though... there is indeed an underlying square grid (used by terrain, pathfinding, LOS/LOF checks) that throws numbers and angles off a bit when it comes to snapping moves onto the hex grid.
P.S. I'd really love a description of how jump distances are calculated. Walk distance rules may be weird, but jump distance rules put them to shame in weirdness. Very little in the json files has been identified to explain how it works either.

The oddest thing about jumping has been that even-numbered jump jets are like 150% as effective as odd numbered jump jets. Jumping heat costs also fluctuate wildly at seemingly the same breakpoints that impact maximum distance. For example: 2 jump jets will let you jump 3 dots for 22 heat. 3 jump jets will let you jump 4 dots for 30 heat (8 more heat to jump 1 more dot). Then, inexplicably, 4 jump jets will let you jump either 5 or 6 dots for 37 heat (7 more heat to jump 2 more dots).

Details collapsed in the spoiler tag to avoid information overload for those who don't want it:
Summary:
YxQC2jn.png


Raw data:
N9iqsx2.png


Note: To interpret this table, see the below image which shows what I mean by "x" and "y". I don't mean X and Y as perpendicular / square axes (even if that may be how it's really modeled behind the scenes)
uZvTgSq.png
 
Last edited:
Okay, the quick version of this is: there is a 4m grid that we build from the map geometry. This grid is treated as the source of truth for pretty much any game-related physical checks.

This includes pathfinding, so when we are looking for the path from one hex-point to another, we convert it over to the matching grid points, and then determine the path between those using something like https://en.wikipedia.org/wiki/Bresenham's_line_algorithm

Some "smudginess" probably works itself in when hex grid nodes don't quite line up with the underlaying square grid. But, the hex grid points are 24m apart.

I sketched up a quick image of some path finding happening on these two grids:

upload_2018-3-5_17-29-58.png


I would expect that the first segment there would report itself as exactly 24m in length - 6 steps of 4m each. But I don't recall if our two grids actually play quite as well together as what I've drawn.

In the second segment, you can see we step both orthogonally as well as diagonally. When stepping diagonally, we count the distance travelled as (sqr(4^2 + 4^2)), or approx. 5.66 meters. So, the distance of that second segment comes out to... either 21 or 25, depending on which square grid the second hex point is determined to be on.

When jumping, we measure the distance from the beginning hex point to the end hex point, and there isn't a concept of "how many hexes away" you are.
 
Okay, the quick version of this is: there is a 4m grid that we build from the map geometry. This grid is treated as the source of truth for pretty much any game-related physical checks.
Thank you for the explanation. It’s nice to understand what is going on, even if I don’t have a practical use for the information. :)
 
Hoyl cow thank you for this info this helps out so much :D
 
And this is why we love you devs!
In a strictly platonic, "we really admire you", kind of way. My wife wouldn't be happy otherwise :p
 
Okay, the quick version of this is: there is a 4m grid that we build from the map geometry. This grid is treated as the source of truth for pretty much any game-related physical checks.

This includes pathfinding, so when we are looking for the path from one hex-point to another, we convert it over to the matching grid points, and then determine the path between those using something like https://en.wikipedia.org/wiki/Bresenham's_line_algorithm

Some "smudginess" probably works itself in when hex grid nodes don't quite line up with the underlaying square grid. But, the hex grid points are 24m apart.

I sketched up a quick image of some path finding happening on these two grids:

View attachment 342451

I would expect that the first segment there would report itself as exactly 24m in length - 6 steps of 4m each. But I don't recall if our two grids actually play quite as well together as what I've drawn.

In the second segment, you can see we step both orthogonally as well as diagonally. When stepping diagonally, we count the distance travelled as (sqr(4^2 + 4^2)), or approx. 5.66 meters. So, the distance of that second segment comes out to... either 21 or 25, depending on which square grid the second hex point is determined to be on.

When jumping, we measure the distance from the beginning hex point to the end hex point, and there isn't a concept of "how many hexes away" you are.

Thanks for that post, it really sheds light on the things we are finding. I tried something I thought would negate the lower cost of moving with the native grain and make all 3 axis equally expensive. I set the grid distance to a prime number, 23, that wouldn't line up with the grid evenly in any direction. However, given the rounding that goes on, I saw the same kind of action regarding single hex movement, going with the grain was still cheaper.

The diagonal movement calculations also explain why for some movement profiles, they can go farther by one dot diagonally than strait at the very edge of their movement that is strait beforehand. It's probably falling to the 21 instead of 25 in some cases where the two types of grid happen to not mesh so cleanly and the hex dot falls in to the closer square.