diff --git a/mods/ENTITIES/mcl_minecarts/API.md b/mods/ENTITIES/mcl_minecarts/API.md index 20fd0328c..ea1e13f1b 100644 --- a/mods/ENTITIES/mcl_minecarts/API.md +++ b/mods/ENTITIES/mcl_minecarts/API.md @@ -25,7 +25,7 @@ second. Defined as 10 blocks/second. - `mcl_minecarts.CART_BLOCKS_SIZE` -The size of blocks to use when searching for carts to respawn. Default is 64. +The size of blocks to use when searching for carts to respawn. Defined as is 64 blocks. - `mcl_minecarts.FRICTION` @@ -77,6 +77,11 @@ Calculate the rail adjacency information for rail placement. Arguments are: - `ignore_neightbor_connections` - if true, don't check that a cart could leave the neighboring node from this direction. +`mcl_minecarts:is_rail(position, railtype)` + +Determines if the node at `position` is a rail. If `railtype` is provided, +determine if the node at `position` is that type of rail. + `mcl_minecarts.register_rail(itemstring, node_definition)` Registers a rail with a few sensible defaults and if a craft recipe was specified, diff --git a/mods/ENTITIES/mcl_minecarts/DOC.md b/mods/ENTITIES/mcl_minecarts/DOC.md new file mode 100644 index 000000000..634bb3f5c --- /dev/null +++ b/mods/ENTITIES/mcl_minecarts/DOC.md @@ -0,0 +1,41 @@ + +## On-rail Minecart Movement + +Minecart movement is handled in two distinct regimes: on a rail and off. The +off-rail movement is handled with minetest's builtin entity movement handling. +The on-rail movement is handled with a custom algorithm. This section details +the latter. + +The data for on-rail minecart movement is stored entirely inside mod storage +and indexed by a hex-encoded 128-bit universally-unique identifier (uuid). The +code for handling this storage is in [storage.lua](./storage.lua). This was +done so that minecarts can still move while no players are connected or +when out of range of players. Inspiration for this was the [Adv Trains mod](http://advtrains.de/). +This is a behavior difference when compared to minecraft, as carts there will +stop movement when out of range of players. + +Processing for minecart movement is as follows: +1. In a globalstep handler, determine which carts are moving. +2. Call `do_movement` in [movement.lua](./movement.lua) to update + the cart's location and handle interactions with the environment. + 1. Each movement is broken up into one or more steps that are completely + contained inside a block. This prevents carts from ever jumping from + one rail to another over a gap or thru solid blocks because of server + lag. + 2. Each step uses physically accurate, timestep-independent physics + to move the cart. + 3. As the cart enters and leaves blocks, handlers in nearby blocks are called + to allow the cart to efficiently interact with the environment. +3. If an entity exists for a given cart, the entity will update its position + while loaded in. + +Cart movement when on a rail occurs regarless of whether an entity for that +cart exists or is loaded into memory. As a consequence of this movement, it +is possible for carts with unloaded entities to enter range of a player. +To handle this, periodic checks are performed around players and carts that +are within range but don't have a cart have a new entity spawned. + +Every time a cart has a new entity spawned, it increases a sequence number in +the cart data to allow removing old entities from the minetest engine. Any cart +entity that does not have the current sequence number for a minecart gets removed +once processing for that entity resumes. diff --git a/mods/ENTITIES/mcl_minecarts/carts.lua b/mods/ENTITIES/mcl_minecarts/carts.lua index f6c2a1436..9d7be5b74 100644 --- a/mods/ENTITIES/mcl_minecarts/carts.lua +++ b/mods/ENTITIES/mcl_minecarts/carts.lua @@ -182,7 +182,6 @@ function DEFAULT_CART_DEF:on_step(dtime) self._staticdata = staticdata end - -- Update entity position local pos = mod.get_cart_position(staticdata) if pos then self.object:move_to(pos) end @@ -551,8 +550,8 @@ minetest.register_globalstep(function(dtime) -- TODO: change how often cart positions are updated based on velocity for uuid,staticdata in mod.carts() do local pos = mod.get_cart_position(staticdata) - local le = mcl_util.get_luaentity_from_uuid(staticdata.uuid) --[[ + local le = mcl_util.get_luaentity_from_uuid(staticdata.uuid) print("cart# "..uuid.. ",velocity="..tostring(staticdata.velocity).. ",pos="..tostring(pos)..