ID:1055365
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
This is a list of feature requests I've been accumulating in my time with pixel movement, by making too many ugly workarounds.
I'll probably keep this updated as I go.
  1. Stop rounding my positions! This is really important for "smooth" movement.
    You can round them when you put them on the screen (although atom.transform tells me that's not even necessary), but let me keep my numbers accurate!

    In order to actually move smoothly, the step_size, step_x, and step_y variables (and maybe even bounds) need to not be rounded.
    For example, along a vector pointing in any angle, your coordinates need to be accumulating all the decimals that come out of the trig used in calculating your velocity.
    When dealing with basic 2D physics, you don't think in pixels. You think in units that can always be divided and scaled by any amount.

    I've been soft-coding workarounds for this, but it's pretty silly.
    It's such a basic feature that should have been in from the very beginning.
    No one's ever given me any reasons why the integer constraint was set.
    All pre-native pixel movement engines had this.

  2. To put tile movement aside even more, a new pair of position variables for absolute pixel position.
    Every time location is changed, these variables are recalculated.
    Every time these variables are changed, location is recalculated.
    A Translate() proc would be great too, but that can be easily soft-coded by setting step_size and calling Move().

    Just as necessary as the bottom-left corner of an atom is its center. But that's easily found.

    If some vector datum could be recognized by the "new" keyword to place an object at a specific absolute pixel position, that'd also really help with putting tile-based movement to the side.

  3. Basic native physics of some kind. Like, Box2D, or something. Now that atom.transform simplifies all the visual parts, the rest is the huge internal parts. Axis-aligned bounding-boxes are so old-school.
    How could I possibly make an Angry Birds clone without this.

    Highly unlikely, but there aren't any feature requests out there for it, so there's that.

The list is open for additions.
++
Yes, bring to BYOND a pefect synthesis of pixel based measurement, and vector based movement!

Pixels are the ultimate unit of measurement for placing, spacing, and measuring any kind of raster based art, including a game running in BYOND. The best way to move any object is along a straight line! That should be self explanatory. Things just shouldn't move from tile to tile like they do now. You should just be able to give an object 2 points and tell it to cover the distance between them, regardless of the angle! That's how physicists or engineers trace trajectories in the real world. They don't wait for an object to pass through each square of space, they simply measure the distance between the start and end points. Let's go trigonometry all the way!

Instead of having to overhaul the existing tile-based framework, you could simply make an optional vector one, so users can decide if they want purely tile based maps or just free form vector movement. Perhaps a whole other type of world.map_format could make this happen. It can change the world from top-down to isometric or even hex, so why not have an additional setting for vector? The vectors could run right through the existing tiles, so objects would still have a tile location, unless perhaps there can be a switch to disable that. It could be useful for keeping things efficient and saving memory (no need to remember the tile locations of every object).

I do think this is the direction BYOND needs to go in order to survive in the long term. Even the Atari 2600 did things that BYOND can't do very well even today, and that should change. This can be the next big leap for the BYOND engine itself. The truth is that all of the developers really want this to happen. We all struggle with the constraints of the tile grid, so let's make that optional. Objects should totally be able to smoothly race through the tile grid at all angles and velocities, moving in pixel perfection. Think of the game asteroids. It's incredibly simple, but right now BYOND just isn't built to do that sort of thing.

One thing we will need to answer though, is how do you create a type of map file that can store the pixel based locations of objects that get placed pixel perfectly on the map before the game runs? A pixel perfect map editor is something we would want right? This would be a special type of map file designed around this particular system. Making the editor pixel perfect is probably the easy part. The hard part is figuring out how the map file is actually going to store that extra information. Maybe there could be 2 separate files that work together. You would have the existing map file, that stores the tile based data, then another, separate file that actually stores the pixel offsets. You might think of it as a kind of relational database. I don't even know if such a thing is feasible, so we need some more ideas on how that could work. I think it's only logical that if you have objects with pixel based positions, then you should be able to just plot those positions directly on a map.
Bu-bump. I updated the main post.

Also, I have no clue what Multiverse7 is talking about.
Nevermind what I said there. While my suggestion had a similar goal, it would be a far bigger project. I don't think it's feasible at all, due to the existence of things like turfs. Turfs and tiles in general are firmly grounded into the foundation of BYOND. The map, screen, and object locations all revolve around tiles and turfs, so digging them up at this point might not be worth it. Although, if those reliances could be lifted, it would open the door to completely free, vector-based worlds.

Your original suggestion is the better one, as it works within the existing system. There should be variables that let you set the absolute map coordinates of atoms. You could simply ignore the tile-based features, but they would always be there if you need them.

In addition to absolute positions, there would need to be procs to help with the setting of those positions. I think the final form of bounds() works well enough as the pixel perfect version of locate(). For movement, there could simply be another format for the Move() proc. The walk() proc might also need another format.

It might work like this:
Move(coord_x, coord_y, Z = src.Z)

coord_x and coord_y are absolute coordinates on the map, starting at 1,1 (lower left) just like in bounds().

Z is the Z-level. This defaults to the movable's current Z-level. It probably has to be a jump if you override this.

Even though this format looks simple, both Move() formats would update the exact same vars. For example, dir would be determined automatically, based on the angle of the trajectory.

This all needs to happen before we can even consider any kind of built-in physics.
This is off-topic, but what exactly do you mean by "vector-based worlds?" When I ask for a couple "absolute pixel coordinates", that's all the vector-based-ness you need.

Because position is a vector.
In response to Kaiochao
Kaiochao wrote:
When I ask for a couple "absolute pixel coordinates", that's all the vector-based-ness you need.

That's why it wouldn't make much sense to have a fully vector-based world.

I will assume for a moment that this is actually feasible. As soon as you set world.map_format = PIXEL_MAP, everything changes. Tiles would not exist. Turfs either could not be defined, or they would simply be obsolete. All atoms would have an absolute map location. All X and Y vars would be null/nonexistent! Even world.icon_size is null! world.view and client.view have pixel based values instead of tiles. world.maxx/maxy now represent the size of the map in pixels. If you make and edit a map in this format, you will find that there is no tile grid and no "offsets". Editing this map is more like editing an image. You can freely place objects all over the place. Even the map file itself would be different. It would define instances with absolute coordinates instead of tiles.

There is practically no end to the changes that would be made. See why I don't think it's feasible?
In response to Multiverse7
I think I'm starting to understand what you're getting at.

I don't see the point in getting rid of the tile grid when mapping. Tile-based maps aren't bad, tile-based pixel movement is. Besides, you can already freely place objects (not tiles or areas) without snapping to the grid, in the current map editor.

Still, I think you're overcomplicating what a "vector" is. I get the feeling that when you say "fully vector-based world" you think you're actually saying something, but really you're not. Vectors aren't something you "base" things on, they're things you use to describe. It's like saying "let's have number-based mathematics." Just stop saying "vector-based." I don't think vectors are what you think they are.
Simply put, vectors are lines. In the terms of DM, we are referring specifically to the movement. So, this is about movement along lines. Now, lines do not actually exist in DM. Tiles exist, which gets in the way of smooth vectors. Vectors are much easier to understand when they are not broken up into tiles. Vectors just make much more sense in a pixel-based world (what I should have said). I was simply suggesting that removing the tiles is a prerequisite for more perfect vector-based movement.

That's not the case, and I'm not going to defend an argument that I no longer support.


Edit:
I know what you are saying. I have been talking about mathematical vectors. You are referring to vectors in physics. Mathematical or geometric vectors (lines) are needed for vector physics (relative velocity).
A vector is not a line, unless your definition of "line" is also skewed.

Moving by a vector, AKA moving any distance at any angle, AKA MOVING, very much exists in DM.

Pixel movement exists in DM. Placing movable atoms at pixel positions instead of tiles already exists in the map editor.

"Perfect" vector-based movement has always existed in DM. The moment you take a step in one of the 8 BYOND directions, a vector exists to describe your movement. The arrow keys on your keyboard show the direction of the vector you just moved by, and the vector's length is the amount of steps you took.

All I'm asking for in the feature request is that the pixel movement coordinates stop being rounded so I don't have to use silly workarounds to preserve the accuracy. It is in no way whatsoever keeping me from having "perfect vector-based movement," though. I'm just asking for convenience, and I'm also confused as to why the coordinates are purposely rounded -- intentionally made inaccurate -- in the first place.
In response to Kaiochao
Kaiochao wrote:
The moment you take a step in one of the 8 BYOND directions, a vector exists to describe your movement. The arrow keys on your keyboard show the direction of the vector you just moved by, and the vector's length is the amount of steps you took.

That's not entirely the case. Any movement in DM is currently a series of step()s. The pixel offsets are just that: offsets. Offsets provide the illusion of a vector, instead of just having a real, solid vector. Without those "offsets" all you really have are individual steps from tile to tile. While pixel movement may exist, that movement revolves around these "artificial" offsets, instead of just directly describing the absolute map positions.

Also, this is the kind of vector I was referring to. Computers use it all the time, when rasterizing 3D vector graphics.
In response to Multiverse7
This is just telling me that you are, in fact, overcomplicating what a vector is.

Assuming your idea of vectors is valid, what difference would it make to move 5 pixels east and 2 pixels north vs. moving by vector (5, 2)?

(both achieved by this code)
Move(loc, 0, step_x + 5, step_y + 2)
In response to Kaiochao
You are comparing geometric vector coordinates with only the pixel offsets. Vectors would replace both the tile location and the offset location. What happens when step_x/y > world.icon_size? Are you just going to leave everything behind at a single tile?
In response to Multiverse7
No? I don't think you understand how BYOND's pixel movement works, either.
It sure doesn't work well enough. That's why we need absolute positioning:
Move(coord_x, coord_y, Z = src.Z)
In response to Multiverse7
It works perfectly except for the fact that step_x/y are rounded to the nearest integer.
I'm just saying that it could be improved with another Move() format. If your game doesn't use tiles, then you shouldn't have to care about the tile locations at all.
In response to Multiverse7
Aren't you a programmer? Can't you write procs that do things?
atom/movable
proc/Translate(X, Y)
var _ = step_size
step_size = round(max(abs(X), abs(Y)))
. = Move(loc, 0, step_x + X, step_y + Y)
step_size = _

// you could even do this for yourself
Move(X, Y)
if(isnum(X) && isnum(Y))
return Translate(X, Y)
return ..()
You could say that about most things in DM. I'm a programmer, therefore I don't need to use an engine. That seems to be what you are suggesting. Something this basic should already be built-in. Also, your implementation does not have real absolute coordinate vars for atoms. That would require making an infinite loop, to constantly check the values of the vars, then calling your Translate() proc with each change. It would end up terribly inefficient.
In response to Multiverse7
This is the definition of a movable atom's absolute pixel position:
py = (x - 1) * TILE_WIDTH + bound_x + step_x
py = (y - 1) * TILE_HEIGHT + bound_y + step_y


If you want to move from your current position to an arbitrary end point,
//  Here's your movement vector.
var dx = end_x - px
var dy = end_y - py

Translate(dx, dy)


If you want to just set your position to an absolute pixel coordinate,
//  Moving to absolute pixel point (nx, ny) at z-level Z.
loc = locate(
1 + nx / TILE_WIDTH,
1 + ny / TILE_HEIGHT, Z)
step_x = nx % TILE_WIDTH
step_y = ny % TILE_HEIGHT
// ^ this is probably why step_x and step_y are rounded
// the modulo operation doesn't support floats
// but that can be changed.


The last two examples are actually straight from pre-native pixel movement.
Page: 1 2